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 | properties: | 70 | properties: |
| 71 | compatible: | 71 | compatible: |
| 72 | contains: | 72 | contains: |
| 73 | const: allwinner,sun8i-h3-spdif | 73 | enum: |
| 74 | - allwinner,sun8i-h3-spdif | ||
| 75 | - allwinner,sun50i-h6-spdif | ||
| 74 | 76 | ||
| 75 | then: | 77 | then: |
| 76 | properties: | 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 | - compatible: 'amlogic,axg-toddr' or | 4 | - compatible: 'amlogic,axg-toddr' or |
| 5 | 'amlogic,axg-toddr' or | 5 | 'amlogic,axg-toddr' or |
| 6 | 'amlogic,g12a-frddr' or | 6 | 'amlogic,g12a-frddr' or |
| 7 | 'amlogic,g12a-toddr' | 7 | 'amlogic,g12a-toddr' or |
| 8 | 'amlogic,sm1-frddr' or | ||
| 9 | 'amlogic,sm1-toddr' | ||
| 8 | - reg: physical base address of the controller and length of memory | 10 | - reg: physical base address of the controller and length of memory |
| 9 | mapped region. | 11 | mapped region. |
| 10 | - interrupts: interrupt specifier for the fifo. | 12 | - interrupts: interrupt specifier for the fifo. |
| 11 | - clocks: phandle to the fifo peripheral clock provided by the audio | 13 | - clocks: phandle to the fifo peripheral clock provided by the audio |
| 12 | clock controller. | 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 | - #sound-dai-cells: must be 0. | 19 | - #sound-dai-cells: must be 0. |
| 15 | 20 | ||
| 16 | Example of FRDDR A on the A113 SoC: | 21 | Example of FRDDR A on the A113 SoC: |
| @@ -2,7 +2,8 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: 'amlogic,axg-pdm' or | 4 | - compatible: 'amlogic,axg-pdm' or |
| 5 | 'amlogic,g12a-pdm' | 5 | 'amlogic,g12a-pdm' or |
| 6 | 'amlogic,sm1-pdm' | ||
| 6 | - reg: physical base address of the controller and length of memory | 7 | - reg: physical base address of the controller and length of memory |
| 7 | mapped region. | 8 | mapped region. |
| 8 | - clocks: list of clock phandle, one for each entry clock-names. | 9 | - clocks: list of clock phandle, one for each entry clock-names. |
| @@ -12,6 +13,9 @@ Required properties: · 3 unmodified lines | |||
| 12 | * "sysclk" : dsp system clock | 13 | * "sysclk" : dsp system clock |
| 13 | - #sound-dai-cells: must be 0. | 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 | Example of PDM on the A113 SoC: | 19 | Example of PDM on the A113 SoC: |
| 16 | 20 | ||
| 17 | pdm: audio-controller@ff632000 { | 21 | pdm: audio-controller@ff632000 { |
| @@ -2,7 +2,8 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: 'amlogic,axg-spdifin' or | 4 | - compatible: 'amlogic,axg-spdifin' or |
| 5 | 'amlogic,g12a-spdifin' | 5 | 'amlogic,g12a-spdifin' or |
| 6 | 'amlogic,sm1-spdifin' | ||
| 6 | - interrupts: interrupt specifier for the spdif input. | 7 | - interrupts: interrupt specifier for the spdif input. |
| 7 | - clocks: list of clock phandle, one for each entry clock-names. | 8 | - clocks: list of clock phandle, one for each entry clock-names. |
| 8 | - clock-names: should contain the following: | 9 | - clock-names: should contain the following: |
| @@ -10,6 +11,9 @@ Required properties: · 1 unmodified line | |||
| 10 | * "refclk" : spdif input reference clock | 11 | * "refclk" : spdif input reference clock |
| 11 | - #sound-dai-cells: must be 0. | 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 | Example on the A113 SoC: | 17 | Example on the A113 SoC: |
| 14 | 18 | ||
| 15 | spdifin: audio-controller@400 { | 19 | spdifin: audio-controller@400 { |
| @@ -2,13 +2,17 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: 'amlogic,axg-spdifout' or | 4 | - compatible: 'amlogic,axg-spdifout' or |
| 5 | 'amlogic,g12a-spdifout' | 5 | 'amlogic,g12a-spdifout' or |
| 6 | 'amlogic,sm1-spdifout' | ||
| 6 | - clocks: list of clock phandle, one for each entry clock-names. | 7 | - clocks: list of clock phandle, one for each entry clock-names. |
| 7 | - clock-names: should contain the following: | 8 | - clock-names: should contain the following: |
| 8 | * "pclk" : peripheral clock. | 9 | * "pclk" : peripheral clock. |
| 9 | * "mclk" : master clock | 10 | * "mclk" : master clock |
| 10 | - #sound-dai-cells: must be 0. | 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 | Example on the A113 SoC: | 16 | Example on the A113 SoC: |
| 13 | 17 | ||
| 14 | spdifout: audio-controller@480 { | 18 | spdifout: audio-controller@480 { |
| @@ -4,7 +4,9 @@ Required properties: · 3 unmodified lines | |||
| 4 | - compatible: 'amlogic,axg-tdmin' or | 4 | - compatible: 'amlogic,axg-tdmin' or |
| 5 | 'amlogic,axg-tdmout' or | 5 | 'amlogic,axg-tdmout' or |
| 6 | 'amlogic,g12a-tdmin' or | 6 | 'amlogic,g12a-tdmin' or |
| 7 | 'amlogic,g12a-tdmout' | 7 | 'amlogic,g12a-tdmout' or |
| 8 | 'amlogic,sm1-tdmin' or | ||
| 9 | 'amlogic,sm1-tdmout | ||
| 8 | - reg: physical base address of the controller and length of memory | 10 | - reg: physical base address of the controller and length of memory |
| 9 | mapped region. | 11 | mapped region. |
| 10 | - clocks: list of clock phandle, one for each entry clock-names. | 12 | - clocks: list of clock phandle, one for each entry clock-names. |
| @@ -1,10 +1,12 @@ | |||
| 1 | * Amlogic HDMI Tx control glue | 1 | * Amlogic HDMI Tx control glue |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: "amlogic,g12a-tohdmitx" | 4 | - compatible: "amlogic,g12a-tohdmitx" or |
| 5 | "amlogic,sm1-tohdmitx" | ||
| 5 | - reg: physical base address of the controller and length of memory | 6 | - reg: physical base address of the controller and length of memory |
| 6 | mapped region. | 7 | mapped region. |
| 7 | - #sound-dai-cells: should be 1. | 8 | - #sound-dai-cells: should be 1. |
| 9 | - resets: phandle to the dedicated reset line of the hdmitx glue. | ||
| 8 | 10 | ||
| 9 | Example on the S905X2 SoC: | 11 | Example on the S905X2 SoC: |
| 10 | 12 | ||
| @@ -12,6 +14,7 @@ tohdmitx: audio-controller@744 { · 1 unmodified line | |||
| 12 | compatible = "amlogic,g12a-tohdmitx"; | 14 | compatible = "amlogic,g12a-tohdmitx"; |
| 13 | reg = <0x0 0x744 0x0 0x4>; | 15 | reg = <0x0 0x744 0x0 0x4>; |
| 14 | #sound-dai-cells = <1>; | 16 | #sound-dai-cells = <1>; |
| 17 | resets = <&clkc_audio AUD_RESET_TOHDMITX>; | ||
| 15 | }; | 18 | }; |
| 16 | 19 | ||
| 17 | Example of an 'amlogic,axg-sound-card': | 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 | Required properties: | 8 | Required properties: |
| 9 | 9 | ||
| 10 | - compatible : Compatible list, must contain "fsl,imx35-esai" or | 10 | - compatible : Compatible list, should contain one of the following |
| 11 | "fsl,vf610-esai" | 11 | compatibles: |
| 12 | "fsl,imx35-esai", | ||
| 13 | "fsl,vf610-esai", | ||
| 14 | "fsl,imx6ull-esai", | ||
| 12 | 15 | ||
| 13 | - reg : Offset and length of the register set for the device. | 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 | Required properties: | 8 | Required properties: |
| 9 | 9 | ||
| 10 | - compatible : Compatible list, contains "fsl,vf610-sai", | 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 | - reg : Offset and length of the register set for the device. | 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 | int (*hdev_detach)(struct hdac_device *hdev); | 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 | #define HDA_UNSOL_QUEUE_SIZE 64 | 256 | #define HDA_UNSOL_QUEUE_SIZE 64 |
| 275 | #define HDA_MAX_CODECS 8 /* limit by controller side */ | 257 | #define HDA_MAX_CODECS 8 /* limit by controller side */ |
| 276 | 258 | ||
| @@ -304,7 +286,6 @@ struct hdac_rb { · 27 unmodified lines | |||
| 304 | struct hdac_bus { | 286 | struct hdac_bus { |
| 305 | struct device *dev; | 287 | struct device *dev; |
| 306 | const struct hdac_bus_ops *ops; | 288 | const struct hdac_bus_ops *ops; |
| 307 | const struct hdac_io_ops *io_ops; | ||
| 308 | const struct hdac_ext_bus_ops *ext_ops; | 289 | const struct hdac_ext_bus_ops *ext_ops; |
| 309 | 290 | ||
| 310 | /* h/w resources */ | 291 | /* h/w resources */ |
| @@ -344,6 +325,7 @@ struct hdac_bus { · 33 unmodified lines | |||
| 344 | /* CORB/RIRB and position buffers */ | 325 | /* CORB/RIRB and position buffers */ |
| 345 | struct snd_dma_buffer rb; | 326 | struct snd_dma_buffer rb; |
| 346 | struct snd_dma_buffer posbuf; | 327 | struct snd_dma_buffer posbuf; |
| 328 | int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */ | ||
| 347 | 329 | ||
| 348 | /* hdac_stream linked list */ | 330 | /* hdac_stream linked list */ |
| 349 | struct list_head stream_list; | 331 | struct list_head stream_list; |
| @@ -384,8 +366,7 @@ struct hdac_bus { · 34 unmodified lines | |||
| 384 | }; | 366 | }; |
| 385 | 367 | ||
| 386 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, | 368 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, |
| 387 | const struct hdac_bus_ops *ops, | 369 | const struct hdac_bus_ops *ops); |
| 388 | const struct hdac_io_ops *io_ops); | ||
| 389 | void snd_hdac_bus_exit(struct hdac_bus *bus); | 370 | void snd_hdac_bus_exit(struct hdac_bus *bus); |
| 390 | int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, | 371 | int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, |
| 391 | unsigned int cmd, unsigned int *res); | 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 | int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus); | 410 | int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus); |
| 430 | void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus); | 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 | * macros for easy use | 431 | * macros for easy use |
| 434 | */ | 432 | */ |
| 435 | #define _snd_hdac_chip_writeb(chip, reg, value) \ | 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 | #define _snd_hdac_chip_readb(chip, reg) \ | 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 | #define _snd_hdac_chip_writew(chip, reg, value) \ | 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 | #define _snd_hdac_chip_readw(chip, reg) \ | 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 | #define _snd_hdac_chip_writel(chip, reg, value) \ | 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 | #define _snd_hdac_chip_readl(chip, reg) \ | 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 | /* read/write a register, pass without AZX_REG_ prefix */ | 446 | /* read/write a register, pass without AZX_REG_ prefix */ |
| 449 | #define snd_hdac_chip_writel(chip, reg, value) \ | 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 | * macros for easy use | 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 | /* read/write a register, pass without AZX_REG_ prefix */ | 549 | /* read/write a register, pass without AZX_REG_ prefix */ |
| 557 | #define snd_hdac_stream_writel(dev, reg, value) \ | 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 | #define snd_hdac_stream_writew(dev, reg, value) \ | 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 | #define snd_hdac_stream_writeb(dev, reg, value) \ | 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 | #define snd_hdac_stream_readl(dev, reg) \ | 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 | #define snd_hdac_stream_readw(dev, reg) \ | 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 | #define snd_hdac_stream_readb(dev, reg) \ | 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 | /* update a register, pass without AZX_REG_ prefix */ | 563 | /* update a register, pass without AZX_REG_ prefix */ |
| 571 | #define snd_hdac_stream_updatel(dev, reg, mask, val) \ | 564 | #define snd_hdac_stream_updatel(dev, reg, mask, val) \ |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, | 7 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, |
| 8 | const struct hdac_bus_ops *ops, | 8 | const struct hdac_bus_ops *ops, |
| 9 | const struct hdac_io_ops *io_ops, | ||
| 10 | const struct hdac_ext_bus_ops *ext_ops); | 9 | const struct hdac_ext_bus_ops *ext_ops); |
| 11 | 10 | ||
| 12 | void snd_hdac_ext_bus_exit(struct hdac_bus *bus); | 11 | void snd_hdac_ext_bus_exit(struct hdac_bus *bus); |
| @@ -47,6 +47,9 @@ struct hdmi_codec_params { · 46 unmodified lines | |||
| 47 | int channels; | 47 | int channels; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | typedef void (*hdmi_codec_plugged_cb)(struct device *dev, | ||
| 51 | bool plugged); | ||
| 52 | |||
| 50 | struct hdmi_codec_pdata; | 53 | struct hdmi_codec_pdata; |
| 51 | struct hdmi_codec_ops { | 54 | struct hdmi_codec_ops { |
| 52 | /* | 55 | /* |
| @@ -88,6 +91,14 @@ struct hdmi_codec_ops { · 35 unmodified lines | |||
| 88 | */ | 91 | */ |
| 89 | int (*get_dai_id)(struct snd_soc_component *comment, | 92 | int (*get_dai_id)(struct snd_soc_component *comment, |
| 90 | struct device_node *endpoint); | 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 | /* HDMI codec initalization data */ | 104 | /* HDMI codec initalization data */ |
| @@ -99,6 +110,12 @@ struct hdmi_codec_pdata { · 5 unmodified lines | |||
| 99 | void *data; | 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 | #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" | 119 | #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" |
| 103 | 120 | ||
| 104 | #endif /* __HDMI_CODEC_H__ */ | 121 | #endif /* __HDMI_CODEC_H__ */ |
| @@ -1,18 +1,17 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 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 | 5 | * Copyright (c) 2015-2019 Intel Corporation |
| 6 | * Author: Sanjiv Kumar <sanjiv.kumar@intel.com> | ||
| 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 8 | * | ||
| 9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 10 | */ | 6 | */ |
| 11 | #ifndef __SKL_NHLT_H__ | 7 | |
| 12 | #define __SKL_NHLT_H__ | 8 | #ifndef __INTEL_NHLT_H__ |
| 9 | #define __INTEL_NHLT_H__ | ||
| 13 | 10 | ||
| 14 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
| 15 | 12 | ||
| 13 | #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT) | ||
| 14 | |||
| 16 | struct wav_fmt { | 15 | struct wav_fmt { |
| 17 | u16 fmt_tag; | 16 | u16 fmt_tag; |
| 18 | u16 channels; | 17 | u16 channels; |
| @@ -97,16 +96,22 @@ struct nhlt_resource_desc { · 78 unmodified lines | |||
| 97 | #define MIC_ARRAY_2CH 2 | 96 | #define MIC_ARRAY_2CH 2 |
| 98 | #define MIC_ARRAY_4CH 4 | 97 | #define MIC_ARRAY_4CH 4 |
| 99 | 98 | ||
| 100 | struct nhlt_tdm_config { | 99 | struct nhlt_device_specific_config { |
| 101 | u8 virtual_slot; | 100 | u8 virtual_slot; |
| 102 | u8 config_type; | 101 | u8 config_type; |
| 103 | } __packed; | 102 | } __packed; |
| 104 | 103 | ||
| 105 | struct nhlt_dmic_array_config { | 104 | struct nhlt_dmic_array_config { |
| 106 | struct nhlt_tdm_config tdm_config; | 105 | struct nhlt_device_specific_config device_config; |
| 107 | u8 array_type; | 106 | u8 array_type; |
| 108 | } __packed; | 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 | enum { | 115 | enum { |
| 111 | NHLT_MIC_ARRAY_2CH_SMALL = 0xa, | 116 | NHLT_MIC_ARRAY_2CH_SMALL = 0xa, |
| 112 | NHLT_MIC_ARRAY_2CH_BIG = 0xb, | 117 | NHLT_MIC_ARRAY_2CH_BIG = 0xb, |
| @@ -116,4 +121,30 @@ enum { · 3 unmodified lines | |||
| 116 | NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf, | 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 | #endif | 150 | #endif |
| @@ -117,6 +117,8 @@ struct snd_pcm_ops { · 116 unmodified lines | |||
| 117 | #define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ | 117 | #define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */ |
| 118 | #define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ | 118 | #define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */ |
| 119 | #define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */ | 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 | #define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ | 123 | #define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */ |
| 122 | #define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */ | 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 | SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000) | 131 | SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000) |
| 130 | #define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\ | 132 | #define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\ |
| 131 | SNDRV_PCM_RATE_192000) | 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 | #define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt) | 137 | #define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt) |
| 133 | #define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8) | 138 | #define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8) |
| 134 | #define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8) | 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 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[]; | 25 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[]; |
| 26 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[]; | 26 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[]; |
| 27 | extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[]; | 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 | * generic table used for HDA codec-based platforms, possibly with | 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 | int snd_soc_dai_is_dummy(struct snd_soc_dai *dai); | 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 | struct snd_soc_dai_ops { | 173 | struct snd_soc_dai_ops { |
| 149 | /* | 174 | /* |
| 150 | * DAI clocking configuration, all optional. | 175 | * DAI clocking configuration, all optional. |
| @@ -268,8 +293,6 @@ struct snd_soc_dai_driver { · 117 unmodified lines | |||
| 268 | /* Optional Callback used at pcm creation*/ | 293 | /* Optional Callback used at pcm creation*/ |
| 269 | int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, | 294 | int (*pcm_new)(struct snd_soc_pcm_runtime *rtd, |
| 270 | struct snd_soc_dai *dai); | 295 | struct snd_soc_dai *dai); |
| 271 | /* DAI is also used for the control bus */ | ||
| 272 | bool bus_control; | ||
| 273 | 296 | ||
| 274 | /* ops */ | 297 | /* ops */ |
| 275 | const struct snd_soc_dai_ops *ops; | 298 | const struct snd_soc_dai_ops *ops; |
| @@ -281,6 +304,7 @@ struct snd_soc_dai_driver { · 5 unmodified lines | |||
| 281 | unsigned int symmetric_rates:1; | 304 | unsigned int symmetric_rates:1; |
| 282 | unsigned int symmetric_channels:1; | 305 | unsigned int symmetric_channels:1; |
| 283 | unsigned int symmetric_samplebits:1; | 306 | unsigned int symmetric_samplebits:1; |
| 307 | unsigned int bus_control:1; /* DAI is also used for the control bus */ | ||
| 284 | 308 | ||
| 285 | /* probe ordering - for components with runtime dependencies */ | 309 | /* probe ordering - for components with runtime dependencies */ |
| 286 | int probe_order; | 310 | int probe_order; |
| @@ -353,6 +353,8 @@ struct device; · 352 unmodified lines | |||
| 353 | #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ | 353 | #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */ |
| 354 | #define SND_SOC_DAPM_PRE_POST_PMD \ | 354 | #define SND_SOC_DAPM_PRE_POST_PMD \ |
| 355 | (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) | 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 | /* convenience event type detection */ | 359 | /* convenience event type detection */ |
| 358 | #define SND_SOC_DAPM_EVENT_ON(e) \ | 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 | /* dapm path setup */ | 419 | /* dapm path setup */ |
| 418 | int snd_soc_dapm_new_widgets(struct snd_soc_card *card); | 420 | int snd_soc_dapm_new_widgets(struct snd_soc_card *card); |
| 419 | void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); | 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 | int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, | 425 | int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, |
| 421 | const struct snd_soc_dapm_route *route, int num); | 426 | const struct snd_soc_dapm_route *route, int num); |
| 422 | int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, | 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 | unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ | 667 | unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ |
| 663 | /* Go to BIAS_OFF in suspend if the DAPM context is idle */ | 668 | /* Go to BIAS_OFF in suspend if the DAPM context is idle */ |
| 664 | unsigned int suspend_bias_off:1; | 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 | struct device *dev; /* from parent - for debug */ | 671 | struct device *dev; /* from parent - for debug */ |
| 669 | struct snd_soc_component *component; /* parent component */ | 672 | struct snd_soc_component *component; /* parent component */ |
| @@ -673,10 +676,6 @@ struct snd_soc_dapm_context { · 3 unmodified lines | |||
| 673 | enum snd_soc_bias_level target_bias_level; | 676 | enum snd_soc_bias_level target_bias_level; |
| 674 | struct list_head list; | 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 | struct snd_soc_dapm_wcache path_sink_cache; | 679 | struct snd_soc_dapm_wcache path_sink_cache; |
| 681 | struct snd_soc_dapm_wcache path_source_cache; | 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 | /* internal use only */ | 143 | /* internal use only */ |
| 144 | int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); | 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 | int soc_dpcm_runtime_update(struct snd_soc_card *); | 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 | int dpcm_path_get(struct snd_soc_pcm_runtime *fe, | 155 | int dpcm_path_get(struct snd_soc_pcm_runtime *fe, |
| 149 | int stream, struct snd_soc_dapm_widget_list **list_); | 156 | int stream, struct snd_soc_dapm_widget_list **list_); |
| 150 | int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, | 157 | int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, |
| @@ -362,21 +362,6 @@ · 361 unmodified lines | |||
| 362 | #define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \ | 362 | #define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \ |
| 363 | const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts) | 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 | * Bias levels | 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 | int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, | 490 | int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, |
| 506 | const struct snd_pcm_hardware *hw); | 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 | /* Jack reporting */ | 493 | /* Jack reporting */ |
| 513 | int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, | 494 | int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, |
| 514 | struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, | 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 | int (*trigger)(struct snd_compr_stream *); | 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 | struct snd_soc_rtdcom_list { | 735 | struct snd_soc_rtdcom_list { |
| 881 | struct snd_soc_component *component; | 736 | struct snd_soc_component *component; |
| 882 | struct list_head list; /* rtd::component_list */ | 737 | struct list_head list; /* rtd::component_list */ |
| @@ -1086,6 +941,7 @@ struct snd_soc_dai_link { · 203 unmodified lines | |||
| 1086 | #define COMP_CPU(_dai) { .dai_name = _dai, } | 941 | #define COMP_CPU(_dai) { .dai_name = _dai, } |
| 1087 | #define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, } | 942 | #define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, } |
| 1088 | #define COMP_PLATFORM(_name) { .name = _name } | 943 | #define COMP_PLATFORM(_name) { .name = _name } |
| 944 | #define COMP_AUX(_name) { .name = _name } | ||
| 1089 | #define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } | 945 | #define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } |
| 1090 | 946 | ||
| 1091 | extern struct snd_soc_dai_link_component null_dailink_component[0]; | 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 | struct snd_soc_aux_dev { | 965 | struct snd_soc_aux_dev { |
| 1110 | const char *name; /* Codec name */ | ||
| 1111 | |||
| 1112 | /* | 966 | /* |
| 1113 | * specify multi-codec either by device name, or by | 967 | * specify multi-codec either by device name, or by |
| 1114 | * DT/OF node, but not both. | 968 | * DT/OF node, but not both. |
| 1115 | */ | 969 | */ |
| 1116 | const char *codec_name; | 970 | struct snd_soc_dai_link_component dlc; |
| 1117 | struct device_node *codec_of_node; | ||
| 1118 | 971 | ||
| 1119 | /* codec/machine specific init - e.g. add machine controls */ | 972 | /* codec/machine specific init - e.g. add machine controls */ |
| 1120 | int (*init)(struct snd_soc_component *component); | 973 | int (*init)(struct snd_soc_component *component); |
| @@ -1135,6 +988,10 @@ struct snd_soc_card { · 14 unmodified lines | |||
| 1135 | struct mutex mutex; | 988 | struct mutex mutex; |
| 1136 | struct mutex dapm_mutex; | 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 | spinlock_t dpcm_lock; | 995 | spinlock_t dpcm_lock; |
| 1139 | 996 | ||
| 1140 | bool instantiated; | 997 | bool instantiated; |
| @@ -1203,8 +1060,6 @@ struct snd_soc_card { · 62 unmodified lines | |||
| 1203 | int num_of_dapm_routes; | 1060 | int num_of_dapm_routes; |
| 1204 | bool fully_routed; | 1061 | bool fully_routed; |
| 1205 | 1062 | ||
| 1206 | struct work_struct deferred_resume_work; | ||
| 1207 | |||
| 1208 | /* lists of probed devices belonging to this card */ | 1063 | /* lists of probed devices belonging to this card */ |
| 1209 | struct list_head component_dev_list; | 1064 | struct list_head component_dev_list; |
| 1210 | struct list_head list; | 1065 | struct list_head list; |
| @@ -1224,7 +1079,9 @@ struct snd_soc_card { · 13 unmodified lines | |||
| 1224 | 1079 | ||
| 1225 | #ifdef CONFIG_DEBUG_FS | 1080 | #ifdef CONFIG_DEBUG_FS |
| 1226 | struct dentry *debugfs_card_root; | 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 | #endif | 1085 | #endif |
| 1229 | u32 pop_time; | 1086 | u32 pop_time; |
| 1230 | 1087 | ||
| @@ -1234,6 +1091,10 @@ struct snd_soc_card { · 3 unmodified lines | |||
| 1234 | for ((i) = 0; \ | 1091 | for ((i) = 0; \ |
| 1235 | ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \ | 1092 | ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \ |
| 1236 | (i)++) | 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 | #define for_each_card_links(card, link) \ | 1099 | #define for_each_card_links(card, link) \ |
| 1239 | list_for_each_entry(link, &(card)->dai_link_list, list) | 1100 | list_for_each_entry(link, &(card)->dai_link_list, list) |
| @@ -1245,6 +1106,12 @@ struct snd_soc_card { · 5 unmodified lines | |||
| 1245 | #define for_each_card_rtds_safe(card, rtd, _rtd) \ | 1106 | #define for_each_card_rtds_safe(card, rtd, _rtd) \ |
| 1246 | list_for_each_entry_safe(rtd, _rtd, &(card)->rtd_list, list) | 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 | #define for_each_card_components(card, component) \ | 1115 | #define for_each_card_components(card, component) \ |
| 1249 | list_for_each_entry(component, &(card)->component_dev_list, card_list) | 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 | struct device *dev; | 1120 | struct device *dev; |
| 1254 | struct snd_soc_card *card; | 1121 | struct snd_soc_card *card; |
| 1255 | struct snd_soc_dai_link *dai_link; | 1122 | struct snd_soc_dai_link *dai_link; |
| 1256 | struct mutex pcm_mutex; | ||
| 1257 | enum snd_soc_pcm_subclass pcm_subclass; | ||
| 1258 | struct snd_pcm_ops ops; | 1123 | struct snd_pcm_ops ops; |
| 1259 | 1124 | ||
| 1260 | unsigned int params_select; /* currently selected param for dai link */ | 1125 | unsigned int params_select; /* currently selected param for dai link */ |
| @@ -1342,134 +1207,6 @@ struct soc_enum { · 81 unmodified lines | |||
| 1342 | struct snd_soc_dobj dobj; | 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 | /* device driver data */ | 1210 | /* device driver data */ |
| 1474 | 1211 | ||
| 1475 | static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, | 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 | return card->drvdata; | 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 | static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) | 1223 | static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) |
| 1508 | { | 1224 | { |
| 1509 | if (mc->reg == mc->rreg && mc->shift == mc->rshift) | 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 | return e->values[item]; | 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 | * snd_soc_kcontrol_component() - Returns the component that registered the | 1260 | * snd_soc_kcontrol_component() - Returns the component that registered the |
| 1551 | * control | 1261 | * control |
| @@ -1681,24 +1391,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm) · 129 unmodified lines | |||
| 1681 | mutex_unlock(&dapm->card->dapm_mutex); | 1391 | mutex_unlock(&dapm->card->dapm_mutex); |
| 1682 | } | 1392 | } |
| 1683 | 1393 | ||
| 1684 | int snd_soc_component_enable_pin(struct snd_soc_component *component, | 1394 | #include <sound/soc-component.h> |
| 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); | ||
| 1703 | 1395 | ||
| 1704 | #endif | 1396 | #endif |
| @@ -76,6 +76,9 @@ struct sof_ipc_dai_ssp_params { · 75 unmodified lines | |||
| 76 | uint16_t tdm_per_slot_padding_flag; | 76 | uint16_t tdm_per_slot_padding_flag; |
| 77 | uint32_t clks_control; | 77 | uint32_t clks_control; |
| 78 | uint32_t quirks; | 78 | uint32_t quirks; |
| 79 | uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK | ||
| 80 | * will be driven, before sending data | ||
| 81 | */ | ||
| 79 | } __packed; | 82 | } __packed; |
| 80 | 83 | ||
| 81 | /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ | 84 | /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ |
| @@ -176,4 +179,13 @@ struct sof_ipc_dai_dmic_params { · 94 unmodified lines | |||
| 176 | struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; | 179 | struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; |
| 177 | } __packed; | 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 | #endif | 191 | #endif |
| @@ -49,7 +49,9 @@ enum sof_ipc_dai_type { · 48 unmodified lines | |||
| 49 | SOF_DAI_INTEL_SSP, /**< Intel SSP */ | 49 | SOF_DAI_INTEL_SSP, /**< Intel SSP */ |
| 50 | SOF_DAI_INTEL_DMIC, /**< Intel DMIC */ | 50 | SOF_DAI_INTEL_DMIC, /**< Intel DMIC */ |
| 51 | SOF_DAI_INTEL_HDA, /**< Intel HD/A */ | 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 | /* general purpose DAI configuration */ | 57 | /* general purpose DAI configuration */ |
| @@ -70,6 +72,7 @@ struct sof_ipc_dai_config { · 14 unmodified lines | |||
| 70 | struct sof_ipc_dai_ssp_params ssp; | 72 | struct sof_ipc_dai_ssp_params ssp; |
| 71 | struct sof_ipc_dai_dmic_params dmic; | 73 | struct sof_ipc_dai_dmic_params dmic; |
| 72 | struct sof_ipc_dai_hda_params hda; | 74 | struct sof_ipc_dai_hda_params hda; |
| 75 | struct sof_ipc_dai_alh_params alh; | ||
| 73 | }; | 76 | }; |
| 74 | } __packed; | 77 | } __packed; |
| 75 | 78 | ||
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | /* SOF ABI version major, minor and patch numbers */ | 27 | /* SOF ABI version major, minor and patch numbers */ |
| 28 | #define SOF_ABI_MAJOR 3 | 28 | #define SOF_ABI_MAJOR 3 |
| 29 | #define SOF_ABI_MINOR 8 | 29 | #define SOF_ABI_MINOR 10 |
| 30 | #define SOF_ABI_PATCH 0 | 30 | #define SOF_ABI_PATCH 0 |
| 31 | 31 | ||
| 32 | /* SOF ABI version number. Format within 32bit word is MMmmmppp */ | 32 | /* SOF ABI version number. Format within 32bit word is MMmmmppp */ |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | |||
| 75 | #define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503 | 75 | #define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503 |
| 76 | #define SOF_TKN_INTEL_SSP_QUIRKS 504 | 76 | #define SOF_TKN_INTEL_SSP_QUIRKS 504 |
| 77 | #define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505 | 77 | #define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505 |
| 78 | #define SOF_TKN_INTEL_SSP_BCLK_DELAY 506 | ||
| 78 | 79 | ||
| 79 | /* DMIC */ | 80 | /* DMIC */ |
| 80 | #define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600 | 81 | #define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600 |
| @@ -105,4 +106,12 @@ · 24 unmodified lines | |||
| 105 | /* for backward compatibility */ | 106 | /* for backward compatibility */ |
| 106 | #define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE | 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 | #endif | 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 | static const unsigned int rates[] = { | 2171 | static const unsigned int rates[] = { |
| 2172 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, | 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 | const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { | 2176 | const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { |
| @@ -6,6 +6,9 @@ config SND_HDA_CORE · 5 unmodified lines | |||
| 6 | config SND_HDA_DSP_LOADER | 6 | config SND_HDA_DSP_LOADER |
| 7 | bool | 7 | bool |
| 8 | 8 | ||
| 9 | config SND_HDA_ALIGNED_MMIO | ||
| 10 | bool | ||
| 11 | |||
| 9 | config SND_HDA_COMPONENT | 12 | config SND_HDA_COMPONENT |
| 10 | bool | 13 | bool |
| 11 | 14 | ||
| @@ -29,3 +32,8 @@ config SND_HDA_PREALLOC_SIZE · 17 unmodified lines | |||
| 29 | 32 | ||
| 30 | Note that the pre-allocation size can be changed dynamically | 33 | Note that the pre-allocation size can be changed dynamically |
| 31 | via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too. | 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 | #extended hda | 14 | #extended hda |
| 15 | obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/ | 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 | MODULE_DESCRIPTION("HDA extended core"); | 17 | MODULE_DESCRIPTION("HDA extended core"); |
| 18 | MODULE_LICENSE("GPL v2"); | 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 | * snd_hdac_ext_bus_init - initialize a HD-audio extended bus | 21 | * snd_hdac_ext_bus_init - initialize a HD-audio extended bus |
| 74 | * @ebus: the pointer to extended bus object | 22 | * @ebus: the pointer to extended bus object |
| 75 | * @dev: device pointer | 23 | * @dev: device pointer |
| 76 | * @ops: bus verb operators | 24 | * @ops: bus verb operators |
| 77 | * @io_ops: lowlevel I/O operators, can be NULL. If NULL core will use | ||
| 78 | * default ops | 25 | * default ops |
| 79 | * | 26 | * |
| 80 | * Returns 0 if successful, or a negative error code. | 27 | * Returns 0 if successful, or a negative error code. |
| 81 | */ | 28 | */ |
| 82 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, | 29 | int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, |
| 83 | const struct hdac_bus_ops *ops, | 30 | const struct hdac_bus_ops *ops, |
| 84 | const struct hdac_io_ops *io_ops, | ||
| 85 | const struct hdac_ext_bus_ops *ext_ops) | 31 | const struct hdac_ext_bus_ops *ext_ops) |
| 86 | { | 32 | { |
| 87 | int ret; | 33 | int ret; |
| 88 | 34 | ||
| 89 | /* check if io ops are provided, if not load the defaults */ | 35 | ret = snd_hdac_bus_init(bus, dev, ops); |
| 90 | if (io_ops == NULL) | ||
| 91 | io_ops = &hdac_ext_default_io; | ||
| 92 | |||
| 93 | ret = snd_hdac_bus_init(bus, dev, ops, io_ops); | ||
| 94 | if (ret < 0) | 36 | if (ret < 0) |
| 95 | return ret; | 37 | return ret; |
| 96 | 38 | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
| 7 | #include <linux/io.h> | ||
| 7 | #include <linux/device.h> | 8 | #include <linux/device.h> |
| 8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 9 | #include <linux/export.h> | 10 | #include <linux/export.h> |
| @@ -19,13 +20,11 @@ static const struct hdac_bus_ops default_ops = { · 9 unmodified lines | |||
| 19 | * snd_hdac_bus_init - initialize a HD-audio bas bus | 20 | * snd_hdac_bus_init - initialize a HD-audio bas bus |
| 20 | * @bus: the pointer to bus object | 21 | * @bus: the pointer to bus object |
| 21 | * @ops: bus verb operators | 22 | * @ops: bus verb operators |
| 22 | * @io_ops: lowlevel I/O operators | ||
| 23 | * | 23 | * |
| 24 | * Returns 0 if successful, or a negative error code. | 24 | * Returns 0 if successful, or a negative error code. |
| 25 | */ | 25 | */ |
| 26 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, | 26 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, |
| 27 | const struct hdac_bus_ops *ops, | 27 | const struct hdac_bus_ops *ops) |
| 28 | const struct hdac_io_ops *io_ops) | ||
| 29 | { | 28 | { |
| 30 | memset(bus, 0, sizeof(*bus)); | 29 | memset(bus, 0, sizeof(*bus)); |
| 31 | bus->dev = dev; | 30 | bus->dev = dev; |
| @@ -33,7 +32,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, · 1 unmodified line | |||
| 33 | bus->ops = ops; | 32 | bus->ops = ops; |
| 34 | else | 33 | else |
| 35 | bus->ops = &default_ops; | 34 | bus->ops = &default_ops; |
| 36 | bus->io_ops = io_ops; | 35 | bus->dma_type = SNDRV_DMA_TYPE_DEV; |
| 37 | INIT_LIST_HEAD(&bus->stream_list); | 36 | INIT_LIST_HEAD(&bus->stream_list); |
| 38 | INIT_LIST_HEAD(&bus->codec_list); | 37 | INIT_LIST_HEAD(&bus->codec_list); |
| 39 | INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); | 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 | flush_work(&bus->unsol_work); | 216 | flush_work(&bus->unsol_work); |
| 218 | } | 217 | } |
| 219 | EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device); | 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 | struct hdac_stream *s; | 576 | struct hdac_stream *s; |
| 577 | int num_streams = 0; | 577 | int num_streams = 0; |
| 578 | int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV; | ||
| 578 | int err; | 579 | int err; |
| 579 | 580 | ||
| 580 | list_for_each_entry(s, &bus->stream_list, list) { | 581 | list_for_each_entry(s, &bus->stream_list, list) { |
| 581 | /* allocate memory for the BDL for each stream */ | 582 | /* allocate memory for the BDL for each stream */ |
| 582 | err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, | 583 | err = snd_dma_alloc_pages(dma_type, bus->dev, |
| 583 | BDL_SIZE, &s->bdl); | 584 | BDL_SIZE, &s->bdl); |
| 584 | num_streams++; | 585 | num_streams++; |
| 585 | if (err < 0) | 586 | if (err < 0) |
| 586 | return -ENOMEM; | 587 | return -ENOMEM; |
| @@ -589,16 +590,15 @@ int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus) · 2 unmodified lines | |||
| 589 | if (WARN_ON(!num_streams)) | 590 | if (WARN_ON(!num_streams)) |
| 590 | return -EINVAL; | 591 | return -EINVAL; |
| 591 | /* allocate memory for the position buffer */ | 592 | /* allocate memory for the position buffer */ |
| 592 | err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, | 593 | err = snd_dma_alloc_pages(dma_type, bus->dev, |
| 593 | num_streams * 8, &bus->posbuf); | 594 | num_streams * 8, &bus->posbuf); |
| 594 | if (err < 0) | 595 | if (err < 0) |
| 595 | return -ENOMEM; | 596 | return -ENOMEM; |
| 596 | list_for_each_entry(s, &bus->stream_list, list) | 597 | list_for_each_entry(s, &bus->stream_list, list) |
| 597 | s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8); | 598 | s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8); |
| 598 | 599 | ||
| 599 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ | 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 | return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb); |
| 601 | PAGE_SIZE, &bus->rb); | ||
| 602 | } | 602 | } |
| 603 | EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages); | 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 | list_for_each_entry(s, &bus->stream_list, list) { | 613 | list_for_each_entry(s, &bus->stream_list, list) { |
| 614 | if (s->bdl.area) | 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 | if (bus->rb.area) | 618 | if (bus->rb.area) |
| 619 | bus->io_ops->dma_free_pages(bus, &bus->rb); | 619 | snd_dma_free_pages(&bus->rb); |
| 620 | if (bus->posbuf.area) | 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 | EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages); | 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 | azx_dev->locked = true; | 680 | azx_dev->locked = true; |
| 681 | spin_unlock_irq(&bus->reg_lock); | 681 | spin_unlock_irq(&bus->reg_lock); |
| 682 | 682 | ||
| 683 | err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV_SG, | 683 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev, |
| 684 | byte_size, bufp); | 684 | byte_size, bufp); |
| 685 | if (err < 0) | 685 | if (err < 0) |
| 686 | goto err_alloc; | 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 | return azx_dev->stream_tag; | 707 | return azx_dev->stream_tag; |
| 708 | 708 | ||
| 709 | error: | 709 | error: |
| 710 | bus->io_ops->dma_free_pages(bus, bufp); | 710 | snd_dma_free_pages(bufp); |
| 711 | err_alloc: | 711 | err_alloc: |
| 712 | spin_lock_irq(&bus->reg_lock); | 712 | spin_lock_irq(&bus->reg_lock); |
| 713 | azx_dev->locked = false; | 713 | azx_dev->locked = false; |
| @@ -754,7 +754,7 @@ void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, · 40 unmodified lines | |||
| 754 | azx_dev->period_bytes = 0; | 754 | azx_dev->period_bytes = 0; |
| 755 | azx_dev->format_val = 0; | 755 | azx_dev->format_val = 0; |
| 756 | 756 | ||
| 757 | bus->io_ops->dma_free_pages(bus, dmab); | 757 | snd_dma_free_pages(dmab); |
| 758 | dmab->area = NULL; | 758 | dmab->area = NULL; |
| 759 | 759 | ||
| 760 | spin_lock_irq(&bus->reg_lock); | 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 | tristate "HD Audio PCI" | 12 | tristate "HD Audio PCI" |
| 13 | depends on SND_PCI | 13 | depends on SND_PCI |
| 14 | select SND_HDA | 14 | select SND_HDA |
| 15 | select SND_INTEL_NHLT if ACPI | ||
| 15 | help | 16 | help |
| 16 | Say Y here to include support for Intel "High Definition | 17 | Say Y here to include support for Intel "High Definition |
| 17 | Audio" (Azalia) and its compatible devices. | 18 | Audio" (Azalia) and its compatible devices. |
| @@ -22,10 +23,20 @@ config SND_HDA_INTEL · 4 unmodified lines | |||
| 22 | To compile this driver as a module, choose M here: the module | 23 | To compile this driver as a module, choose M here: the module |
| 23 | will be called snd-hda-intel. | 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 | config SND_HDA_TEGRA | 35 | config SND_HDA_TEGRA |
| 26 | tristate "NVIDIA Tegra HD Audio" | 36 | tristate "NVIDIA Tegra HD Audio" |
| 27 | depends on ARCH_TEGRA | 37 | depends on ARCH_TEGRA |
| 28 | select SND_HDA | 38 | select SND_HDA |
| 39 | select SND_HDA_ALIGNED_MMIO | ||
| 29 | help | 40 | help |
| 30 | Say Y here to support the HDA controller present in NVIDIA | 41 | Say Y here to support the HDA controller present in NVIDIA |
| 31 | Tegra SoCs | 42 | Tegra SoCs |
| @@ -846,7 +846,13 @@ static void snd_hda_codec_dev_release(struct device *dev) · 845 unmodified lines | |||
| 846 | snd_hda_sysfs_clear(codec); | 846 | snd_hda_sysfs_clear(codec); |
| 847 | kfree(codec->modelname); | 847 | kfree(codec->modelname); |
| 848 | kfree(codec->wcaps); | 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 | #define DEV_NAME_LEN 31 | 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 | /* HD-audio bus initialization */ | 1209 | /* HD-audio bus initialization */ |
| 1210 | int azx_bus_init(struct azx *chip, const char *model, | 1210 | int azx_bus_init(struct azx *chip, const char *model) |
| 1211 | const struct hdac_io_ops *io_ops) | ||
| 1212 | { | 1211 | { |
| 1213 | struct hda_bus *bus = &chip->bus; | 1212 | struct hda_bus *bus = &chip->bus; |
| 1214 | int err; | 1213 | int err; |
| 1215 | 1214 | ||
| 1216 | err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops, | 1215 | err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops); |
| 1217 | io_ops); | ||
| 1218 | if (err < 0) | 1216 | if (err < 0) |
| 1219 | return err; | 1217 | return err; |
| 1220 | 1218 | ||
| @@ -206,8 +206,7 @@ void azx_stop_chip(struct azx *chip); · 205 unmodified lines | |||
| 206 | irqreturn_t azx_interrupt(int irq, void *dev_id); | 206 | irqreturn_t azx_interrupt(int irq, void *dev_id); |
| 207 | 207 | ||
| 208 | /* Codec interface */ | 208 | /* Codec interface */ |
| 209 | int azx_bus_init(struct azx *chip, const char *model, | 209 | int azx_bus_init(struct azx *chip, const char *model); |
| 210 | const struct hdac_io_ops *io_ops); | ||
| 211 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots); | 210 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots); |
| 212 | int azx_codec_configure(struct azx *chip); | 211 | int azx_codec_configure(struct azx *chip); |
| 213 | int azx_init_streams(struct azx *chip); | 212 | int azx_init_streams(struct azx *chip); |
| @@ -46,6 +46,7 @@ · 45 unmodified lines | |||
| 46 | #include <sound/initval.h> | 46 | #include <sound/initval.h> |
| 47 | #include <sound/hdaudio.h> | 47 | #include <sound/hdaudio.h> |
| 48 | #include <sound/hda_i915.h> | 48 | #include <sound/hda_i915.h> |
| 49 | #include <sound/intel-nhlt.h> | ||
| 49 | #include <linux/vgaarb.h> | 50 | #include <linux/vgaarb.h> |
| 50 | #include <linux/vga_switcheroo.h> | 51 | #include <linux/vga_switcheroo.h> |
| 51 | #include <linux/firmware.h> | 52 | #include <linux/firmware.h> |
| @@ -125,6 +126,7 @@ static char *patch[SNDRV_CARDS]; · 73 unmodified lines | |||
| 125 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | 126 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
| 126 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | 127 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
| 127 | #endif | 128 | #endif |
| 129 | static bool dmic_detect = IS_ENABLED(CONFIG_SND_HDA_INTEL_DETECT_DMIC); | ||
| 128 | 130 | ||
| 129 | module_param_array(index, int, NULL, 0444); | 131 | module_param_array(index, int, NULL, 0444); |
| 130 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 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 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 161 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
| 160 | "(0=off, 1=on) (default=1)."); | 162 | "(0=off, 1=on) (default=1)."); |
| 161 | #endif | 163 | #endif |
| 164 | module_param(dmic_detect, bool, 0444); | ||
| 165 | MODULE_PARM_DESC(dmic_detect, "DMIC detect on SKL+ platforms"); | ||
| 162 | 166 | ||
| 163 | #ifdef CONFIG_PM | 167 | #ifdef CONFIG_PM |
| 164 | static int param_set_xint(const char *val, const struct kernel_param *kp); | 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 | * constructor | 1689 | * constructor |
| 1686 | */ | 1690 | */ |
| 1687 | static const struct hdac_io_ops pci_hda_io_ops; | ||
| 1688 | static const struct hda_controller_ops pci_hda_ops; | 1691 | static const struct hda_controller_ops pci_hda_ops; |
| 1689 | 1692 | ||
| 1690 | static int azx_create(struct snd_card *card, struct pci_dev *pci, | 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 | else | 1747 | else |
| 1745 | chip->bdl_pos_adj = bdl_pos_adj[dev]; | 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 | if (err < 0) { | 1751 | if (err < 0) { |
| 1749 | kfree(hda); | 1752 | kfree(hda); |
| 1750 | pci_disable_device(pci); | 1753 | pci_disable_device(pci); |
| 1751 | return err; | 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 | /* Workaround for a communication error on CFL (bko#199007) and CNL */ | 1761 | /* Workaround for a communication error on CFL (bko#199007) and CNL */ |
| 1755 | if (IS_CFL(pci) || IS_CNL(pci)) | 1762 | if (IS_CFL(pci) || IS_CNL(pci)) |
| 1756 | azx_bus(chip)->polling_mode = 1; | 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 | #endif | 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 | static int disable_msi_reset_irq(struct azx *chip) | 1995 | static int disable_msi_reset_irq(struct azx *chip) |
| 2024 | { | 1996 | { |
| 2025 | struct hdac_bus *bus = azx_bus(chip); | 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 | return 0; | 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 | static void pcm_mmap_prepare(struct snd_pcm_substream *substream, | 2011 | static void pcm_mmap_prepare(struct snd_pcm_substream *substream, |
| 2058 | struct vm_area_struct *area) | 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 | #endif | 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 | static const struct hda_controller_ops pci_hda_ops = { | 2022 | static const struct hda_controller_ops pci_hda_ops = { |
| 2080 | .disable_msi_reset_irq = disable_msi_reset_irq, | 2023 | .disable_msi_reset_irq = disable_msi_reset_irq, |
| 2081 | .pcm_mmap_prepare = pcm_mmap_prepare, | 2024 | .pcm_mmap_prepare = pcm_mmap_prepare, |
| 2082 | .position_check = azx_position_check, | 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 | static int azx_probe(struct pci_dev *pci, | 2047 | static int azx_probe(struct pci_dev *pci, |
| 2086 | const struct pci_device_id *pci_id) | 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 | card->private_data = chip; | 2074 | card->private_data = chip; |
| 2113 | hda = container_of(chip, struct hda_intel, chip); | 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 | pci_set_drvdata(pci, card); | 2088 | pci_set_drvdata(pci, card); |
| 2116 | 2089 | ||
| 2117 | err = register_vga_switcheroo(chip); | 2090 | err = register_vga_switcheroo(chip); |
| @@ -75,88 +75,6 @@ MODULE_PARM_DESC(power_save, · 74 unmodified lines | |||
| 75 | #define power_save 0 | 75 | #define power_save 0 |
| 76 | #endif | 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 | static const struct hda_controller_ops hda_tegra_ops; /* nothing special */ | 78 | static const struct hda_controller_ops hda_tegra_ops; /* nothing special */ |
| 161 | 79 | ||
| 162 | static void hda_tegra_init(struct hda_tegra *hda) | 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 | INIT_WORK(&hda->probe_work, hda_tegra_probe_work); | 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 | if (err < 0) | 397 | if (err < 0) |
| 480 | return err; | 398 | return err; |
| 481 | 399 | ||
| @@ -51,7 +51,6 @@ source "sound/soc/dwc/Kconfig" · 50 unmodified lines | |||
| 51 | source "sound/soc/fsl/Kconfig" | 51 | source "sound/soc/fsl/Kconfig" |
| 52 | source "sound/soc/hisilicon/Kconfig" | 52 | source "sound/soc/hisilicon/Kconfig" |
| 53 | source "sound/soc/jz4740/Kconfig" | 53 | source "sound/soc/jz4740/Kconfig" |
| 54 | source "sound/soc/nuc900/Kconfig" | ||
| 55 | source "sound/soc/kirkwood/Kconfig" | 54 | source "sound/soc/kirkwood/Kconfig" |
| 56 | source "sound/soc/img/Kconfig" | 55 | source "sound/soc/img/Kconfig" |
| 57 | source "sound/soc/intel/Kconfig" | 56 | source "sound/soc/intel/Kconfig" |
| @@ -1,5 +1,5 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 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 | snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o | 3 | snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o |
| 4 | snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o | 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 | obj-$(CONFIG_SND_SOC) += mediatek/ | 39 | obj-$(CONFIG_SND_SOC) += mediatek/ |
| 40 | obj-$(CONFIG_SND_SOC) += meson/ | 40 | obj-$(CONFIG_SND_SOC) += meson/ |
| 41 | obj-$(CONFIG_SND_SOC) += mxs/ | 41 | obj-$(CONFIG_SND_SOC) += mxs/ |
| 42 | obj-$(CONFIG_SND_SOC) += nuc900/ | ||
| 43 | obj-$(CONFIG_SND_SOC) += kirkwood/ | 42 | obj-$(CONFIG_SND_SOC) += kirkwood/ |
| 44 | obj-$(CONFIG_SND_SOC) += pxa/ | 43 | obj-$(CONFIG_SND_SOC) += pxa/ |
| 45 | obj-$(CONFIG_SND_SOC) += qcom/ | 44 | obj-$(CONFIG_SND_SOC) += qcom/ |
| @@ -1251,8 +1251,7 @@ static int acp_audio_probe(struct platform_device *pdev) · 1250 unmodified lines | |||
| 1251 | if (!audio_drv_data) | 1251 | if (!audio_drv_data) |
| 1252 | return -ENOMEM; | 1252 | return -ENOMEM; |
| 1253 | 1253 | ||
| 1254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1254 | audio_drv_data->acp_mmio = devm_platform_ioremap_resource(pdev, 0); |
| 1255 | audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res); | ||
| 1256 | if (IS_ERR(audio_drv_data->acp_mmio)) | 1255 | if (IS_ERR(audio_drv_data->acp_mmio)) |
| 1257 | return PTR_ERR(audio_drv_data->acp_mmio); | 1256 | return PTR_ERR(audio_drv_data->acp_mmio); |
| 1258 | 1257 | ||
| @@ -12,25 +12,31 @@ if SND_ATMEL_SOC · 11 unmodified lines | |||
| 12 | config SND_ATMEL_SOC_PDC | 12 | config SND_ATMEL_SOC_PDC |
| 13 | tristate | 13 | tristate |
| 14 | depends on HAS_DMA | 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 | config SND_ATMEL_SOC_DMA | 16 | config SND_ATMEL_SOC_DMA |
| 22 | tristate | 17 | tristate |
| 23 | select SND_SOC_GENERIC_DMAENGINE_PCM | 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 | config SND_ATMEL_SOC_SSC | 20 | config SND_ATMEL_SOC_SSC |
| 31 | tristate | 21 | tristate |
| 32 | default y if SND_ATMEL_SOC_SSC_DMA=y || SND_ATMEL_SOC_SSC_PDC=y | 22 | |
| 33 | default m if SND_ATMEL_SOC_SSC_DMA=m || SND_ATMEL_SOC_SSC_PDC=m | 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 | config SND_AT91_SOC_SAM9G20_WM8731 | 41 | config SND_AT91_SOC_SAM9G20_WM8731 |
| 36 | tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" | 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 | dd->pdata = pdata; | 571 | dd->pdata = pdata; |
| 572 | 572 | ||
| 573 | dd->irq = platform_get_irq(pdev, 0); | 573 | dd->irq = platform_get_irq(pdev, 0); |
| 574 | if (dd->irq < 0) { | 574 | if (dd->irq < 0) |
| 575 | ret = dd->irq; | 575 | return dd->irq; |
| 576 | dev_err(dev, "failed to could not get irq: %d\n", ret); | ||
| 577 | return ret; | ||
| 578 | } | ||
| 579 | 576 | ||
| 580 | dd->pclk = devm_clk_get(dev, "pclk"); | 577 | dd->pclk = devm_clk_get(dev, "pclk"); |
| 581 | if (IS_ERR(dd->pclk)) { | 578 | if (IS_ERR(dd->pclk)) { |
| @@ -612,11 +612,8 @@ static int atmel_pdmic_probe(struct platform_device *pdev) · 611 unmodified lines | |||
| 612 | dd->dev = dev; | 612 | dd->dev = dev; |
| 613 | 613 | ||
| 614 | dd->irq = platform_get_irq(pdev, 0); | 614 | dd->irq = platform_get_irq(pdev, 0); |
| 615 | if (dd->irq < 0) { | 615 | if (dd->irq < 0) |
| 616 | ret = dd->irq; | 616 | return dd->irq; |
| 617 | dev_err(dev, "failed to get irq: %d\n", ret); | ||
| 618 | return ret; | ||
| 619 | } | ||
| 620 | 617 | ||
| 621 | dd->pclk = devm_clk_get(dev, "pclk"); | 618 | dd->pclk = devm_clk_get(dev, "pclk"); |
| 622 | if (IS_ERR(dd->pclk)) { | 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 | int dir, channels, bits; | 471 | int dir, channels, bits; |
| 472 | u32 tfmr, rfmr, tcmr, rcmr; | 472 | u32 tfmr, rfmr, tcmr, rcmr; |
| 473 | int ret; | 473 | int ret; |
| 474 | int fslen, fslen_ext; | 474 | int fslen, fslen_ext, fs_osync, fs_edge; |
| 475 | u32 cmr_div; | 475 | u32 cmr_div; |
| 476 | u32 tcmr_period; | 476 | u32 tcmr_period; |
| 477 | u32 rcmr_period; | 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 | * Compute SSC register settings. | 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: | 562 | fslen_ext = (bits - 1) / 16; |
| 565 | /* | 563 | fslen = (bits - 1) % 16; |
| 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 | */ | ||
| 572 | 564 | ||
| 573 | if (bits > 16 && !ssc->pdata->has_fslen_ext) { | 565 | switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 574 | dev_err(dai->dev, | ||
| 575 | "sample size %d is too large for SSC device\n", | ||
| 576 | bits); | ||
| 577 | return -EINVAL; | ||
| 578 | } | ||
| 579 | 566 | ||
| 580 | fslen_ext = (bits - 1) / 16; | 567 | case SND_SOC_DAIFMT_LEFT_J: |
| 581 | fslen = (bits - 1) % 16; | 568 | fs_osync = SSC_FSOS_POSITIVE; |
| 582 | 569 | fs_edge = SSC_START_RISING_RF; | |
| 583 | rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) | 570 | |
| 584 | | SSC_BF(RCMR_STTDLY, START_DELAY) | 571 | rcmr = SSC_BF(RCMR_STTDLY, 0); |
| 585 | | SSC_BF(RCMR_START, SSC_START_FALLING_RF) | 572 | tcmr = SSC_BF(TCMR_STTDLY, 0); |
| 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; | ||
| 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 | break; | 574 | break; |
| 652 | 575 | ||
| 653 | case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: | 576 | case SND_SOC_DAIFMT_I2S: |
| 654 | /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ | 577 | fs_osync = SSC_FSOS_NEGATIVE; |
| 655 | if (bits > 16 && !ssc->pdata->has_fslen_ext) { | 578 | fs_edge = SSC_START_FALLING_RF; |
| 656 | dev_err(dai->dev, | ||
| 657 | "sample size %d is too large for SSC device\n", | ||
| 658 | bits); | ||
| 659 | return -EINVAL; | ||
| 660 | } | ||
| 661 | 579 | ||
| 662 | fslen_ext = (bits - 1) / 16; | 580 | rcmr = SSC_BF(RCMR_STTDLY, 1); |
| 663 | fslen = (bits - 1) % 16; | 581 | tcmr = SSC_BF(TCMR_STTDLY, 1); |
| 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; | ||
| 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 | break; | 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 | * Data is transferred on first BCLK after LRC pulse rising | 589 | * Data is transferred on first BCLK after LRC pulse rising |
| 746 | * edge.If stereo, the right channel data is contiguous with | 590 | * edge.If stereo, the right channel data is contiguous with |
| 747 | * the left channel data. | 591 | * the left channel data. |
| 748 | */ | 592 | */ |
| 749 | rcmr = SSC_BF(RCMR_PERIOD, 0) | 593 | fs_osync = SSC_FSOS_POSITIVE; |
| 750 | | SSC_BF(RCMR_STTDLY, START_DELAY) | 594 | fs_edge = SSC_START_RISING_RF; |
| 751 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) | 595 | fslen = fslen_ext = 0; |
| 752 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | 596 | |
| 753 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | 597 | rcmr = SSC_BF(RCMR_STTDLY, 1); |
| 754 | | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? | 598 | tcmr = SSC_BF(TCMR_STTDLY, 1); |
| 755 | SSC_CKS_PIN : SSC_CKS_CLOCK); | 599 | |
| 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)); | ||
| 781 | break; | 600 | break; |
| 782 | 601 | ||
| 783 | default: | 602 | default: |
| @@ -785,6 +604,70 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line | |||
| 785 | ssc_p->daifmt); | 604 | ssc_p->daifmt); |
| 786 | return -EINVAL; | 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 | pr_debug("atmel_ssc_hw_params: " | 671 | pr_debug("atmel_ssc_hw_params: " |
| 789 | "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", | 672 | "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", |
| 790 | rcmr, rfmr, tcmr, tfmr); | 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 | static int mchp_i2s_mcc_config_divs(struct mchp_i2s_mcc_dev *dev, | 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 | unsigned long clk_rate; | 398 | unsigned long clk_rate; |
| 398 | unsigned long lcm_rate; | 399 | unsigned long lcm_rate; |
| 399 | unsigned long best_rate = 0; | ||
| 400 | unsigned long best_diff_rate = ~0; | 400 | unsigned long best_diff_rate = ~0; |
| 401 | unsigned int sysclk; | 401 | unsigned int sysclk; |
| 402 | struct clk *best_clk = NULL; | 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 | (clk_rate == bclk || clk_rate / (bclk * 2) <= GENMASK(5, 0)); | 423 | (clk_rate == bclk || clk_rate / (bclk * 2) <= GENMASK(5, 0)); |
| 424 | clk_rate += lcm_rate) { | 424 | clk_rate += lcm_rate) { |
| 425 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->gclk, clk_rate, | 425 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->gclk, clk_rate, |
| 426 | &best_clk, &best_rate, | 426 | &best_clk, best_rate, |
| 427 | &best_diff_rate); | 427 | &best_diff_rate); |
| 428 | if (ret) { | 428 | if (ret) { |
| 429 | dev_err(dev->dev, "gclk error for rate %lu: %d", | 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 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->pclk, clk_rate, | 439 | ret = mchp_i2s_mcc_clk_get_rate_diff(dev->pclk, clk_rate, |
| 440 | &best_clk, &best_rate, | 440 | &best_clk, best_rate, |
| 441 | &best_diff_rate); | 441 | &best_diff_rate); |
| 442 | if (ret) { | 442 | if (ret) { |
| 443 | dev_err(dev->dev, "pclk error for rate %lu: %d", | 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 | dev_dbg(dev->dev, "source CLK is %s with rate %lu, diff %lu\n", | 460 | dev_dbg(dev->dev, "source CLK is %s with rate %lu, diff %lu\n", |
| 461 | best_clk == dev->pclk ? "pclk" : "gclk", | 461 | best_clk == dev->pclk ? "pclk" : "gclk", |
| 462 | best_rate, best_diff_rate); | 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 | } | ||
| 472 | 463 | ||
| 473 | /* Configure divisors */ | 464 | /* Configure divisors */ |
| 474 | if (dev->sysclk) | 465 | if (dev->sysclk) |
| 475 | *mra |= MCHP_I2SMCC_MRA_IMCKDIV(best_rate / (2 * sysclk)); | 466 | *mra |= MCHP_I2SMCC_MRA_IMCKDIV(*best_rate / (2 * sysclk)); |
| 476 | *mra |= MCHP_I2SMCC_MRA_ISCKDIV(best_rate / (2 * bclk)); | 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 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_GCLK; | 470 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_GCLK; |
| 480 | ret = clk_prepare(dev->gclk); | 471 | else |
| 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 { | ||
| 486 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_PCLK; | 472 | *mra |= MCHP_I2SMCC_MRA_SRCCLK_PCLK; |
| 487 | dev->gclk_use = 0; | ||
| 488 | } | ||
| 489 | 473 | ||
| 490 | return 0; | 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 | struct snd_pcm_hw_params *params, | 486 | struct snd_pcm_hw_params *params, |
| 503 | struct snd_soc_dai *dai) | 487 | struct snd_soc_dai *dai) |
| 504 | { | 488 | { |
| 489 | unsigned long rate = 0; | ||
| 505 | struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai); | 490 | struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai); |
| 506 | u32 mra = 0; | 491 | u32 mra = 0; |
| 507 | u32 mrb = 0; | 492 | u32 mrb = 0; |
| @@ -640,6 +625,17 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, · 132 unmodified lines | |||
| 640 | return -EINVAL; | 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 | * If we are already running, the wanted setup must be | 640 | * If we are already running, the wanted setup must be |
| 645 | * the same with the one that's currently ongoing | 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 | return 0; | 652 | return 0; |
| 657 | } | 653 | } |
| 658 | 654 | ||
| 659 | /* Save the number of channels to know what interrupts to enable */ | 655 | if (mra & MCHP_I2SMCC_MRA_SRCCLK_GCLK && !dev->gclk_use) { |
| 660 | dev->channels = channels; | 656 | /* set the rate */ |
| 661 | 657 | ret = clk_set_rate(dev->gclk, rate); | |
| 662 | if (set_divs) { | ||
| 663 | bclk_rate = frame_length * params_rate(params); | ||
| 664 | ret = mchp_i2s_mcc_config_divs(dev, bclk_rate, &mra); | ||
| 665 | if (ret) { | 658 | if (ret) { |
| 666 | dev_err(dev->dev, "unable to configure the divisors: %d\n", | 659 | dev_err(dev->dev, |
| 667 | ret); | 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 | return ret; | 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 | ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra); | 676 | ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra); |
| 673 | if (ret < 0) { | 677 | if (ret < 0) { |
| 674 | if (dev->gclk_use) { | 678 | if (dev->gclk_use) { |
| @@ -363,7 +363,7 @@ static const struct snd_soc_component_driver au1xpsc_ac97_component = { · 362 unmodified lines | |||
| 363 | static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) | 363 | static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) |
| 364 | { | 364 | { |
| 365 | int ret; | 365 | int ret; |
| 366 | struct resource *iores, *dmares; | 366 | struct resource *dmares; |
| 367 | unsigned long sel; | 367 | unsigned long sel; |
| 368 | struct au1xpsc_audio_data *wd; | 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 | mutex_init(&wd->lock); | 375 | mutex_init(&wd->lock); |
| 376 | 376 | ||
| 377 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 377 | wd->mmio = devm_platform_ioremap_resource(pdev, 0); |
| 378 | wd->mmio = devm_ioremap_resource(&pdev->dev, iores); | ||
| 379 | if (IS_ERR(wd->mmio)) | 378 | if (IS_ERR(wd->mmio)) |
| 380 | return PTR_ERR(wd->mmio); | 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 | static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) | 292 | static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) |
| 293 | { | 293 | { |
| 294 | struct resource *iores, *dmares; | 294 | struct resource *dmares; |
| 295 | unsigned long sel; | 295 | unsigned long sel; |
| 296 | struct au1xpsc_audio_data *wd; | 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 | if (!wd) | 300 | if (!wd) |
| 301 | return -ENOMEM; | 301 | return -ENOMEM; |
| 302 | 302 | ||
| 303 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 303 | wd->mmio = devm_platform_ioremap_resource(pdev, 0); |
| 304 | wd->mmio = devm_ioremap_resource(&pdev->dev, iores); | ||
| 305 | if (IS_ERR(wd->mmio)) | 304 | if (IS_ERR(wd->mmio)) |
| 306 | return PTR_ERR(wd->mmio); | 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 | struct bcm2835_i2s_dev *dev; | 829 | struct bcm2835_i2s_dev *dev; |
| 830 | int ret; | 830 | int ret; |
| 831 | struct resource *mem; | ||
| 832 | void __iomem *base; | 831 | void __iomem *base; |
| 833 | const __be32 *addr; | 832 | const __be32 *addr; |
| 834 | dma_addr_t dma_base; | 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 | /* Request ioarea */ | 849 | /* Request ioarea */ |
| 851 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 850 | base = devm_platform_ioremap_resource(pdev, 0); |
| 852 | base = devm_ioremap_resource(&pdev->dev, mem); | ||
| 853 | if (IS_ERR(base)) | 851 | if (IS_ERR(base)) |
| 854 | return PTR_ERR(base); | 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 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 639 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 640 | struct snd_pcm_runtime *runtime = substream->runtime; | 640 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 641 | struct cygnus_aio_port *aio; | 641 | struct cygnus_aio_port *aio; |
| 642 | int ret = 0; | ||
| 643 | 642 | ||
| 644 | aio = cygnus_dai_get_dma_data(substream); | 643 | aio = cygnus_dai_get_dma_data(substream); |
| 645 | dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); | 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 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 646 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
| 648 | runtime->dma_bytes = params_buffer_bytes(params); | 647 | runtime->dma_bytes = params_buffer_bytes(params); |
| 649 | 648 | ||
| 650 | return ret; | 649 | return 0; |
| 651 | } | 650 | } |
| 652 | 651 | ||
| 653 | static int cygnus_pcm_hw_free(struct snd_pcm_substream *substream) | 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 | struct snd_pcm_runtime *runtime = substream->runtime; | 667 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 669 | struct cygnus_aio_port *aio; | 668 | struct cygnus_aio_port *aio; |
| 670 | unsigned long bufsize, periodsize; | 669 | unsigned long bufsize, periodsize; |
| 671 | int ret = 0; | ||
| 672 | bool is_play; | 670 | bool is_play; |
| 673 | u32 start; | 671 | u32 start; |
| 674 | struct ringbuf_regs *p_rbuf = NULL; | 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 | ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start, | 691 | ringbuf_set_initial(aio->cygaud->audio, p_rbuf, is_play, start, |
| 694 | periodsize, bufsize); | 692 | periodsize, bufsize); |
| 695 | 693 | ||
| 696 | return ret; | 694 | return 0; |
| 697 | } | 695 | } |
| 698 | 696 | ||
| 699 | static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_pcm_substream *substream) | 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 | cygaud->irq_num = platform_get_irq(pdev, 0); | 1344 | cygaud->irq_num = platform_get_irq(pdev, 0); |
| 1345 | if (cygaud->irq_num <= 0) { | 1345 | if (cygaud->irq_num <= 0) |
| 1346 | dev_err(dev, "platform_get_irq failed\n"); | 1346 | return cygaud->irq_num; |
| 1347 | err = cygaud->irq_num; | ||
| 1348 | return err; | ||
| 1349 | } | ||
| 1350 | 1347 | ||
| 1351 | err = audio_clk_init(pdev, cygaud); | 1348 | err = audio_clk_init(pdev, cygaud); |
| 1352 | if (err) { | 1349 | if (err) { |
| @@ -362,7 +362,6 @@ static const struct snd_soc_component_driver ep93xx_ac97_component = { · 361 unmodified lines | |||
| 362 | static int ep93xx_ac97_probe(struct platform_device *pdev) | 362 | static int ep93xx_ac97_probe(struct platform_device *pdev) |
| 363 | { | 363 | { |
| 364 | struct ep93xx_ac97_info *info; | 364 | struct ep93xx_ac97_info *info; |
| 365 | struct resource *res; | ||
| 366 | int irq; | 365 | int irq; |
| 367 | int ret; | 366 | int ret; |
| 368 | 367 | ||
| @@ -370,8 +369,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 370 | if (!info) | 369 | if (!info) |
| 371 | return -ENOMEM; | 370 | return -ENOMEM; |
| 372 | 371 | ||
| 373 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 372 | info->regs = devm_platform_ioremap_resource(pdev, 0); |
| 374 | info->regs = devm_ioremap_resource(&pdev->dev, res); | ||
| 375 | if (IS_ERR(info->regs)) | 373 | if (IS_ERR(info->regs)) |
| 376 | return PTR_ERR(info->regs); | 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 | static int ep93xx_i2s_probe(struct platform_device *pdev) | 430 | static int ep93xx_i2s_probe(struct platform_device *pdev) |
| 431 | { | 431 | { |
| 432 | struct ep93xx_i2s_info *info; | 432 | struct ep93xx_i2s_info *info; |
| 433 | struct resource *res; | ||
| 434 | int err; | 433 | int err; |
| 435 | 434 | ||
| 436 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 435 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
| 437 | if (!info) | 436 | if (!info) |
| 438 | return -ENOMEM; | 437 | return -ENOMEM; |
| 439 | 438 | ||
| 440 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 439 | info->regs = devm_platform_ioremap_resource(pdev, 0); |
| 441 | info->regs = devm_ioremap_resource(&pdev->dev, res); | ||
| 442 | if (IS_ERR(info->regs)) | 440 | if (IS_ERR(info->regs)) |
| 443 | return PTR_ERR(info->regs); | 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 | * DAPM Controls | 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 | /* AUX1 Switch */ | 532 | /* AUX1 Switch */ |
| 537 | static const struct snd_kcontrol_new aux1_switch_controls = | 533 | static const struct snd_kcontrol_new aux1_switch_controls = |
| 538 | SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0); | 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 | static const struct snd_kcontrol_new repa_switch_controls = | 545 | static const struct snd_kcontrol_new repa_switch_controls = |
| 550 | SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0); | 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 | /* I2S Mux / Mux9 */ | 548 | /* I2S Mux / Mux9 */ |
| 564 | static const char *i2s_din_text[] = { | 549 | static const char *i2s_din_text[] = { |
| 565 | "DIN", "DIN1", | 550 | "DIN", "DIN1", |
| @@ -70,10 +70,12 @@ config SND_SOC_ALL_CODECS · 69 unmodified lines | |||
| 70 | select SND_SOC_CS43130 if I2C | 70 | select SND_SOC_CS43130 if I2C |
| 71 | select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI | 71 | select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI |
| 72 | select SND_SOC_CS4349 if I2C | 72 | select SND_SOC_CS4349 if I2C |
| 73 | select SND_SOC_CS47L15 if MFD_CS47L15 | ||
| 73 | select SND_SOC_CS47L24 if MFD_CS47L24 | 74 | select SND_SOC_CS47L24 if MFD_CS47L24 |
| 74 | select SND_SOC_CS47L35 if MFD_CS47L35 | 75 | select SND_SOC_CS47L35 if MFD_CS47L35 |
| 75 | select SND_SOC_CS47L85 if MFD_CS47L85 | 76 | select SND_SOC_CS47L85 if MFD_CS47L85 |
| 76 | select SND_SOC_CS47L90 if MFD_CS47L90 | 77 | select SND_SOC_CS47L90 if MFD_CS47L90 |
| 78 | select SND_SOC_CS47L92 if MFD_CS47L92 | ||
| 77 | select SND_SOC_CS53L30 if I2C | 79 | select SND_SOC_CS53L30 if I2C |
| 78 | select SND_SOC_CX20442 if TTY | 80 | select SND_SOC_CX20442 if TTY |
| 79 | select SND_SOC_CX2072X if I2C | 81 | select SND_SOC_CX2072X if I2C |
| @@ -197,6 +199,7 @@ config SND_SOC_ALL_CODECS · 117 unmodified lines | |||
| 197 | select SND_SOC_TS3A227E if I2C | 199 | select SND_SOC_TS3A227E if I2C |
| 198 | select SND_SOC_TWL4030 if TWL4030_CORE | 200 | select SND_SOC_TWL4030 if TWL4030_CORE |
| 199 | select SND_SOC_TWL6040 if TWL6040_CORE | 201 | select SND_SOC_TWL6040 if TWL6040_CORE |
| 202 | select SND_SOC_UDA1334 if GPIOLIB | ||
| 200 | select SND_SOC_UDA134X | 203 | select SND_SOC_UDA134X |
| 201 | select SND_SOC_UDA1380 if I2C | 204 | select SND_SOC_UDA1380 if I2C |
| 202 | select SND_SOC_WCD9335 if SLIMBUS | 205 | select SND_SOC_WCD9335 if SLIMBUS |
| @@ -581,6 +584,9 @@ config SND_SOC_CS4349 · 378 unmodified lines | |||
| 581 | tristate "Cirrus Logic CS4349 CODEC" | 584 | tristate "Cirrus Logic CS4349 CODEC" |
| 582 | depends on I2C | 585 | depends on I2C |
| 583 | 586 | ||
| 587 | config SND_SOC_CS47L15 | ||
| 588 | tristate | ||
| 589 | |||
| 584 | config SND_SOC_CS47L24 | 590 | config SND_SOC_CS47L24 |
| 585 | tristate | 591 | tristate |
| 586 | 592 | ||
| @@ -593,6 +599,9 @@ config SND_SOC_CS47L85 · 6 unmodified lines | |||
| 593 | config SND_SOC_CS47L90 | 599 | config SND_SOC_CS47L90 |
| 594 | tristate | 600 | tristate |
| 595 | 601 | ||
| 602 | config SND_SOC_CS47L92 | ||
| 603 | tristate | ||
| 604 | |||
| 596 | # Cirrus Logic Quad-Channel ADC | 605 | # Cirrus Logic Quad-Channel ADC |
| 597 | config SND_SOC_CS53L30 | 606 | config SND_SOC_CS53L30 |
| 598 | tristate "Cirrus Logic CS53L30 CODEC" | 607 | tristate "Cirrus Logic CS53L30 CODEC" |
| @@ -722,12 +731,16 @@ config SND_SOC_LOCHNAGAR_SC · 123 unmodified lines | |||
| 722 | 731 | ||
| 723 | config SND_SOC_MADERA | 732 | config SND_SOC_MADERA |
| 724 | tristate | 733 | tristate |
| 734 | default y if SND_SOC_CS47L15=y | ||
| 725 | default y if SND_SOC_CS47L35=y | 735 | default y if SND_SOC_CS47L35=y |
| 726 | default y if SND_SOC_CS47L85=y | 736 | default y if SND_SOC_CS47L85=y |
| 727 | default y if SND_SOC_CS47L90=y | 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 | default m if SND_SOC_CS47L35=m | 740 | default m if SND_SOC_CS47L35=m |
| 729 | default m if SND_SOC_CS47L85=m | 741 | default m if SND_SOC_CS47L85=m |
| 730 | default m if SND_SOC_CS47L90=m | 742 | default m if SND_SOC_CS47L90=m |
| 743 | default m if SND_SOC_CS47L92=m | ||
| 731 | 744 | ||
| 732 | config SND_SOC_MAX98088 | 745 | config SND_SOC_MAX98088 |
| 733 | tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec" | 746 | tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec" |
| @@ -1195,6 +1208,14 @@ config SND_SOC_TWL4030 · 461 unmodified lines | |||
| 1195 | config SND_SOC_TWL6040 | 1208 | config SND_SOC_TWL6040 |
| 1196 | tristate | 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 | config SND_SOC_UDA134X | 1219 | config SND_SOC_UDA134X |
| 1199 | tristate | 1220 | tristate |
| 1200 | 1221 | ||
| @@ -64,10 +64,12 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o · 63 unmodified lines | |||
| 64 | snd-soc-cs43130-objs := cs43130.o | 64 | snd-soc-cs43130-objs := cs43130.o |
| 65 | snd-soc-cs4341-objs := cs4341.o | 65 | snd-soc-cs4341-objs := cs4341.o |
| 66 | snd-soc-cs4349-objs := cs4349.o | 66 | snd-soc-cs4349-objs := cs4349.o |
| 67 | snd-soc-cs47l15-objs := cs47l15.o | ||
| 67 | snd-soc-cs47l24-objs := cs47l24.o | 68 | snd-soc-cs47l24-objs := cs47l24.o |
| 68 | snd-soc-cs47l35-objs := cs47l35.o | 69 | snd-soc-cs47l35-objs := cs47l35.o |
| 69 | snd-soc-cs47l85-objs := cs47l85.o | 70 | snd-soc-cs47l85-objs := cs47l85.o |
| 70 | snd-soc-cs47l90-objs := cs47l90.o | 71 | snd-soc-cs47l90-objs := cs47l90.o |
| 72 | snd-soc-cs47l92-objs := cs47l92.o | ||
| 71 | snd-soc-cs53l30-objs := cs53l30.o | 73 | snd-soc-cs53l30-objs := cs53l30.o |
| 72 | snd-soc-cx20442-objs := cx20442.o | 74 | snd-soc-cx20442-objs := cx20442.o |
| 73 | snd-soc-cx2072x-objs := cx2072x.o | 75 | snd-soc-cx2072x-objs := cx2072x.o |
| @@ -210,6 +212,7 @@ snd-soc-tscs454-objs := tscs454.o · 136 unmodified lines | |||
| 210 | snd-soc-ts3a227e-objs := ts3a227e.o | 212 | snd-soc-ts3a227e-objs := ts3a227e.o |
| 211 | snd-soc-twl4030-objs := twl4030.o | 213 | snd-soc-twl4030-objs := twl4030.o |
| 212 | snd-soc-twl6040-objs := twl6040.o | 214 | snd-soc-twl6040-objs := twl6040.o |
| 215 | snd-soc-uda1334-objs := uda1334.o | ||
| 213 | snd-soc-uda134x-objs := uda134x.o | 216 | snd-soc-uda134x-objs := uda134x.o |
| 214 | snd-soc-uda1380-objs := uda1380.o | 217 | snd-soc-uda1380-objs := uda1380.o |
| 215 | snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o | 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 | obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o | 349 | obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o |
| 347 | obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o | 350 | obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o |
| 348 | obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o | 351 | obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o |
| 352 | obj-$(CONFIG_SND_SOC_CS47L15) += snd-soc-cs47l15.o | ||
| 349 | obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o | 353 | obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o |
| 350 | obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o | 354 | obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o |
| 351 | obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o | 355 | obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o |
| 356 | obj-$(CONFIG_SND_SOC_CS47L92) += snd-soc-cs47l92.o | ||
| 352 | obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o | 357 | obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o |
| 353 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o | 358 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o |
| 354 | obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o | 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 | obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o | 495 | obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o |
| 491 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o | 496 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
| 492 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | 497 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o |
| 498 | obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o | ||
| 493 | obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o | 499 | obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o |
| 494 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o | 500 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o |
| 495 | obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o | 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 | .ops = &ad193x_dai_ops, | 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 | /* codec register values to set after reset */ | 416 | /* codec register values to set after reset */ |
| 422 | static void ad193x_reg_default_init(struct ad193x_priv *ad193x) | 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 | { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */ | 420 | { 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */ |
| 426 | { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */ | 421 | { 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */ |
| 427 | { 2, 0x40 }, /* DAC_CTRL0: TDM mode */ | 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 | { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */ | 432 | { 12, 0x00 }, /* DAC_L4_VOL: no attenuation */ |
| 438 | { 13, 0x00 }, /* DAC_R4_VOL: no attenuation */ | 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 | { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */ | 436 | { 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */ |
| 442 | { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */ | 437 | { 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */ |
| 443 | { 16, 0x00 }, /* ADC_CTRL2: reset */ | 438 | { 16, 0x00 }, /* ADC_CTRL2: reset */ |
| 444 | }; | 439 | }; |
| 445 | int i; | ||
| 446 | 440 | ||
| 447 | for (i = 0; i < ARRAY_SIZE(reg_init); i++) | 441 | regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init)); |
| 448 | regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val); | ||
| 449 | 442 | ||
| 450 | if (ad193x_has_adc(ad193x)) { | 443 | if (ad193x_has_adc(ad193x)) { |
| 451 | for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) { | 444 | regmap_multi_reg_write(ad193x->regmap, reg_adc_init, |
| 452 | regmap_write(ad193x->regmap, reg_adc_init[i].reg, | 445 | ARRAY_SIZE(reg_adc_init)); |
| 453 | reg_adc_init[i].val); | ||
| 454 | } | ||
| 455 | } | 446 | } |
| 456 | } | 447 | } |
| 457 | 448 | ||
| @@ -334,7 +334,7 @@ static struct cs4271_clk_cfg cs4271_clk_tab[] = { · 333 unmodified lines | |||
| 334 | {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2}, | 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 | static int cs4271_hw_params(struct snd_pcm_substream *substream, | 339 | static int cs4271_hw_params(struct snd_pcm_substream *substream, |
| 340 | struct snd_pcm_hw_params *params, | 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 | val = CS4271_MODE1_MODE_4X; | 383 | val = CS4271_MODE1_MODE_4X; |
| 384 | 384 | ||
| 385 | ratio = cs4271->mclk / cs4271->rate; | 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 | if ((cs4271_clk_tab[i].master == cs4271->master) && | 387 | if ((cs4271_clk_tab[i].master == cs4271->master) && |
| 388 | (cs4271_clk_tab[i].speed_mode == val) && | 388 | (cs4271_clk_tab[i].speed_mode == val) && |
| 389 | (cs4271_clk_tab[i].ratio == ratio)) | 389 | (cs4271_clk_tab[i].ratio == ratio)) |
| 390 | break; | 390 | break; |
| 391 | 391 | ||
| 392 | if (i == CS4171_NR_RATIOS) { | 392 | if (i == CS4271_NR_RATIOS) { |
| 393 | dev_err(component->dev, "Invalid sample rate\n"); | 393 | dev_err(component->dev, "Invalid sample rate\n"); |
| 394 | return -EINVAL; | 394 | return -EINVAL; |
| 395 | } | 395 | } |
| @@ -199,14 +199,6 @@ static const struct soc_enum beep_bass_enum = · 198 unmodified lines | |||
| 199 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, | 199 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, |
| 200 | ARRAY_SIZE(beep_bass_text), beep_bass_text); | 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 | static const char * const pgaa_mux_text[] = { | 202 | static const char * const pgaa_mux_text[] = { |
| 211 | "AIN1A", "AIN2A", "AIN3A"}; | 203 | "AIN1A", "AIN2A", "AIN3A"}; |
| 212 | 204 | ||
| @@ -273,12 +273,6 @@ static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum, · 272 unmodified lines | |||
| 273 | CS42L73_MIXERCTL, 4, | 273 | CS42L73_MIXERCTL, 4, |
| 274 | cs42l73_spo_mixer_text); | 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 | static const struct snd_kcontrol_new hp_amp_ctl = | 276 | static const struct snd_kcontrol_new hp_amp_ctl = |
| 283 | SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1); | 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 | #endif | 684 | #endif |
| 685 | 685 | ||
| 686 | const struct dev_pm_ops cs42xx8_pm = { | 686 | const struct dev_pm_ops cs42xx8_pm = { |
| 687 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
| 688 | pm_runtime_force_resume) | ||
| 687 | SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) | 689 | SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) |
| 688 | }; | 690 | }; |
| 689 | EXPORT_SYMBOL_GPL(cs42xx8_pm); | 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 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 524 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 525 | SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, | 525 | SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK, |
| 526 | MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0), | 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 | 0, NULL, 0), | 528 | 0, NULL, 0), |
| 529 | 529 | ||
| 530 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0), | 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 | return IRQ_HANDLED; | 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 | static int cs47l90_component_probe(struct snd_soc_component *component) | 2405 | static int cs47l90_component_probe(struct snd_soc_component *component) |
| 2413 | { | 2406 | { |
| 2414 | struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component); | 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 | if (ret == 0) { | 2552 | if (ret == 0) { |
| 2560 | ret = madera_init_bus_error_irq(&cs47l90->core, i, | 2553 | ret = madera_init_bus_error_irq(&cs47l90->core, i, |
| 2561 | cs47l90_dsp_bus_error); | 2554 | wm_adsp2_bus_error); |
| 2562 | if (ret != 0) | 2555 | if (ret != 0) |
| 2563 | wm_adsp2_remove(&cs47l90->core.adsp[i]); | 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 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/acpi.h> | 11 | #include <linux/acpi.h> |
| 12 | #include <linux/clk.h> | ||
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 13 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
| 14 | #include <linux/mod_devicetable.h> | 15 | #include <linux/mod_devicetable.h> |
| @@ -33,6 +34,7 @@ static const unsigned int supported_mclk_lrck_ratios[] = { · 18 unmodified lines | |||
| 33 | 34 | ||
| 34 | struct es8316_priv { | 35 | struct es8316_priv { |
| 35 | struct mutex lock; | 36 | struct mutex lock; |
| 37 | struct clk *mclk; | ||
| 36 | struct regmap *regmap; | 38 | struct regmap *regmap; |
| 37 | struct snd_soc_component *component; | 39 | struct snd_soc_component *component; |
| 38 | struct snd_soc_jack *jack; | 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 | struct snd_soc_component *component = codec_dai->component; | 366 | struct snd_soc_component *component = codec_dai->component; |
| 365 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | 367 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 366 | int i; | 368 | int i, ret; |
| 367 | int count = 0; | 369 | int count = 0; |
| 368 | 370 | ||
| 369 | es8316->sysclk = freq; | 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 | return 0; | 377 | return 0; |
| 378 | } | ||
| 379 | |||
| 380 | ret = clk_set_rate(es8316->mclk, freq); | ||
| 381 | if (ret) | ||
| 382 | return ret; | ||
| 373 | 383 | ||
| 374 | /* Limit supported sample rates to ones that can be autodetected | 384 | /* Limit supported sample rates to ones that can be autodetected |
| 375 | * by the codec running in slave mode. | 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 | struct snd_soc_component *component = dai->component; | 454 | struct snd_soc_component *component = dai->component; |
| 445 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | 455 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 446 | 456 | ||
| 447 | if (es8316->sysclk == 0) { | 457 | if (es8316->sysclk_constraints.list) |
| 448 | dev_err(component->dev, "No sysclk provided\n"); | 458 | snd_pcm_hw_constraint_list(substream->runtime, 0, |
| 449 | return -EINVAL; | 459 | SNDRV_PCM_HW_PARAM_RATE, |
| 450 | } | 460 | &es8316->sysclk_constraints); |
| 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); | ||
| 458 | 461 | ||
| 459 | return 0; | 462 | return 0; |
| 460 | } | 463 | } |
| @@ -466,11 +469,19 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, · 5 unmodified lines | |||
| 466 | struct snd_soc_component *component = dai->component; | 469 | struct snd_soc_component *component = dai->component; |
| 467 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | 470 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 468 | u8 wordlen = 0; | 471 | u8 wordlen = 0; |
| 472 | int i; | ||
| 469 | 473 | ||
| 470 | if (!es8316->sysclk) { | 474 | /* Validate supported sample rates that are autodetected from MCLK */ |
| 471 | dev_err(component->dev, "No MCLK configured\n"); | 475 | for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) { |
| 472 | return -EINVAL; | 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 | switch (params_format(params)) { | 486 | switch (params_format(params)) { |
| 476 | case SNDRV_PCM_FORMAT_S16_LE: | 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 | static int es8316_probe(struct snd_soc_component *component) | 711 | static int es8316_probe(struct snd_soc_component *component) |
| 701 | { | 712 | { |
| 702 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | 713 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 714 | int ret; | ||
| 703 | 715 | ||
| 704 | es8316->component = component; | 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 | /* Reset codec and enable current state machine */ | 732 | /* Reset codec and enable current state machine */ |
| 707 | snd_soc_component_write(component, ES8316_RESET, 0x3f); | 733 | snd_soc_component_write(component, ES8316_RESET, 0x3f); |
| 708 | usleep_range(5000, 5500); | 734 | usleep_range(5000, 5500); |
| @@ -725,8 +751,16 @@ static int es8316_probe(struct snd_soc_component *component) · 16 unmodified lines | |||
| 725 | return 0; | 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 | static const struct snd_soc_component_driver soc_component_dev_es8316 = { | 761 | static const struct snd_soc_component_driver soc_component_dev_es8316 = { |
| 729 | .probe = es8316_probe, | 762 | .probe = es8316_probe, |
| 763 | .remove = es8316_remove, | ||
| 730 | .set_jack = es8316_set_jack, | 764 | .set_jack = es8316_set_jack, |
| 731 | .controls = es8316_snd_controls, | 765 | .controls = es8316_snd_controls, |
| 732 | .num_controls = ARRAY_SIZE(es8316_snd_controls), | 766 | .num_controls = ARRAY_SIZE(es8316_snd_controls), |
| @@ -99,7 +99,6 @@ static SOC_ENUM_SINGLE_DECL(adcpol, · 98 unmodified lines | |||
| 99 | 99 | ||
| 100 | static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); | 100 | static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); |
| 101 | static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); | 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 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | 102 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); |
| 104 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); | 103 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); |
| 105 | 104 | ||
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
| 9 | #include <sound/core.h> | 9 | #include <sound/core.h> |
| 10 | #include <sound/jack.h> | ||
| 10 | #include <sound/pcm.h> | 11 | #include <sound/pcm.h> |
| 11 | #include <sound/pcm_params.h> | 12 | #include <sound/pcm_params.h> |
| 12 | #include <sound/soc.h> | 13 | #include <sound/soc.h> |
| @@ -274,6 +275,8 @@ struct hdmi_codec_priv { · 261 unmodified lines | |||
| 274 | struct snd_pcm_chmap *chmap_info; | 275 | struct snd_pcm_chmap *chmap_info; |
| 275 | unsigned int chmap_idx; | 276 | unsigned int chmap_idx; |
| 276 | struct mutex lock; | 277 | struct mutex lock; |
| 278 | struct snd_soc_jack *jack; | ||
| 279 | unsigned int jack_status; | ||
| 277 | }; | 280 | }; |
| 278 | 281 | ||
| 279 | static const struct snd_soc_dapm_widget hdmi_widgets[] = { | 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 | return 0; | 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 | static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) | 712 | static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) |
| 667 | { | 713 | { |
| 668 | struct hdmi_codec_daifmt *cf = dai->playback_dma_data; | 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 | struct rk3036_codec_priv *priv; | 406 | struct rk3036_codec_priv *priv; |
| 407 | struct device_node *of_node = pdev->dev.of_node; | 407 | struct device_node *of_node = pdev->dev.of_node; |
| 408 | struct resource *res; | ||
| 409 | void __iomem *base; | 408 | void __iomem *base; |
| 410 | struct regmap *grf; | 409 | struct regmap *grf; |
| 411 | int ret; | 410 | int ret; |
| @@ -414,8 +413,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 414 | if (!priv) | 413 | if (!priv) |
| 415 | return -ENOMEM; | 414 | return -ENOMEM; |
| 416 | 415 | ||
| 417 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 416 | base = devm_platform_ioremap_resource(pdev, 0); |
| 418 | base = devm_ioremap_resource(&pdev->dev, res); | ||
| 419 | if (IS_ERR(base)) | 417 | if (IS_ERR(base)) |
| 420 | return PTR_ERR(base); | 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 | struct device *dev = &pdev->dev; | 546 | struct device *dev = &pdev->dev; |
| 547 | struct jz_icdc *icdc; | 547 | struct jz_icdc *icdc; |
| 548 | struct resource *mem; | ||
| 549 | int ret; | 548 | int ret; |
| 550 | 549 | ||
| 551 | icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL); | 550 | icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL); |
| 552 | if (!icdc) | 551 | if (!icdc) |
| 553 | return -ENOMEM; | 552 | return -ENOMEM; |
| 554 | 553 | ||
| 555 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 554 | icdc->base = devm_platform_ioremap_resource(pdev, 0); |
| 556 | icdc->base = devm_ioremap_resource(dev, mem); | ||
| 557 | if (IS_ERR(icdc->base)) | 555 | if (IS_ERR(icdc->base)) |
| 558 | return PTR_ERR(icdc->base); | 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 | int ret; | 319 | int ret; |
| 320 | struct jz4740_codec *jz4740_codec; | 320 | struct jz4740_codec *jz4740_codec; |
| 321 | struct resource *mem; | ||
| 322 | void __iomem *base; | 321 | void __iomem *base; |
| 323 | 322 | ||
| 324 | jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), | 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 | if (!jz4740_codec) | 325 | if (!jz4740_codec) |
| 327 | return -ENOMEM; | 326 | return -ENOMEM; |
| 328 | 327 | ||
| 329 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 328 | base = devm_platform_ioremap_resource(pdev, 0); |
| 330 | base = devm_ioremap_resource(&pdev->dev, mem); | ||
| 331 | if (IS_ERR(base)) | 329 | if (IS_ERR(base)) |
| 332 | return PTR_ERR(base); | 330 | return PTR_ERR(base); |
| 333 | 331 | ||
| @@ -87,6 +87,16 @@ · 86 unmodified lines | |||
| 87 | #define MADERA_FLLAO_MIN_N 4 | 87 | #define MADERA_FLLAO_MIN_N 4 |
| 88 | #define MADERA_FLLAO_MAX_N 1023 | 88 | #define MADERA_FLLAO_MAX_N 1023 |
| 89 | #define MADERA_FLLAO_MAX_FBDIV 254 | 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 | #define MADERA_FLL_SYNCHRONISER_OFFS 0x10 | 101 | #define MADERA_FLL_SYNCHRONISER_OFFS 0x10 |
| 92 | #define CS47L35_FLL_SYNCHRONISER_OFFS 0xE | 102 | #define CS47L35_FLL_SYNCHRONISER_OFFS 0xE |
| @@ -96,6 +106,7 @@ · 3 unmodified lines | |||
| 96 | #define MADERA_FLL_CONTROL_4_OFFS 0x4 | 106 | #define MADERA_FLL_CONTROL_4_OFFS 0x4 |
| 97 | #define MADERA_FLL_CONTROL_5_OFFS 0x5 | 107 | #define MADERA_FLL_CONTROL_5_OFFS 0x5 |
| 98 | #define MADERA_FLL_CONTROL_6_OFFS 0x6 | 108 | #define MADERA_FLL_CONTROL_6_OFFS 0x6 |
| 109 | #define MADERA_FLL_GAIN_OFFS 0x8 | ||
| 99 | #define MADERA_FLL_CONTROL_7_OFFS 0x9 | 110 | #define MADERA_FLL_CONTROL_7_OFFS 0x9 |
| 100 | #define MADERA_FLL_EFS_2_OFFS 0xA | 111 | #define MADERA_FLL_EFS_2_OFFS 0xA |
| 101 | #define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1 | 112 | #define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1 |
| @@ -107,6 +118,9 @@ · 5 unmodified lines | |||
| 107 | #define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7 | 118 | #define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7 |
| 108 | #define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9 | 119 | #define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9 |
| 109 | #define MADERA_FLL_GPIO_CLOCK_OFFS 0xA | 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 | #define MADERA_FLLAO_CONTROL_1_OFFS 0x1 | 125 | #define MADERA_FLLAO_CONTROL_1_OFFS 0x1 |
| 112 | #define MADERA_FLLAO_CONTROL_2_OFFS 0x2 | 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 | EXPORT_SYMBOL_GPL(madera_free_overheat); | 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 | int madera_core_init(struct madera_priv *priv) | 411 | int madera_core_init(struct madera_priv *priv) |
| 304 | { | 412 | { |
| 305 | int i; | 413 | int i; |
| @@ -308,6 +416,9 @@ int madera_core_init(struct madera_priv *priv) · 2 unmodified lines | |||
| 308 | BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]); | 416 | BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]); |
| 309 | BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]); | 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 | mutex_init(&priv->rate_lock); | 422 | mutex_init(&priv->rate_lock); |
| 312 | 423 | ||
| 313 | for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++) | 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 | int max_analogue_inputs, max_dmic_sup, i; | 1055 | int max_analogue_inputs, max_dmic_sup, i; |
| 945 | 1056 | ||
| 946 | switch (madera->type) { | 1057 | switch (madera->type) { |
| 1058 | case CS47L15: | ||
| 1059 | max_analogue_inputs = 1; | ||
| 1060 | max_dmic_sup = 2; | ||
| 1061 | break; | ||
| 947 | case CS47L35: | 1062 | case CS47L35: |
| 948 | max_analogue_inputs = 2; | 1063 | max_analogue_inputs = 2; |
| 949 | max_dmic_sup = 2; | 1064 | max_dmic_sup = 2; |
| @@ -1770,6 +1885,18 @@ const struct soc_enum madera_asrc1_rate[] = { · 820 unmodified lines | |||
| 1770 | }; | 1885 | }; |
| 1771 | EXPORT_SYMBOL_GPL(madera_asrc1_rate); | 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 | const struct soc_enum madera_asrc2_rate[] = { | 1900 | const struct soc_enum madera_asrc2_rate[] = { |
| 1774 | SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1, | 1901 | SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1, |
| 1775 | MADERA_ASRC2_RATE1_SHIFT, 0xf, | 1902 | MADERA_ASRC2_RATE1_SHIFT, 0xf, |
| @@ -2149,6 +2276,9 @@ int madera_out_ev(struct snd_soc_dapm_widget *w, · 373 unmodified lines | |||
| 2149 | switch (madera->type) { | 2276 | switch (madera->type) { |
| 2150 | case CS47L90: | 2277 | case CS47L90: |
| 2151 | case CS47L91: | 2278 | case CS47L91: |
| 2279 | case CS42L92: | ||
| 2280 | case CS47L92: | ||
| 2281 | case CS47L93: | ||
| 2152 | out_up_delay = 6; | 2282 | out_up_delay = 6; |
| 2153 | break; | 2283 | break; |
| 2154 | default: | 2284 | default: |
| @@ -2264,9 +2394,17 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w, · 109 unmodified lines | |||
| 2264 | madera->hp_ena &= ~mask; | 2394 | madera->hp_ena &= ~mask; |
| 2265 | madera->hp_ena |= val; | 2395 | madera->hp_ena |= val; |
| 2266 | 2396 | ||
| 2267 | /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */ | 2397 | switch (madera->type) { |
| 2268 | regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); | 2398 | case CS42L92: |
| 2269 | ep_sel &= MADERA_EP_SEL_MASK; | 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 | /* Force off if HPDET has disabled the clamp for this output */ | 2409 | /* Force off if HPDET has disabled the clamp for this output */ |
| 2272 | if (!ep_sel && | 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 | int madera_set_sysclk(struct snd_soc_component *component, int clk_id, | 2635 | int madera_set_sysclk(struct snd_soc_component *component, int clk_id, |
| 2446 | int source, unsigned int freq, int dir) | 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 | case MADERA_CLK_OPCLK: | 2668 | case MADERA_CLK_OPCLK: |
| 2479 | case MADERA_CLK_ASYNC_OPCLK: | 2669 | case MADERA_CLK_ASYNC_OPCLK: |
| 2480 | return madera_set_opclk(component, clk_id, freq); | 2670 | return madera_set_opclk(component, clk_id, freq); |
| 2671 | case MADERA_CLK_OUTCLK: | ||
| 2672 | return madera_set_outclk(component, source, freq); | ||
| 2481 | default: | 2673 | default: |
| 2482 | return -EINVAL; | 2674 | return -EINVAL; |
| 2483 | } | 2675 | } |
| @@ -2691,6 +2883,10 @@ static const unsigned int madera_sr_vals[] = { · 207 unmodified lines | |||
| 2691 | #define MADERA_192K_44K1_RATE_MASK 0x003E00 | 2883 | #define MADERA_192K_44K1_RATE_MASK 0x003E00 |
| 2692 | #define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \ | 2884 | #define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \ |
| 2693 | MADERA_192K_44K1_RATE_MASK) | 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 | static const struct snd_pcm_hw_constraint_list madera_constraint = { | 2891 | static const struct snd_pcm_hw_constraint_list madera_constraint = { |
| 2696 | .count = ARRAY_SIZE(madera_sr_vals), | 2892 | .count = ARRAY_SIZE(madera_sr_vals), |
| @@ -2703,6 +2899,7 @@ static int madera_startup(struct snd_pcm_substream *substream, · 6 unmodified lines | |||
| 2703 | struct snd_soc_component *component = dai->component; | 2899 | struct snd_soc_component *component = dai->component; |
| 2704 | struct madera_priv *priv = snd_soc_component_get_drvdata(component); | 2900 | struct madera_priv *priv = snd_soc_component_get_drvdata(component); |
| 2705 | struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1]; | 2901 | struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1]; |
| 2902 | struct madera *madera = priv->madera; | ||
| 2706 | unsigned int base_rate; | 2903 | unsigned int base_rate; |
| 2707 | 2904 | ||
| 2708 | if (!substream->runtime) | 2905 | if (!substream->runtime) |
| @@ -2722,12 +2919,26 @@ static int madera_startup(struct snd_pcm_substream *substream, · 13 unmodified lines | |||
| 2722 | return 0; | 2919 | return 0; |
| 2723 | } | 2920 | } |
| 2724 | 2921 | ||
| 2725 | if (base_rate == 0) | 2922 | switch (madera->type) { |
| 2726 | dai_priv->constraint.mask = MADERA_192K_RATE_MASK; | 2923 | case CS42L92: |
| 2727 | else if (base_rate % 4000) | 2924 | case CS47L92: |
| 2728 | dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK; | 2925 | case CS47L93: |
| 2729 | else | 2926 | if (base_rate == 0) |
| 2730 | dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK; | 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 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | 2943 | return snd_pcm_hw_constraint_list(substream->runtime, 0, |
| 2733 | SNDRV_PCM_HW_PARAM_RATE, | 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 | EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk); | 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 | * madera_set_output_mode - Set the mode of the specified output | 4565 | * madera_set_output_mode - Set the mode of the specified output |
| 4053 | * | 4566 | * |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | |||
| 47 | #define MADERA_CLK_SYSCLK_3 6 | 47 | #define MADERA_CLK_SYSCLK_3 6 |
| 48 | #define MADERA_CLK_ASYNCCLK_2 7 | 48 | #define MADERA_CLK_ASYNCCLK_2 7 |
| 49 | #define MADERA_CLK_DSPCLK 8 | 49 | #define MADERA_CLK_DSPCLK 8 |
| 50 | #define MADERA_CLK_OUTCLK 9 | ||
| 50 | 51 | ||
| 51 | #define MADERA_CLK_SRC_MCLK1 0x0 | 52 | #define MADERA_CLK_SRC_MCLK1 0x0 |
| 52 | #define MADERA_CLK_SRC_MCLK2 0x1 | 53 | #define MADERA_CLK_SRC_MCLK2 0x1 |
| @@ -61,6 +62,12 @@ · 8 unmodified lines | |||
| 61 | #define MADERA_CLK_SRC_AIF4BCLK 0xB | 62 | #define MADERA_CLK_SRC_AIF4BCLK 0xB |
| 62 | #define MADERA_CLK_SRC_FLLAO 0xF | 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 | #define MADERA_MIXER_VOL_MASK 0x00FE | 71 | #define MADERA_MIXER_VOL_MASK 0x00FE |
| 65 | #define MADERA_MIXER_VOL_SHIFT 1 | 72 | #define MADERA_MIXER_VOL_SHIFT 1 |
| 66 | #define MADERA_MIXER_VOL_WIDTH 7 | 73 | #define MADERA_MIXER_VOL_WIDTH 7 |
| @@ -326,6 +333,7 @@ extern const struct soc_enum madera_sample_rate[]; · 259 unmodified lines | |||
| 326 | extern const struct soc_enum madera_isrc_fsl[]; | 333 | extern const struct soc_enum madera_isrc_fsl[]; |
| 327 | extern const struct soc_enum madera_isrc_fsh[]; | 334 | extern const struct soc_enum madera_isrc_fsh[]; |
| 328 | extern const struct soc_enum madera_asrc1_rate[]; | 335 | extern const struct soc_enum madera_asrc1_rate[]; |
| 336 | extern const struct soc_enum madera_asrc1_bidir_rate[]; | ||
| 329 | extern const struct soc_enum madera_asrc2_rate[]; | 337 | extern const struct soc_enum madera_asrc2_rate[]; |
| 330 | extern const struct soc_enum madera_dfc_width[]; | 338 | extern const struct soc_enum madera_dfc_width[]; |
| 331 | extern const struct soc_enum madera_dfc_type[]; | 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 | unsigned int fref, unsigned int fout); | 411 | unsigned int fref, unsigned int fout); |
| 404 | int madera_set_fll_ao_refclk(struct madera_fll *fll, int source, | 412 | int madera_set_fll_ao_refclk(struct madera_fll *fll, int source, |
| 405 | unsigned int fin, unsigned int fout); | 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 | int madera_core_init(struct madera_priv *priv); | 417 | int madera_core_init(struct madera_priv *priv); |
| 408 | int madera_core_free(struct madera_priv *priv); | 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 | 8, 10, TLV_DB_SCALE_ITEM(400, 100, 0) | 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 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1); | 157 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1); |
| 162 | 158 | ||
| 163 | static const struct snd_kcontrol_new max98371_snd_controls[] = { | 159 | static const struct snd_kcontrol_new max98371_snd_controls[] = { |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <sound/pcm_params.h> | 12 | #include <sound/pcm_params.h> |
| 13 | #include <sound/soc.h> | 13 | #include <sound/soc.h> |
| 14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
| 15 | #include <linux/of.h> | ||
| 15 | #include <linux/of_gpio.h> | 16 | #include <linux/of_gpio.h> |
| 16 | #include <sound/tlv.h> | 17 | #include <sound/tlv.h> |
| 17 | #include "max98373.h" | 18 | #include "max98373.h" |
| @@ -901,6 +902,17 @@ static void max98373_slot_config(struct i2c_client *i2c, · 883 unmodified lines | |||
| 901 | else | 902 | else |
| 902 | max98373->i_slot = 1; | 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 | if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) | 916 | if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) |
| 905 | max98373->spkfb_slot = value & 0xF; | 917 | max98373->spkfb_slot = value & 0xF; |
| 906 | else | 918 | else |
| @@ -929,7 +941,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c, · 22 unmodified lines | |||
| 929 | else | 941 | else |
| 930 | max98373->interleave_mode = false; | 942 | max98373->interleave_mode = false; |
| 931 | 943 | ||
| 932 | |||
| 933 | /* regmap initialization */ | 944 | /* regmap initialization */ |
| 934 | max98373->regmap | 945 | max98373->regmap |
| 935 | = devm_regmap_init_i2c(i2c, &max98373_regmap); | 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 | return ret; | 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 | /* Check Revision ID */ | 972 | /* Check Revision ID */ |
| 944 | ret = regmap_read(max98373->regmap, | 973 | ret = regmap_read(max98373->regmap, |
| 945 | MAX98373_R21FF_REV_ID, ®); | 974 | MAX98373_R21FF_REV_ID, ®); |
| @@ -950,9 +979,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c, · 4 unmodified lines | |||
| 950 | } | 979 | } |
| 951 | dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg); | 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 | /* codec registeration */ | 982 | /* codec registeration */ |
| 957 | ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373, | 983 | ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373, |
| 958 | max98373_dai, ARRAY_SIZE(max98373_dai)); | 984 | max98373_dai, ARRAY_SIZE(max98373_dai)); |
| @@ -205,6 +205,7 @@ · 204 unmodified lines | |||
| 205 | 205 | ||
| 206 | struct max98373_priv { | 206 | struct max98373_priv { |
| 207 | struct regmap *regmap; | 207 | struct regmap *regmap; |
| 208 | int reset_gpio; | ||
| 208 | unsigned int v_slot; | 209 | unsigned int v_slot; |
| 209 | unsigned int i_slot; | 210 | unsigned int i_slot; |
| 210 | unsigned int spkfb_slot; | 211 | unsigned int spkfb_slot; |
| @@ -27,19 +27,6 @@ struct max9850_priv { · 26 unmodified lines | |||
| 27 | unsigned int sysclk; | 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 | /* these registers are not used at the moment but provided for the sake of | 30 | /* these registers are not used at the moment but provided for the sake of |
| 44 | * completeness */ | 31 | * completeness */ |
| 45 | static bool max9850_volatile_register(struct device *dev, unsigned int reg) | 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 | "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V" | 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 | static const char *const max98926_pdm_ch_text[] = { | 23 | static const char *const max98926_pdm_ch_text[] = { |
| 33 | "Current", "Voltage", | 24 | "Current", "Voltage", |
| 34 | }; | 25 | }; |
| @@ -56,7 +56,6 @@ static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0); · 55 unmodified lines | |||
| 56 | static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0); | 56 | static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0); |
| 57 | static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0); | 57 | static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0); |
| 58 | static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0); | 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 | static const char * const ml26124_companding[] = {"16bit PCM", "u-law", | 60 | static const char * const ml26124_companding[] = {"16bit PCM", "u-law", |
| 62 | "A-law"}; | 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 | irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); | 1187 | irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); |
| 1188 | if (irq < 0) { | 1188 | if (irq < 0) |
| 1189 | dev_err(dev, "failed to get mbhc switch irq\n"); | ||
| 1190 | return irq; | 1189 | return irq; |
| 1191 | } | ||
| 1192 | 1190 | ||
| 1193 | ret = devm_request_threaded_irq(dev, irq, NULL, | 1191 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1194 | pm8916_mbhc_switch_irq_handler, | 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 | if (priv->mbhc_btn_enabled) { | 1199 | if (priv->mbhc_btn_enabled) { |
| 1202 | irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); | 1200 | irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); |
| 1203 | if (irq < 0) { | 1201 | if (irq < 0) |
| 1204 | dev_err(dev, "failed to get button press irq\n"); | ||
| 1205 | return irq; | 1202 | return irq; |
| 1206 | } | ||
| 1207 | 1203 | ||
| 1208 | ret = devm_request_threaded_irq(dev, irq, NULL, | 1204 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1209 | mbhc_btn_press_irq_handler, | 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 | dev_err(dev, "cannot request mbhc button press irq\n"); | 1210 | dev_err(dev, "cannot request mbhc button press irq\n"); |
| 1215 | 1211 | ||
| 1216 | irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); | 1212 | irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); |
| 1217 | if (irq < 0) { | 1213 | if (irq < 0) |
| 1218 | dev_err(dev, "failed to get button release irq\n"); | ||
| 1219 | return irq; | 1214 | return irq; |
| 1220 | } | ||
| 1221 | 1215 | ||
| 1222 | ret = devm_request_threaded_irq(dev, irq, NULL, | 1216 | ret = devm_request_threaded_irq(dev, irq, NULL, |
| 1223 | mbhc_btn_release_irq_handler, | 1217 | mbhc_btn_release_irq_handler, |
| @@ -1143,7 +1143,6 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev) · 1142 unmodified lines | |||
| 1143 | struct msm8916_wcd_digital_priv *priv; | 1143 | struct msm8916_wcd_digital_priv *priv; |
| 1144 | struct device *dev = &pdev->dev; | 1144 | struct device *dev = &pdev->dev; |
| 1145 | void __iomem *base; | 1145 | void __iomem *base; |
| 1146 | struct resource *mem_res; | ||
| 1147 | struct regmap *digital_map; | 1146 | struct regmap *digital_map; |
| 1148 | int ret; | 1147 | int ret; |
| 1149 | 1148 | ||
| @@ -1151,8 +1150,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1151 | if (!priv) | 1150 | if (!priv) |
| 1152 | return -ENOMEM; | 1151 | return -ENOMEM; |
| 1153 | 1152 | ||
| 1154 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1153 | base = devm_platform_ioremap_resource(pdev, 0); |
| 1155 | base = devm_ioremap_resource(&pdev->dev, mem_res); | ||
| 1156 | if (IS_ERR(base)) | 1154 | if (IS_ERR(base)) |
| 1157 | return PTR_ERR(base); | 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 | return 0; | 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 | /* DAPM Widgets */ | 1069 | /* DAPM Widgets */ |
| 1075 | static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = { | 1070 | static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = { |
| 1076 | /* Digital Clock */ | 1071 | /* Digital Clock */ |
| @@ -1730,6 +1730,10 @@ static int mt6358_dmic_enable(struct mt6358_priv *priv) · 1729 unmodified lines | |||
| 1730 | 1730 | ||
| 1731 | /* UL turn on */ | 1731 | /* UL turn on */ |
| 1732 | regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003); | 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 | return 0; | 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 | /* Disable HeadphoneL/HeadphoneR short circuit protection */ | 2264 | /* Disable HeadphoneL/HeadphoneR short circuit protection */ |
| 2263 | regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0, | 2265 | regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0, |
| 2264 | RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT, | 2266 | RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT, |
| @@ -2285,8 +2287,6 @@ static int mt6358_codec_init_reg(struct mt6358_priv *priv) · 20 unmodified lines | |||
| 2285 | /* set gpio */ | 2287 | /* set gpio */ |
| 2286 | playback_gpio_reset(priv); | 2288 | playback_gpio_reset(priv); |
| 2287 | capture_gpio_reset(priv); | 2289 | capture_gpio_reset(priv); |
| 2288 | |||
| 2289 | return ret; | ||
| 2290 | } | 2290 | } |
| 2291 | 2291 | ||
| 2292 | static int mt6358_codec_probe(struct snd_soc_component *cmpnt) | 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 | "VCCDA2" | 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 | struct pcm3168a_priv { | 59 | struct pcm3168a_priv { |
| 48 | struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES]; | 60 | struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES]; |
| 49 | struct regmap *regmap; | 61 | struct regmap *regmap; |
| 50 | struct clk *scki; | 62 | struct clk *scki; |
| 51 | bool adc_master_mode; | ||
| 52 | bool dac_master_mode; | ||
| 53 | unsigned long sysclk; | 63 | unsigned long sysclk; |
| 54 | unsigned int adc_fmt; | 64 | |
| 55 | unsigned int dac_fmt; | 65 | struct pcm3168a_io_params io_params[2]; |
| 56 | int tdm_slots; | ||
| 57 | u32 tdm_mask[2]; | ||
| 58 | int slot_width; | ||
| 59 | }; | 66 | }; |
| 60 | 67 | ||
| 61 | static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" }; | 68 | static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" }; |
| @@ -263,7 +270,7 @@ static unsigned int pcm3168a_scki_ratios[] = { · 201 unmodified lines | |||
| 263 | #define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios) | 270 | #define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios) |
| 264 | #define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2) | 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 | static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a) | 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 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); | 303 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); |
| 297 | int ret; | 304 | int ret; |
| 298 | 305 | ||
| 299 | if (freq > PCM1368A_MAX_SYSCLK) | 306 | if (freq > PCM3168A_MAX_SYSCLK) |
| 300 | return -EINVAL; | 307 | return -EINVAL; |
| 301 | 308 | ||
| 302 | ret = clk_set_rate(pcm3168a->scki, freq); | 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 | return 0; | 315 | return 0; |
| 309 | } | 316 | } |
| 310 | 317 | ||
| 311 | static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, | 318 | static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format) |
| 312 | unsigned int format, bool dac) | ||
| 313 | { | 319 | { |
| 314 | struct snd_soc_component *component = dai->component; | 320 | struct snd_soc_component *component = dai->component; |
| 315 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); | 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 | return -EINVAL; | 362 | return -EINVAL; |
| 357 | } | 363 | } |
| 358 | 364 | ||
| 359 | if (dac) { | 365 | if (dai->id == PCM3168A_DAI_DAC) { |
| 360 | reg = PCM3168A_DAC_PWR_MST_FMT; | 366 | reg = PCM3168A_DAC_PWR_MST_FMT; |
| 361 | mask = PCM3168A_DAC_FMT_MASK; | 367 | mask = PCM3168A_DAC_FMT_MASK; |
| 362 | shift = PCM3168A_DAC_FMT_SHIFT; | 368 | shift = PCM3168A_DAC_FMT_SHIFT; |
| 363 | pcm3168a->dac_master_mode = master_mode; | ||
| 364 | pcm3168a->dac_fmt = fmt; | ||
| 365 | } else { | 369 | } else { |
| 366 | reg = PCM3168A_ADC_MST_FMT; | 370 | reg = PCM3168A_ADC_MST_FMT; |
| 367 | mask = PCM3168A_ADC_FMTAD_MASK; | 371 | mask = PCM3168A_ADC_FMTAD_MASK; |
| 368 | shift = PCM3168A_ADC_FMTAD_SHIFT; | 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 | regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); | 378 | regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); |
| 374 | 379 | ||
| 375 | return 0; | 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 | static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | 383 | static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
| 391 | unsigned int rx_mask, int slots, | 384 | unsigned int rx_mask, int slots, |
| 392 | int slot_width) | 385 | int slot_width) |
| 393 | { | 386 | { |
| 394 | struct snd_soc_component *component = dai->component; | 387 | struct snd_soc_component *component = dai->component; |
| 395 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); | 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 | if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) { | 391 | if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) { |
| 398 | dev_err(component->dev, | 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 | return -EINVAL; | 402 | return -EINVAL; |
| 409 | } | 403 | } |
| 410 | 404 | ||
| 411 | if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) { | 405 | io_params->tdm_slots = slots; |
| 412 | dev_err(component->dev, "Not matching slots %d vs %d\n", | 406 | io_params->slot_width = slot_width; |
| 413 | pcm3168a->tdm_slots, slots); | 407 | /* Ignore the not relevant mask for the DAI/direction */ |
| 414 | return -EINVAL; | 408 | if (dai->id == PCM3168A_DAI_DAC) |
| 415 | } | 409 | io_params->tdm_mask = tx_mask; |
| 416 | 410 | else | |
| 417 | if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) { | 411 | io_params->tdm_mask = rx_mask; |
| 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; | ||
| 427 | 412 | ||
| 428 | return 0; | 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 | struct snd_soc_component *component = dai->component; | 420 | struct snd_soc_component *component = dai->component; |
| 436 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); | 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 | u32 val, mask, shift, reg; | 424 | u32 val, mask, shift, reg; |
| 439 | unsigned int rate, fmt, ratio, max_ratio; | 425 | unsigned int rate, fmt, ratio, max_ratio; |
| 440 | unsigned int tdm_slots; | 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 | ratio = pcm3168a->sysclk / rate; | 431 | ratio = pcm3168a->sysclk / rate; |
| 446 | 432 | ||
| 447 | tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 433 | if (dai->id == PCM3168A_DAI_DAC) { |
| 448 | if (tx) { | ||
| 449 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC; | 434 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC; |
| 450 | reg = PCM3168A_DAC_PWR_MST_FMT; | 435 | reg = PCM3168A_DAC_PWR_MST_FMT; |
| 451 | mask = PCM3168A_DAC_MSDA_MASK; | 436 | mask = PCM3168A_DAC_MSDA_MASK; |
| 452 | shift = PCM3168A_DAC_MSDA_SHIFT; | 437 | shift = PCM3168A_DAC_MSDA_SHIFT; |
| 453 | master_mode = pcm3168a->dac_master_mode; | ||
| 454 | fmt = pcm3168a->dac_fmt; | ||
| 455 | } else { | 438 | } else { |
| 456 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC; | 439 | max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC; |
| 457 | reg = PCM3168A_ADC_MST_FMT; | 440 | reg = PCM3168A_ADC_MST_FMT; |
| 458 | mask = PCM3168A_ADC_MSAD_MASK; | 441 | mask = PCM3168A_ADC_MSAD_MASK; |
| 459 | shift = PCM3168A_ADC_MSAD_SHIFT; | 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 | for (i = 0; i < max_ratio; i++) { | 448 | for (i = 0; i < max_ratio; i++) { |
| 465 | if (pcm3168a_scki_ratios[i] == ratio) | 449 | if (pcm3168a_scki_ratios[i] == ratio) |
| 466 | break; | 450 | break; |
| @@ -471,8 +455,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 4 unmodified lines | |||
| 471 | return -EINVAL; | 455 | return -EINVAL; |
| 472 | } | 456 | } |
| 473 | 457 | ||
| 474 | if (pcm3168a->slot_width) | 458 | if (io_params->slot_width) |
| 475 | slot_width = pcm3168a->slot_width; | 459 | slot_width = io_params->slot_width; |
| 476 | else | 460 | else |
| 477 | slot_width = params_width(params); | 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 | return -EINVAL; | 481 | return -EINVAL; |
| 498 | } | 482 | } |
| 499 | 483 | ||
| 500 | if (pcm3168a->tdm_slots) | 484 | if (io_params->tdm_slots) |
| 501 | tdm_slots = pcm3168a->tdm_slots; | 485 | tdm_slots = io_params->tdm_slots; |
| 502 | else | 486 | else |
| 503 | tdm_slots = params_channels(params); | 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 | regmap_update_bits(pcm3168a->regmap, reg, mask, val); | 519 | regmap_update_bits(pcm3168a->regmap, reg, mask, val); |
| 536 | 520 | ||
| 537 | if (tx) { | 521 | if (dai->id == PCM3168A_DAI_DAC) { |
| 538 | mask = PCM3168A_DAC_FMT_MASK; | 522 | mask = PCM3168A_DAC_FMT_MASK; |
| 539 | shift = PCM3168A_DAC_FMT_SHIFT; | 523 | shift = PCM3168A_DAC_FMT_SHIFT; |
| 540 | } else { | 524 | } else { |
| @@ -552,20 +536,13 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 11 unmodified lines | |||
| 552 | { | 536 | { |
| 553 | struct snd_soc_component *component = dai->component; | 537 | struct snd_soc_component *component = dai->component; |
| 554 | struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component); | 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 | unsigned int sample_min; | 539 | unsigned int sample_min; |
| 558 | unsigned int channel_max; | 540 | unsigned int channel_max; |
| 559 | unsigned int channel_maxs[] = { | 541 | unsigned int channel_maxs[] = { |
| 560 | 6, /* rx */ | 542 | 8, /* DAC */ |
| 561 | 8 /* tx */ | 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 | * Available Data Bits | 547 | * Available Data Bits |
| 571 | * | 548 | * |
| @@ -578,7 +555,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 6 unmodified lines | |||
| 578 | * I2S | 555 | * I2S |
| 579 | * LEFT_J | 556 | * LEFT_J |
| 580 | */ | 557 | */ |
| 581 | switch (fmt) { | 558 | switch (pcm3168a->io_params[dai->id].fmt) { |
| 582 | case PCM3168A_FMT_RIGHT_J: | 559 | case PCM3168A_FMT_RIGHT_J: |
| 583 | sample_min = 16; | 560 | sample_min = 16; |
| 584 | channel_max = 2; | 561 | channel_max = 2; |
| @@ -588,7 +565,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 3 unmodified lines | |||
| 588 | case PCM3168A_FMT_DSP_A: | 565 | case PCM3168A_FMT_DSP_A: |
| 589 | case PCM3168A_FMT_DSP_B: | 566 | case PCM3168A_FMT_DSP_B: |
| 590 | sample_min = 24; | 567 | sample_min = 24; |
| 591 | channel_max = channel_maxs[tx]; | 568 | channel_max = channel_maxs[dai->id]; |
| 592 | break; | 569 | break; |
| 593 | default: | 570 | default: |
| 594 | sample_min = 24; | 571 | sample_min = 24; |
| @@ -599,32 +576,29 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream, · 4 unmodified lines | |||
| 599 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | 576 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, |
| 600 | sample_min, 32); | 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 | snd_pcm_hw_constraint_minmax(substream->runtime, | 583 | snd_pcm_hw_constraint_minmax(substream->runtime, |
| 603 | SNDRV_PCM_HW_PARAM_CHANNELS, | 584 | SNDRV_PCM_HW_PARAM_CHANNELS, |
| 604 | 2, channel_max); | 585 | 2, channel_max); |
| 605 | 586 | ||
| 606 | return 0; | 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 | .startup = pcm3168a_startup, | 590 | .startup = pcm3168a_startup, |
| 610 | .set_fmt = pcm3168a_set_dai_fmt_dac, | 591 | .set_fmt = pcm3168a_set_dai_fmt, |
| 611 | .set_sysclk = pcm3168a_set_dai_sysclk, | 592 | .set_sysclk = pcm3168a_set_dai_sysclk, |
| 612 | .hw_params = pcm3168a_hw_params, | 593 | .hw_params = pcm3168a_hw_params, |
| 613 | .digital_mute = pcm3168a_digital_mute, | 594 | .digital_mute = pcm3168a_digital_mute, |
| 614 | .set_tdm_slot = pcm3168a_set_tdm_slot, | 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 | static struct snd_soc_dai_driver pcm3168a_dais[] = { | 598 | static struct snd_soc_dai_driver pcm3168a_dais[] = { |
| 626 | { | 599 | { |
| 627 | .name = "pcm3168a-dac", | 600 | .name = "pcm3168a-dac", |
| 601 | .id = PCM3168A_DAI_DAC, | ||
| 628 | .playback = { | 602 | .playback = { |
| 629 | .stream_name = "Playback", | 603 | .stream_name = "Playback", |
| 630 | .channels_min = 1, | 604 | .channels_min = 1, |
| @@ -632,10 +606,11 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = { · 1 unmodified line | |||
| 632 | .rates = SNDRV_PCM_RATE_8000_192000, | 606 | .rates = SNDRV_PCM_RATE_8000_192000, |
| 633 | .formats = PCM3168A_FORMATS | 607 | .formats = PCM3168A_FORMATS |
| 634 | }, | 608 | }, |
| 635 | .ops = &pcm3168a_dac_dai_ops | 609 | .ops = &pcm3168a_dai_ops |
| 636 | }, | 610 | }, |
| 637 | { | 611 | { |
| 638 | .name = "pcm3168a-adc", | 612 | .name = "pcm3168a-adc", |
| 613 | .id = PCM3168A_DAI_ADC, | ||
| 639 | .capture = { | 614 | .capture = { |
| 640 | .stream_name = "Capture", | 615 | .stream_name = "Capture", |
| 641 | .channels_min = 1, | 616 | .channels_min = 1, |
| @@ -643,7 +618,7 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = { · 1 unmodified line | |||
| 643 | .rates = SNDRV_PCM_RATE_8000_96000, | 618 | .rates = SNDRV_PCM_RATE_8000_96000, |
| 644 | .formats = PCM3168A_FORMATS | 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 | struct device_node *rk3328_np = pdev->dev.of_node; | 433 | struct device_node *rk3328_np = pdev->dev.of_node; |
| 434 | struct rk3328_codec_priv *rk3328; | 434 | struct rk3328_codec_priv *rk3328; |
| 435 | struct resource *res; | ||
| 436 | struct regmap *grf; | 435 | struct regmap *grf; |
| 437 | void __iomem *base; | 436 | void __iomem *base; |
| 438 | int ret = 0; | 437 | int ret = 0; |
| @@ -482,8 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev) · 43 unmodified lines | |||
| 482 | return ret; | 481 | return ret; |
| 483 | } | 482 | } |
| 484 | 483 | ||
| 485 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 484 | base = devm_platform_ioremap_resource(pdev, 0); |
| 486 | base = devm_ioremap_resource(&pdev->dev, res); | ||
| 487 | if (IS_ERR(base)) | 485 | if (IS_ERR(base)) |
| 488 | return PTR_ERR(base); | 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 | static const char * const rt1011_din_source_select[] = { | 981 | static const char * const rt1011_din_source_select[] = { |
| 985 | "Left", | 982 | "Left", |
| 986 | "Right", | 983 | "Right", |
| @@ -1029,6 +1026,8 @@ static const char * const rt1011_tdm_adc_swap_select[] = { · 42 unmodified lines | |||
| 1029 | 1026 | ||
| 1030 | static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6, | 1027 | static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6, |
| 1031 | rt1011_tdm_adc_swap_select); | 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 | static void rt1011_reset(struct regmap *regmap) | 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 | static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol, | 1222 | static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol, |
| 1224 | struct snd_ctl_elem_value *ucontrol) | 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 | return 0; | 1230 | return 0; |
| 1229 | } | 1231 | } |
| @@ -1237,6 +1239,7 @@ static int rt1011_r0_cali_put(struct snd_kcontrol *kcontrol, · 7 unmodified lines | |||
| 1237 | if (!component->card->instantiated) | 1239 | if (!component->card->instantiated) |
| 1238 | return 0; | 1240 | return 0; |
| 1239 | 1241 | ||
| 1242 | rt1011->cali_done = 0; | ||
| 1240 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF && | 1243 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF && |
| 1241 | ucontrol->value.integer.value[0]) | 1244 | ucontrol->value.integer.value[0]) |
| 1242 | rt1011_calibrate(rt1011, 1); | 1245 | rt1011_calibrate(rt1011, 1); |
| @@ -1333,7 +1336,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = { · 90 unmodified lines | |||
| 1333 | /* TDM1 Data Out Selection */ | 1336 | /* TDM1 Data Out Selection */ |
| 1334 | SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum), | 1337 | SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum), |
| 1335 | SOC_ENUM("TDM1 DOUT Location", rt1011_tdm1_adc1_loc_enum), | 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 | /* Data Out Mode */ | 1342 | /* Data Out Mode */ |
| 1339 | SOC_ENUM("I2S ADC DOUT Mode", rt1011_adc_dout_mode_enum), | 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 | SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0, | 1359 | SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0, |
| 1356 | rt1011_r0_cali_get, rt1011_r0_cali_put), | 1360 | rt1011_r0_cali_get, rt1011_r0_cali_put), |
| 1357 | RT1011_R0_LOAD("R0 Load Mode"), | 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 | static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 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 | static int rt1011_get_clk_info(int sclk, int rate) | 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 | if (sclk <= 0 || rate <= 0) | 1525 | if (sclk <= 0 || rate <= 0) |
| 1517 | return -EINVAL; | 1526 | return -EINVAL; |
| @@ -2139,6 +2148,7 @@ static int rt1011_calibrate(struct rt1011_priv *rt1011, unsigned char cali_flag) · 621 unmodified lines | |||
| 2139 | r0_factor = ((format / r0[0] * 100) / 128) | 2148 | r0_factor = ((format / r0[0] * 100) / 128) |
| 2140 | - (r0_integer * 100); | 2149 | - (r0_integer * 100); |
| 2141 | rt1011->r0_reg = r0[0]; | 2150 | rt1011->r0_reg = r0[0]; |
| 2151 | rt1011->cali_done = 1; | ||
| 2142 | dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n", | 2152 | dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n", |
| 2143 | r0_integer, r0_factor, r0[0]); | 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 | rt1011_calibrate(rt1011, 1); | 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 | /* initial */ | 2209 | /* initial */ |
| 2193 | rt1011_reg_init(component); | 2210 | rt1011_reg_init(component); |
| 2194 | } | 2211 | } |
| @@ -227,6 +227,7 @@ · 226 unmodified lines | |||
| 227 | #define RT1011_STP_CALIB_RS_TEMP 0x152a | 227 | #define RT1011_STP_CALIB_RS_TEMP 0x152a |
| 228 | #define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538 | 228 | #define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538 |
| 229 | #define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539 | 229 | #define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539 |
| 230 | #define RT1011_STP_INITIAL_RESISTANCE_TEMP 0x153c | ||
| 230 | #define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e | 231 | #define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e |
| 231 | #define RT1011_SPK_RESISTANCE_1 0x1544 | 232 | #define RT1011_SPK_RESISTANCE_1 0x1544 |
| 232 | #define RT1011_SPK_RESISTANCE_2 0x1546 | 233 | #define RT1011_SPK_RESISTANCE_2 0x1546 |
| @@ -665,7 +666,7 @@ struct rt1011_priv { · 432 unmodified lines | |||
| 665 | int pll_out; | 666 | int pll_out; |
| 666 | 667 | ||
| 667 | int bq_drc_set; | 668 | int bq_drc_set; |
| 668 | unsigned int r0_reg; | 669 | unsigned int r0_reg, cali_done; |
| 669 | int recv_spk_mode; | 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 | static int rt1305_get_clk_info(int sclk, int rate) | 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 | if (sclk <= 0 || rate <= 0) | 614 | if (sclk <= 0 || rate <= 0) |
| 614 | return -EINVAL; | 615 | return -EINVAL; |
| @@ -1,13 +1,10 @@ | |||
| 1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | * rt1308.c -- RT1308 ALSA SoC amplifier component driver | 2 | // |
| 3 | * | 3 | // rt1308.c -- RT1308 ALSA SoC amplifier component driver |
| 4 | * Copyright 2019 Realtek Semiconductor Corp. | 4 | // |
| 5 | * Author: Derek Fang <derek.fang@realtek.com> | 5 | // Copyright 2019 Realtek Semiconductor Corp. |
| 6 | * | 6 | // Author: Derek Fang <derek.fang@realtek.com> |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | // |
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | 8 | ||
| 12 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 13 | #include <linux/moduleparam.h> | 10 | #include <linux/moduleparam.h> |
| @@ -40,10 +37,10 @@ static const struct reg_sequence init_list[] = { · 26 unmodified lines | |||
| 40 | { RT1308_VREF, 0x18100000 }, | 37 | { RT1308_VREF, 0x18100000 }, |
| 41 | { RT1308_IV_SENSE, 0x87010000 }, | 38 | { RT1308_IV_SENSE, 0x87010000 }, |
| 42 | { RT1308_DUMMY_REG, 0x00000200 }, | 39 | { RT1308_DUMMY_REG, 0x00000200 }, |
| 43 | { RT1308_SIL_DET, 0x61c30000 }, | 40 | { RT1308_SIL_DET, 0xe1c30000 }, |
| 44 | { RT1308_DC_CAL_2, 0x00ffff00 }, | 41 | { RT1308_DC_CAL_2, 0x00ffff00 }, |
| 45 | { RT1308_CLK_DET, 0x01000000 }, | 42 | { RT1308_CLK_DET, 0x01000000 }, |
| 46 | { RT1308_POWER_STATUS, 0x00800000 }, | 43 | { RT1308_POWER_STATUS, 0x08800000 }, |
| 47 | { RT1308_DAC_SET, 0xafaf0700 }, | 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 | case SND_SOC_DAPM_POST_PMU: | 305 | case SND_SOC_DAPM_POST_PMU: |
| 309 | msleep(30); | 306 | msleep(30); |
| 310 | snd_soc_component_update_bits(component, RT1308_POWER_STATUS, | 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 | msleep(40); | 310 | msleep(40); |
| 313 | break; | 311 | break; |
| 314 | case SND_SOC_DAPM_PRE_PMD: | 312 | case SND_SOC_DAPM_PRE_PMD: |
| 315 | snd_soc_component_update_bits(component, RT1308_POWER_STATUS, | 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 | usleep_range(150000, 200000); | 315 | usleep_range(150000, 200000); |
| 318 | break; | 316 | break; |
| 319 | 317 | ||
| @@ -438,7 +436,8 @@ static const struct snd_soc_dapm_route rt1308_dapm_routes[] = { · 118 unmodified lines | |||
| 438 | 436 | ||
| 439 | static int rt1308_get_clk_info(int sclk, int rate) | 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 | if (sclk <= 0 || rate <= 0) | 442 | if (sclk <= 0 || rate <= 0) |
| 444 | return -EINVAL; | 443 | return -EINVAL; |
| @@ -808,33 +807,11 @@ static void rt1308_efuse(struct rt1308_priv *rt1308) · 363 unmodified lines | |||
| 808 | { | 807 | { |
| 809 | regmap_write(rt1308->regmap, RT1308_RESET, 0); | 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 | regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000); | 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 | msleep(100); | 811 | msleep(100); |
| 829 | regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00); | 812 | regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00); |
| 830 | msleep(20); | 813 | msleep(20); |
| 831 | regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000); | 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 | static int rt1308_i2c_probe(struct i2c_client *i2c, | 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 | * Copyright 2019 Realtek Semiconductor Corp. | 5 | * Copyright 2019 Realtek Semiconductor Corp. |
| 5 | * Author: Derek Fang <derek.fang@realtek.com> | 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 | #ifndef _RT1308_H_ | 10 | #ifndef _RT1308_H_ |
| @@ -2566,7 +2566,7 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w, · 2565 unmodified lines | |||
| 2566 | return 0; | 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 | struct snd_kcontrol *kcontrol, int event) | 2570 | struct snd_kcontrol *kcontrol, int event) |
| 2571 | { | 2571 | { |
| 2572 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | 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 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL, | 2686 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL, |
| 2687 | RT5665_PWR_MIC_DET_BIT, 0, NULL, 0), | 2687 | RT5665_PWR_MIC_DET_BIT, 0, NULL, 0), |
| 2688 | SND_SOC_DAPM_SUPPLY("Vref1", RT5665_PWR_ANLG_1, RT5665_PWR_VREF1_BIT, 0, | 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 | SND_SOC_DAPM_SUPPLY("Vref2", RT5665_PWR_ANLG_1, RT5665_PWR_VREF2_BIT, 0, | 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 | SND_SOC_DAPM_SUPPLY("Vref3", RT5665_PWR_ANLG_1, RT5665_PWR_VREF3_BIT, 0, | 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 | /* ASRC */ | 2695 | /* ASRC */ |
| 2696 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5665_ASRC_1, | 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 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); | 691 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
| 692 | 692 | ||
| 693 | if (on) { | 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 | rt5677->is_dsp_mode = true; | 696 | rt5677->is_dsp_mode = true; |
| 696 | } else { | 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 | rt5677->is_dsp_mode = false; | 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 | regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, | 4469 | regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, |
| 4468 | RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, | 4470 | RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, |
| 4469 | 0x0055); | 4471 | 5 << RT5677_LDO1_SEL_SFT | |
| 4472 | 5 << RT5677_LDO2_SEL_SFT); | ||
| 4470 | regmap_update_bits(rt5677->regmap, | 4473 | regmap_update_bits(rt5677->regmap, |
| 4471 | RT5677_PR_BASE + RT5677_BIAS_CUR4, | 4474 | RT5677_PR_BASE + RT5677_BIAS_CUR4, |
| 4472 | 0x0f00, 0x0f00); | 4475 | 0x0f00, 0x0f00); |
| @@ -4490,9 +4493,11 @@ static int rt5677_set_bias_level(struct snd_soc_component *component, · 17 unmodified lines | |||
| 4490 | case SND_SOC_BIAS_OFF: | 4493 | case SND_SOC_BIAS_OFF: |
| 4491 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); | 4494 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); |
| 4492 | regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); | 4495 | regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); |
| 4493 | regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000); | 4496 | regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, |
| 4494 | regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022); | 4497 | 2 << RT5677_LDO1_SEL_SFT | |
| 4495 | regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); | 4498 | 2 << RT5677_LDO2_SEL_SFT); |
| 4499 | regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, | ||
| 4500 | RT5677_PWR_CORE, 0); | ||
| 4496 | regmap_update_bits(rt5677->regmap, | 4501 | regmap_update_bits(rt5677->regmap, |
| 4497 | RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); | 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 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, | 4725 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, |
| 4721 | ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020); | 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 | for (i = 0; i < RT5677_GPIO_NUM; i++) | 4730 | for (i = 0; i < RT5677_GPIO_NUM; i++) |
| 4725 | rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); | 4731 | rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); |
| @@ -31,6 +31,13 @@ · 30 unmodified lines | |||
| 31 | #define SGTL5000_DAP_REG_OFFSET 0x0100 | 31 | #define SGTL5000_DAP_REG_OFFSET 0x0100 |
| 32 | #define SGTL5000_MAX_REG_OFFSET 0x013A | 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 | /* default value of sgtl5000 registers */ | 41 | /* default value of sgtl5000 registers */ |
| 35 | static const struct reg_default sgtl5000_reg_defaults[] = { | 42 | static const struct reg_default sgtl5000_reg_defaults[] = { |
| 36 | { SGTL5000_CHIP_DIG_POWER, 0x0000 }, | 43 | { SGTL5000_CHIP_DIG_POWER, 0x0000 }, |
| @@ -123,6 +130,13 @@ enum { · 86 unmodified lines | |||
| 123 | I2S_SCLK_STRENGTH_HIGH, | 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 | /* sgtl5000 private structure in codec */ | 140 | /* sgtl5000 private structure in codec */ |
| 127 | struct sgtl5000_priv { | 141 | struct sgtl5000_priv { |
| 128 | int sysclk; /* sysclk rate */ | 142 | int sysclk; /* sysclk rate */ |
| @@ -137,8 +151,109 @@ struct sgtl5000_priv { · 8 unmodified lines | |||
| 137 | u8 micbias_voltage; | 151 | u8 micbias_voltage; |
| 138 | u8 lrclk_strength; | 152 | u8 lrclk_strength; |
| 139 | u8 sclk_strength; | 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 | * mic_bias power on/off share the same register bits with | 258 | * mic_bias power on/off share the same register bits with |
| 144 | * output impedance of mic bias, when power on mic bias, we | 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 | return 0; | 285 | return 0; |
| 171 | } | 286 | } |
| 172 | 287 | ||
| 173 | /* | 288 | static int vag_and_mute_control(struct snd_soc_component *component, |
| 174 | * As manual described, ADC/DAC only works when VAG powerup, | 289 | int event, int event_source) |
| 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) | ||
| 180 | { | 290 | { |
| 181 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | 291 | static const u16 mute_mask[] = { |
| 182 | const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP; | 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 | switch (event) { | 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 | case SND_SOC_DAPM_POST_PMU: | 315 | case SND_SOC_DAPM_POST_PMU: |
| 186 | snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | 316 | vag_power_on(component, event_source); |
| 187 | SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); | 317 | restore_output(component, mute_mask[event_source], |
| 188 | msleep(400); | 318 | sgtl5000->mute_state[event_source]); |
| 189 | break; | 319 | break; |
| 190 | |||
| 191 | case SND_SOC_DAPM_PRE_PMD: | 320 | case SND_SOC_DAPM_PRE_PMD: |
| 192 | /* | 321 | sgtl5000->mute_state[event_source] = |
| 193 | * Don't clear VAG_POWERUP, when both DAC and ADC are | 322 | mute_output(component, mute_mask[event_source]); |
| 194 | * operational to prevent inadvertently starving the | 323 | vag_power_off(component, event_source); |
| 195 | * other one of them. | 324 | break; |
| 196 | */ | 325 | case SND_SOC_DAPM_POST_PMD: |
| 197 | if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) & | 326 | restore_output(component, mute_mask[event_source], |
| 198 | mask) != mask) { | 327 | sgtl5000->mute_state[event_source]); |
| 199 | snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, | ||
| 200 | SGTL5000_VAG_POWERUP, 0); | ||
| 201 | msleep(400); | ||
| 202 | } | ||
| 203 | break; | 328 | break; |
| 204 | default: | 329 | default: |
| 205 | break; | 330 | break; |
| @@ -208,6 +333,41 @@ static int power_vag_event(struct snd_soc_dapm_widget *w, · 2 unmodified lines | |||
| 208 | return 0; | 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 | /* input sources for ADC */ | 371 | /* input sources for ADC */ |
| 212 | static const char *adc_mux_text[] = { | 372 | static const char *adc_mux_text[] = { |
| 213 | "MIC_IN", "LINE_IN" | 373 | "MIC_IN", "LINE_IN" |
| @@ -280,7 +440,10 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { · 66 unmodified lines | |||
| 280 | mic_bias_event, | 440 | mic_bias_event, |
| 281 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 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 | SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), | 447 | SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), |
| 285 | 448 | ||
| 286 | SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux), | 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 | 0, SGTL5000_CHIP_DIG_POWER, | 464 | 0, SGTL5000_CHIP_DIG_POWER, |
| 302 | 1, 0), | 465 | 1, 0), |
| 303 | 466 | ||
| 304 | SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), | 467 | SND_SOC_DAPM_ADC_E("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0, |
| 305 | SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), | 468 | adc_updown_depop, SND_SOC_DAPM_PRE_POST_PMU | |
| 306 | 469 | SND_SOC_DAPM_PRE_POST_PMD), | |
| 307 | SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event), | 470 | SND_SOC_DAPM_DAC_E("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0, |
| 308 | SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event), | 471 | dac_updown_depop, SND_SOC_DAPM_PRE_POST_PMU | |
| 472 | SND_SOC_DAPM_PRE_POST_PMD), | ||
| 309 | }; | 473 | }; |
| 310 | 474 | ||
| 311 | /* routes for sgtl5000 */ | 475 | /* routes for sgtl5000 */ |
| @@ -556,6 +720,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { · 244 unmodified lines | |||
| 556 | SGTL5000_CHIP_ANA_ADC_CTRL, | 720 | SGTL5000_CHIP_ANA_ADC_CTRL, |
| 557 | 8, 1, 0, capture_6db_attenuate), | 721 | 8, 1, 0, capture_6db_attenuate), |
| 558 | SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0), | 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 | SOC_DOUBLE_TLV("Headphone Playback Volume", | 725 | SOC_DOUBLE_TLV("Headphone Playback Volume", |
| 561 | SGTL5000_CHIP_ANA_HP_CTRL, | 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 | SGTL5000_INT_OSC_EN); | 1338 | SGTL5000_INT_OSC_EN); |
| 1174 | /* Enable VDDC charge pump */ | 1339 | /* Enable VDDC charge pump */ |
| 1175 | ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; | 1340 | ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; |
| 1176 | } else if (vddio >= 3100 && vdda >= 3100) { | 1341 | } else { |
| 1177 | ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; | 1342 | ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP; |
| 1178 | /* VDDC use VDDIO rail */ | 1343 | /* |
| 1179 | lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; | 1344 | * if vddio == vdda the source of charge pump should be |
| 1180 | lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << | 1345 | * assigned manually to VDDIO |
| 1181 | SGTL5000_VDDC_MAN_ASSN_SHIFT; | 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 | snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl); | 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 | int ret; | 1458 | int ret; |
| 1289 | u16 reg; | 1459 | u16 reg; |
| 1290 | struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component); | 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 | /* power up sgtl5000 */ | 1463 | /* power up sgtl5000 */ |
| 1293 | ret = sgtl5000_set_power_regs(component); | 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 | /* enable small pop, introduce 400ms delay in turning off */ | 1468 | /* enable small pop, introduce 400ms delay in turning off */ |
| 1298 | snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL, | 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 | /* disable short cut detector */ | 1472 | /* disable short cut detector */ |
| 1302 | snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0); | 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 | 0x1f); | 1486 | 0x1f); |
| 1316 | snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg); | 1487 | snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg); |
| 1317 | 1488 | ||
| 1318 | snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL, | 1489 | snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, |
| 1319 | SGTL5000_HP_ZCD_EN | | 1490 | zcd_mask, zcd_mask); |
| 1320 | SGTL5000_ADC_ZCD_EN); | ||
| 1321 | 1491 | ||
| 1322 | snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL, | 1492 | snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL, |
| 1323 | SGTL5000_BIAS_R_MASK, | 1493 | SGTL5000_BIAS_R_MASK, |
| @@ -273,7 +273,7 @@ · 272 unmodified lines | |||
| 273 | #define SGTL5000_BIAS_CTRL_MASK 0x000e | 273 | #define SGTL5000_BIAS_CTRL_MASK 0x000e |
| 274 | #define SGTL5000_BIAS_CTRL_SHIFT 1 | 274 | #define SGTL5000_BIAS_CTRL_SHIFT 1 |
| 275 | #define SGTL5000_BIAS_CTRL_WIDTH 3 | 275 | #define SGTL5000_BIAS_CTRL_WIDTH 3 |
| 276 | #define SGTL5000_SMALL_POP 1 | 276 | #define SGTL5000_SMALL_POP 0x0001 |
| 277 | 277 | ||
| 278 | /* | 278 | /* |
| 279 | * SGTL5000_CHIP_MIC_CTRL | 279 | * SGTL5000_CHIP_MIC_CTRL |
| @@ -459,7 +459,6 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev) · 458 unmodified lines | |||
| 459 | int ret; | 459 | int ret; |
| 460 | struct sirf_audio_codec *sirf_audio_codec; | 460 | struct sirf_audio_codec *sirf_audio_codec; |
| 461 | void __iomem *base; | 461 | void __iomem *base; |
| 462 | struct resource *mem_res; | ||
| 463 | 462 | ||
| 464 | sirf_audio_codec = devm_kzalloc(&pdev->dev, | 463 | sirf_audio_codec = devm_kzalloc(&pdev->dev, |
| 465 | sizeof(struct sirf_audio_codec), GFP_KERNEL); | 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 | platform_set_drvdata(pdev, sirf_audio_codec); | 468 | platform_set_drvdata(pdev, sirf_audio_codec); |
| 470 | 469 | ||
| 471 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 470 | base = devm_platform_ioremap_resource(pdev, 0); |
| 472 | base = devm_ioremap_resource(&pdev->dev, mem_res); | ||
| 473 | if (IS_ERR(base)) | 471 | if (IS_ERR(base)) |
| 474 | return PTR_ERR(base); | 472 | return PTR_ERR(base); |
| 475 | 473 | ||
| @@ -67,8 +67,6 @@ static SOC_ENUM_SINGLE_DECL(rec_src_enum, · 66 unmodified lines | |||
| 67 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = | 67 | static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = |
| 68 | SOC_DAPM_ENUM("Input Select", rec_src_enum); | 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 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, | 70 | static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph, |
| 73 | TLV320AIC23_DIGT, 1, deemph_text); | 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 | static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, | 258 | static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, |
| 259 | mic_select_text); | 259 | mic_select_text); |
| 260 | 260 | ||
| 261 | static SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text); | ||
| 262 | static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, | 261 | static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, |
| 263 | mic_select_text); | 262 | mic_select_text); |
| 264 | 263 | ||
| @@ -1553,7 +1552,8 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, · 1288 unmodified lines | |||
| 1553 | aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset", | 1552 | aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset", |
| 1554 | GPIOD_OUT_LOW); | 1553 | GPIOD_OUT_LOW); |
| 1555 | if (IS_ERR(aic31xx->gpio_reset)) { | 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 | return PTR_ERR(aic31xx->gpio_reset); | 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 | ARRAY_SIZE(aic31xx->supplies), | 1564 | ARRAY_SIZE(aic31xx->supplies), |
| 1565 | aic31xx->supplies); | 1565 | aic31xx->supplies); |
| 1566 | if (ret) { | 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 | return ret; | 1570 | return ret; |
| 1569 | } | 1571 | } |
| 1570 | 1572 | ||
| @@ -22,7 +22,6 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | #include "tscs454.h" | 23 | #include "tscs454.h" |
| 24 | 24 | ||
| 25 | static const unsigned int PLL_48K_RATE = (48000 * 256); | ||
| 26 | static const unsigned int PLL_44_1K_RATE = (44100 * 256); | 25 | static const unsigned int PLL_44_1K_RATE = (44100 * 256); |
| 27 | 26 | ||
| 28 | #define COEFF_SIZE 3 | 27 | #define COEFF_SIZE 3 |
| @@ -1108,10 +1108,8 @@ static int twl6040_probe(struct snd_soc_component *component) · 1107 unmodified lines | |||
| 1108 | priv->component = component; | 1108 | priv->component = component; |
| 1109 | 1109 | ||
| 1110 | priv->plug_irq = platform_get_irq(pdev, 0); | 1110 | priv->plug_irq = platform_get_irq(pdev, 0); |
| 1111 | if (priv->plug_irq < 0) { | 1111 | if (priv->plug_irq < 0) |
| 1112 | dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq); | ||
| 1113 | return priv->plug_irq; | 1112 | return priv->plug_irq; |
| 1114 | } | ||
| 1115 | 1113 | ||
| 1116 | INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); | 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 | #define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0 | 65 | #define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0 |
| 66 | #define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7) | 66 | #define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7) |
| 67 | #define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK GENMASK(7, 4) | 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 | #define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3) | 69 | #define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3) |
| 70 | #define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3) | 70 | #define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3) |
| 71 | #define WCD9XXX_HPH_CONST_SEL_BYPASS 0 | 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 | .id = AIF1_PB, | 2071 | .id = AIF1_PB, |
| 2072 | .playback = { | 2072 | .playback = { |
| 2073 | .stream_name = "AIF1 Playback", | 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 | .formats = WCD9335_FORMATS_S16_S24_LE, | 2076 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2076 | .rate_max = 192000, | 2077 | .rate_max = 384000, |
| 2077 | .rate_min = 8000, | 2078 | .rate_min = 8000, |
| 2078 | .channels_min = 1, | 2079 | .channels_min = 1, |
| 2079 | .channels_max = 2, | 2080 | .channels_max = 2, |
| @@ -2099,10 +2100,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 19 unmodified lines | |||
| 2099 | .id = AIF2_PB, | 2100 | .id = AIF2_PB, |
| 2100 | .playback = { | 2101 | .playback = { |
| 2101 | .stream_name = "AIF2 Playback", | 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 | .formats = WCD9335_FORMATS_S16_S24_LE, | 2105 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2104 | .rate_min = 8000, | 2106 | .rate_min = 8000, |
| 2105 | .rate_max = 192000, | 2107 | .rate_max = 384000, |
| 2106 | .channels_min = 1, | 2108 | .channels_min = 1, |
| 2107 | .channels_max = 2, | 2109 | .channels_max = 2, |
| 2108 | }, | 2110 | }, |
| @@ -2127,10 +2129,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 18 unmodified lines | |||
| 2127 | .id = AIF3_PB, | 2129 | .id = AIF3_PB, |
| 2128 | .playback = { | 2130 | .playback = { |
| 2129 | .stream_name = "AIF3 Playback", | 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 | .formats = WCD9335_FORMATS_S16_S24_LE, | 2134 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2132 | .rate_min = 8000, | 2135 | .rate_min = 8000, |
| 2133 | .rate_max = 192000, | 2136 | .rate_max = 384000, |
| 2134 | .channels_min = 1, | 2137 | .channels_min = 1, |
| 2135 | .channels_max = 2, | 2138 | .channels_max = 2, |
| 2136 | }, | 2139 | }, |
| @@ -2155,10 +2158,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = { · 18 unmodified lines | |||
| 2155 | .id = AIF4_PB, | 2158 | .id = AIF4_PB, |
| 2156 | .playback = { | 2159 | .playback = { |
| 2157 | .stream_name = "AIF4 Playback", | 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 | .formats = WCD9335_FORMATS_S16_S24_LE, | 2163 | .formats = WCD9335_FORMATS_S16_S24_LE, |
| 2160 | .rate_min = 8000, | 2164 | .rate_min = 8000, |
| 2161 | .rate_max = 192000, | 2165 | .rate_max = 384000, |
| 2162 | .channels_min = 1, | 2166 | .channels_min = 1, |
| 2163 | .channels_max = 2, | 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 | ret = devm_request_threaded_irq(wcd->dev, irq, NULL, | 4067 | ret = devm_request_threaded_irq(wcd->dev, irq, NULL, |
| 4064 | wcd9335_irqs[i].handler, | 4068 | wcd9335_irqs[i].handler, |
| 4065 | IRQF_TRIGGER_RISING, | 4069 | IRQF_TRIGGER_RISING | |
| 4070 | IRQF_ONESHOT, | ||
| 4066 | wcd9335_irqs[i].name, wcd); | 4071 | wcd9335_irqs[i].name, wcd); |
| 4067 | if (ret) { | 4072 | if (ret) { |
| 4068 | dev_err(wcd->dev, "Failed to request %s\n", | 4073 | dev_err(wcd->dev, "Failed to request %s\n", |
| @@ -140,7 +140,7 @@ struct pll_factors { · 139 unmodified lines | |||
| 140 | * to allow rounding later */ | 140 | * to allow rounding later */ |
| 141 | #define FIXED_FLL_SIZE ((1 << 22) * 10) | 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 | int Fref, int Fout, struct pll_factors *pll) | 144 | int Fref, int Fout, struct pll_factors *pll) |
| 145 | { | 145 | { |
| 146 | u64 Kpart; | 146 | u64 Kpart; |
| @@ -279,7 +279,7 @@ static int wm8955_configure_clocking(struct snd_soc_component *component) · 132 unmodified lines | |||
| 279 | 279 | ||
| 280 | /* Use the last divider configuration we saw for the | 280 | /* Use the last divider configuration we saw for the |
| 281 | * sample rate. */ | 281 | * sample rate. */ |
| 282 | ret = wm8995_pll_factors(component->dev, wm8955->mclk_rate, | 282 | ret = wm8955_pll_factors(component->dev, wm8955->mclk_rate, |
| 283 | clock_cfgs[sr].mclk, &pll); | 283 | clock_cfgs[sr].mclk, &pll); |
| 284 | if (ret != 0) { | 284 | if (ret != 0) { |
| 285 | dev_err(component->dev, | 285 | dev_err(component->dev, |
| @@ -273,7 +273,7 @@ static const struct soc_enum wm8988_rline_enum = · 272 unmodified lines | |||
| 273 | wm8988_line_texts, | 273 | wm8988_line_texts, |
| 274 | wm8988_line_values); | 274 | wm8988_line_values); |
| 275 | static const struct snd_kcontrol_new wm8988_right_line_controls = | 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 | /* Left Mixer */ | 278 | /* Left Mixer */ |
| 279 | static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { | 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 | unsigned int val; | 4248 | unsigned int val; |
| 4248 | struct regmap *regmap = dsp->regmap; | 4249 | struct regmap *regmap = dsp->regmap; |
| 4249 | int ret = 0; | 4250 | int ret = 0; |
| @@ -4307,8 +4308,9 @@ error: · 57 unmodified lines | |||
| 4307 | } | 4308 | } |
| 4308 | EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); | 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 | struct regmap *regmap = dsp->regmap; | 4314 | struct regmap *regmap = dsp->regmap; |
| 4313 | unsigned int fault[6]; | 4315 | unsigned int fault[6]; |
| 4314 | struct reg_sequence clear[] = { | 4316 | struct reg_sequence clear[] = { |
| @@ -171,8 +171,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, · 170 unmodified lines | |||
| 171 | int wm_adsp_early_event(struct snd_soc_dapm_widget *w, | 171 | int wm_adsp_early_event(struct snd_soc_dapm_widget *w, |
| 172 | struct snd_kcontrol *kcontrol, int event); | 172 | struct snd_kcontrol *kcontrol, int event); |
| 173 | 173 | ||
| 174 | irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp); | 174 | irqreturn_t wm_adsp2_bus_error(int irq, void *data); |
| 175 | irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp); | 175 | irqreturn_t wm_halo_bus_error(int irq, void *data); |
| 176 | irqreturn_t wm_halo_wdt_expire(int irq, void *data); | 176 | irqreturn_t wm_halo_wdt_expire(int irq, void *data); |
| 177 | 177 | ||
| 178 | int wm_adsp_event(struct snd_soc_dapm_widget *w, | 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 | irq = platform_get_irq(pdev, 0); | 887 | irq = platform_get_irq(pdev, 0); |
| 888 | if (irq < 0) { | 888 | if (irq < 0) |
| 889 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | ||
| 890 | return irq; | 889 | return irq; |
| 891 | } | ||
| 892 | 890 | ||
| 893 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, | 891 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, |
| 894 | dev_name(&pdev->dev), asrc_priv); | 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 | struct device *dev = &pdev->dev; | 459 | struct device *dev = &pdev->dev; |
| 460 | struct fsl_audmix *priv; | 460 | struct fsl_audmix *priv; |
| 461 | struct resource *res; | ||
| 462 | const char *mdrv; | 461 | const char *mdrv; |
| 463 | const struct of_device_id *of_id; | 462 | const struct of_device_id *of_id; |
| 464 | void __iomem *regs; | 463 | void __iomem *regs; |
| @@ -475,8 +474,7 @@ static int fsl_audmix_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 475 | return -ENOMEM; | 474 | return -ENOMEM; |
| 476 | 475 | ||
| 477 | /* Get the addresses */ | 476 | /* Get the addresses */ |
| 478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 477 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 479 | regs = devm_ioremap_resource(dev, res); | ||
| 480 | if (IS_ERR(regs)) | 478 | if (IS_ERR(regs)) |
| 481 | return PTR_ERR(regs); | 479 | return PTR_ERR(regs); |
| 482 | 480 | ||
| @@ -32,15 +32,18 @@ · 31 unmodified lines | |||
| 32 | * @extalclk: esai clock source to derive HCK, SCK and FS | 32 | * @extalclk: esai clock source to derive HCK, SCK and FS |
| 33 | * @fsysclk: system clock source to derive HCK, SCK and FS | 33 | * @fsysclk: system clock source to derive HCK, SCK and FS |
| 34 | * @spbaclk: SPBA clock (optional, depending on SoC design) | 34 | * @spbaclk: SPBA clock (optional, depending on SoC design) |
| 35 | * @task: tasklet to handle the reset operation | ||
| 35 | * @fifo_depth: depth of tx/rx FIFO | 36 | * @fifo_depth: depth of tx/rx FIFO |
| 36 | * @slot_width: width of each DAI slot | 37 | * @slot_width: width of each DAI slot |
| 37 | * @slots: number of slots | 38 | * @slots: number of slots |
| 39 | * @channels: channel num for tx or rx | ||
| 38 | * @hck_rate: clock rate of desired HCKx clock | 40 | * @hck_rate: clock rate of desired HCKx clock |
| 39 | * @sck_rate: clock rate of desired SCKx clock | 41 | * @sck_rate: clock rate of desired SCKx clock |
| 40 | * @hck_dir: the direction of HCKx pads | 42 | * @hck_dir: the direction of HCKx pads |
| 41 | * @sck_div: if using PSR/PM dividers for SCKx clock | 43 | * @sck_div: if using PSR/PM dividers for SCKx clock |
| 42 | * @slave_mode: if fully using DAI slave mode | 44 | * @slave_mode: if fully using DAI slave mode |
| 43 | * @synchronous: if using tx/rx synchronous mode | 45 | * @synchronous: if using tx/rx synchronous mode |
| 46 | * @reset_at_xrun: flags for enable reset operaton | ||
| 44 | * @name: driver name | 47 | * @name: driver name |
| 45 | */ | 48 | */ |
| 46 | struct fsl_esai { | 49 | struct fsl_esai { |
| @@ -52,17 +55,20 @@ struct fsl_esai { · 5 unmodified lines | |||
| 52 | struct clk *extalclk; | 55 | struct clk *extalclk; |
| 53 | struct clk *fsysclk; | 56 | struct clk *fsysclk; |
| 54 | struct clk *spbaclk; | 57 | struct clk *spbaclk; |
| 58 | struct tasklet_struct task; | ||
| 55 | u32 fifo_depth; | 59 | u32 fifo_depth; |
| 56 | u32 slot_width; | 60 | u32 slot_width; |
| 57 | u32 slots; | 61 | u32 slots; |
| 58 | u32 tx_mask; | 62 | u32 tx_mask; |
| 59 | u32 rx_mask; | 63 | u32 rx_mask; |
| 64 | u32 channels[2]; | ||
| 60 | u32 hck_rate[2]; | 65 | u32 hck_rate[2]; |
| 61 | u32 sck_rate[2]; | 66 | u32 sck_rate[2]; |
| 62 | bool hck_dir[2]; | 67 | bool hck_dir[2]; |
| 63 | bool sck_div[2]; | 68 | bool sck_div[2]; |
| 64 | bool slave_mode; | 69 | bool slave_mode; |
| 65 | bool synchronous; | 70 | bool synchronous; |
| 71 | bool reset_at_xrun; | ||
| 66 | char name[32]; | 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 | struct fsl_esai *esai_priv = (struct fsl_esai *)devid; | 77 | struct fsl_esai *esai_priv = (struct fsl_esai *)devid; |
| 72 | struct platform_device *pdev = esai_priv->pdev; | 78 | struct platform_device *pdev = esai_priv->pdev; |
| 73 | u32 esr; | 79 | u32 esr; |
| 80 | u32 saisr; | ||
| 74 | 81 | ||
| 75 | regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); | 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 | if (esr & ESAI_ESR_TINIT_MASK) | 91 | if (esr & ESAI_ESR_TINIT_MASK) |
| 78 | dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); | 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 | return 0; | 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 | static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | 720 | static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, |
| 547 | struct snd_soc_dai *dai) | 721 | struct snd_soc_dai *dai) |
| 548 | { | 722 | { |
| 549 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 723 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
| 550 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 724 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 551 | u8 i, channels = substream->runtime->channels; | 725 | |
| 552 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | 726 | esai_priv->channels[tx] = substream->runtime->channels; |
| 553 | u32 mask; | ||
| 554 | 727 | ||
| 555 | switch (cmd) { | 728 | switch (cmd) { |
| 556 | case SNDRV_PCM_TRIGGER_START: | 729 | case SNDRV_PCM_TRIGGER_START: |
| 557 | case SNDRV_PCM_TRIGGER_RESUME: | 730 | case SNDRV_PCM_TRIGGER_RESUME: |
| 558 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 731 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 559 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), | 732 | fsl_esai_trigger_start(esai_priv, 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 | |||
| 588 | break; | 733 | break; |
| 589 | case SNDRV_PCM_TRIGGER_SUSPEND: | 734 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 590 | case SNDRV_PCM_TRIGGER_STOP: | 735 | case SNDRV_PCM_TRIGGER_STOP: |
| 591 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 736 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 592 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 737 | fsl_esai_trigger_stop(esai_priv, 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); | ||
| 604 | break; | 738 | break; |
| 605 | default: | 739 | default: |
| 606 | return -EINVAL; | 740 | return -EINVAL; |
| @@ -787,6 +921,10 @@ static int fsl_esai_probe(struct platform_device *pdev) · 180 unmodified lines | |||
| 787 | esai_priv->pdev = pdev; | 921 | esai_priv->pdev = pdev; |
| 788 | snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); | 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 | /* Get the addresses and IRQ */ | 928 | /* Get the addresses and IRQ */ |
| 791 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 929 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 792 | regs = devm_ioremap_resource(&pdev->dev, res); | 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 | PTR_ERR(esai_priv->spbaclk)); | 962 | PTR_ERR(esai_priv->spbaclk)); |
| 825 | 963 | ||
| 826 | irq = platform_get_irq(pdev, 0); | 964 | irq = platform_get_irq(pdev, 0); |
| 827 | if (irq < 0) { | 965 | if (irq < 0) |
| 828 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | ||
| 829 | return irq; | 966 | return irq; |
| 830 | } | ||
| 831 | 967 | ||
| 832 | ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, | 968 | ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, |
| 833 | esai_priv->name, esai_priv); | 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 | dev_set_drvdata(&pdev->dev, esai_priv); | 1003 | dev_set_drvdata(&pdev->dev, esai_priv); |
| 868 | 1004 | ||
| 869 | /* Reset ESAI unit */ | 1005 | ret = fsl_esai_hw_init(esai_priv); |
| 870 | ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST); | 1006 | if (ret) |
| 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); | ||
| 883 | return ret; | 1007 | return ret; |
| 884 | } | ||
| 885 | 1008 | ||
| 886 | esai_priv->tx_mask = 0xFFFFFFFF; | 1009 | esai_priv->tx_mask = 0xFFFFFFFF; |
| 887 | esai_priv->rx_mask = 0xFFFFFFFF; | 1010 | esai_priv->rx_mask = 0xFFFFFFFF; |
| @@ -899,6 +1022,9 @@ static int fsl_esai_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 899 | return ret; | 1022 | return ret; |
| 900 | } | 1023 | } |
| 901 | 1024 | ||
| 1025 | tasklet_init(&esai_priv->task, fsl_esai_hw_reset, | ||
| 1026 | (unsigned long)esai_priv); | ||
| 1027 | |||
| 902 | pm_runtime_enable(&pdev->dev); | 1028 | pm_runtime_enable(&pdev->dev); |
| 903 | 1029 | ||
| 904 | regcache_cache_only(esai_priv->regmap, true); | 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 | static int fsl_esai_remove(struct platform_device *pdev) | 1039 | static int fsl_esai_remove(struct platform_device *pdev) |
| 914 | { | 1040 | { |
| 1041 | struct fsl_esai *esai_priv = platform_get_drvdata(pdev); | ||
| 1042 | |||
| 915 | pm_runtime_disable(&pdev->dev); | 1043 | pm_runtime_disable(&pdev->dev); |
| 1044 | tasklet_kill(&esai_priv->task); | ||
| 916 | 1045 | ||
| 917 | return 0; | 1046 | return 0; |
| 918 | } | 1047 | } |
| @@ -920,6 +1049,7 @@ static int fsl_esai_remove(struct platform_device *pdev) · 1 unmodified line | |||
| 920 | static const struct of_device_id fsl_esai_dt_ids[] = { | 1049 | static const struct of_device_id fsl_esai_dt_ids[] = { |
| 921 | { .compatible = "fsl,imx35-esai", }, | 1050 | { .compatible = "fsl,imx35-esai", }, |
| 922 | { .compatible = "fsl,vf610-esai", }, | 1051 | { .compatible = "fsl,vf610-esai", }, |
| 1052 | { .compatible = "fsl,imx6ull-esai", }, | ||
| 923 | {} | 1053 | {} |
| 924 | }; | 1054 | }; |
| 925 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); | 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 | regcache_cache_only(esai->regmap, false); | 1086 | regcache_cache_only(esai->regmap, false); |
| 957 | 1087 | ||
| 958 | /* FIFO reset for safety */ | 1088 | ret = fsl_esai_register_restore(esai); |
| 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); | ||
| 965 | if (ret) | 1089 | if (ret) |
| 966 | goto err_regcache_sync; | 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 | return 0; | 1092 | return 0; |
| 973 | 1093 | ||
| 974 | err_regcache_sync: | 1094 | err_regcache_sync: |
| @@ -991,7 +1111,6 @@ static int fsl_esai_runtime_suspend(struct device *dev) · 16 unmodified lines | |||
| 991 | struct fsl_esai *esai = dev_get_drvdata(dev); | 1111 | struct fsl_esai *esai = dev_get_drvdata(dev); |
| 992 | 1112 | ||
| 993 | regcache_cache_only(esai->regmap, true); | 1113 | regcache_cache_only(esai->regmap, true); |
| 994 | regcache_mark_dirty(esai->regmap); | ||
| 995 | 1114 | ||
| 996 | if (!IS_ERR(esai->fsysclk)) | 1115 | if (!IS_ERR(esai->fsysclk)) |
| 997 | clk_disable_unprepare(esai->fsysclk); | 1116 | clk_disable_unprepare(esai->fsysclk); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/dmaengine.h> | 9 | #include <linux/dmaengine.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/of_address.h> | 11 | #include <linux/of_address.h> |
| 12 | #include <linux/of_device.h> | ||
| 12 | #include <linux/pm_runtime.h> | 13 | #include <linux/pm_runtime.h> |
| 13 | #include <linux/regmap.h> | 14 | #include <linux/regmap.h> |
| 14 | #include <linux/slab.h> | 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 | static irqreturn_t fsl_sai_isr(int irq, void *devid) | 40 | static irqreturn_t fsl_sai_isr(int irq, void *devid) |
| 40 | { | 41 | { |
| 41 | struct fsl_sai *sai = (struct fsl_sai *)devid; | 42 | struct fsl_sai *sai = (struct fsl_sai *)devid; |
| 43 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 42 | struct device *dev = &sai->pdev->dev; | 44 | struct device *dev = &sai->pdev->dev; |
| 43 | u32 flags, xcsr, mask; | 45 | u32 flags, xcsr, mask; |
| 44 | bool irq_none = true; | 46 | bool irq_none = true; |
| @@ -51,7 +53,7 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) · 6 unmodified lines | |||
| 51 | mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; | 53 | mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; |
| 52 | 54 | ||
| 53 | /* Tx IRQ */ | 55 | /* Tx IRQ */ |
| 54 | regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); | 56 | regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr); |
| 55 | flags = xcsr & mask; | 57 | flags = xcsr & mask; |
| 56 | 58 | ||
| 57 | if (flags) | 59 | if (flags) |
| @@ -81,11 +83,11 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) · 23 unmodified lines | |||
| 81 | xcsr &= ~FSL_SAI_CSR_xF_MASK; | 83 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
| 82 | 84 | ||
| 83 | if (flags) | 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 | irq_rx: | 88 | irq_rx: |
| 87 | /* Rx IRQ */ | 89 | /* Rx IRQ */ |
| 88 | regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); | 90 | regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr); |
| 89 | flags = xcsr & mask; | 91 | flags = xcsr & mask; |
| 90 | 92 | ||
| 91 | if (flags) | 93 | if (flags) |
| @@ -115,7 +117,7 @@ irq_rx: · 23 unmodified lines | |||
| 115 | xcsr &= ~FSL_SAI_CSR_xF_MASK; | 117 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
| 116 | 118 | ||
| 117 | if (flags) | 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 | out: | 122 | out: |
| 121 | if (irq_none) | 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 | int clk_id, unsigned int freq, int fsl_dir) | 141 | int clk_id, unsigned int freq, int fsl_dir) |
| 140 | { | 142 | { |
| 141 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 143 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 144 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 142 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; | 145 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
| 143 | u32 val_cr2 = 0; | 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 | return -EINVAL; | 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 | FSL_SAI_CR2_MSEL_MASK, val_cr2); | 166 | FSL_SAI_CR2_MSEL_MASK, val_cr2); |
| 164 | 167 | ||
| 165 | return 0; | 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 | unsigned int fmt, int fsl_dir) | 195 | unsigned int fmt, int fsl_dir) |
| 193 | { | 196 | { |
| 194 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 197 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 198 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 195 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; | 199 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
| 196 | u32 val_cr2 = 0, val_cr4 = 0; | 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 | return -EINVAL; | 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 | FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); | 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 | FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | | 296 | FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | |
| 293 | FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); | 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 | static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) | 319 | static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) |
| 316 | { | 320 | { |
| 317 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); | 321 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); |
| 322 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 318 | unsigned long clk_rate; | 323 | unsigned long clk_rate; |
| 319 | u32 savediv = 0, ratio, savesub = freq; | 324 | u32 savediv = 0, ratio, savesub = freq; |
| 320 | u32 id; | 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 | if ((sai->synchronous[TX] && !sai->synchronous[RX]) || | 383 | if ((sai->synchronous[TX] && !sai->synchronous[RX]) || |
| 379 | (!tx && !sai->synchronous[RX])) { | 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 | FSL_SAI_CR2_MSEL_MASK, | 386 | FSL_SAI_CR2_MSEL_MASK, |
| 382 | FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); | 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 | FSL_SAI_CR2_DIV_MASK, savediv - 1); | 389 | FSL_SAI_CR2_DIV_MASK, savediv - 1); |
| 385 | } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || | 390 | } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || |
| 386 | (tx && !sai->synchronous[TX])) { | 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 | FSL_SAI_CR2_MSEL_MASK, | 393 | FSL_SAI_CR2_MSEL_MASK, |
| 389 | FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); | 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 | FSL_SAI_CR2_DIV_MASK, savediv - 1); | 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 | struct snd_soc_dai *cpu_dai) | 407 | struct snd_soc_dai *cpu_dai) |
| 403 | { | 408 | { |
| 404 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 409 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 410 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 405 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 411 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 406 | unsigned int channels = params_channels(params); | 412 | unsigned int channels = params_channels(params); |
| 407 | u32 word_width = params_width(params); | 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 | if (!sai->is_slave_mode) { | 461 | if (!sai->is_slave_mode) { |
| 456 | if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { | 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 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, | 464 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 459 | val_cr4); | 465 | val_cr4); |
| 460 | regmap_update_bits(sai->regmap, FSL_SAI_TCR5, | 466 | regmap_update_bits(sai->regmap, FSL_SAI_TCR5(ofs), |
| 461 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | | 467 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 462 | FSL_SAI_CR5_FBT_MASK, val_cr5); | 468 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 463 | regmap_write(sai->regmap, FSL_SAI_TMR, | 469 | regmap_write(sai->regmap, FSL_SAI_TMR, |
| 464 | ~0UL - ((1 << channels) - 1)); | 470 | ~0UL - ((1 << channels) - 1)); |
| 465 | } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { | 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 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, | 473 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 468 | val_cr4); | 474 | val_cr4); |
| 469 | regmap_update_bits(sai->regmap, FSL_SAI_RCR5, | 475 | regmap_update_bits(sai->regmap, FSL_SAI_RCR5(ofs), |
| 470 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | | 476 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 471 | FSL_SAI_CR5_FBT_MASK, val_cr5); | 477 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 472 | regmap_write(sai->regmap, FSL_SAI_RMR, | 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 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, | 484 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
| 479 | val_cr4); | 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 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | | 487 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | |
| 482 | FSL_SAI_CR5_FBT_MASK, val_cr5); | 488 | FSL_SAI_CR5_FBT_MASK, val_cr5); |
| 483 | regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); | 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 | struct snd_soc_dai *cpu_dai) | 511 | struct snd_soc_dai *cpu_dai) |
| 506 | { | 512 | { |
| 507 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 513 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 514 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 515 | |||
| 508 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 516 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 509 | u32 xcsr, count = 100; | 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 | * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. | 521 | * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. |
| 514 | * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. | 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, | 524 | regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC, |
| 517 | sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); | 525 | sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); |
| 518 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, | 526 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC, |
| 519 | sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); | 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 | case SNDRV_PCM_TRIGGER_START: | 534 | case SNDRV_PCM_TRIGGER_START: |
| 527 | case SNDRV_PCM_TRIGGER_RESUME: | 535 | case SNDRV_PCM_TRIGGER_RESUME: |
| 528 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 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 | FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); | 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 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | 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 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | 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 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); | 546 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); |
| 539 | break; | 547 | break; |
| 540 | case SNDRV_PCM_TRIGGER_STOP: | 548 | case SNDRV_PCM_TRIGGER_STOP: |
| 541 | case SNDRV_PCM_TRIGGER_SUSPEND: | 549 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 542 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 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 | FSL_SAI_CSR_FRDE, 0); | 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 | FSL_SAI_CSR_xIE_MASK, 0); | 554 | FSL_SAI_CSR_xIE_MASK, 0); |
| 547 | 555 | ||
| 548 | /* Check if the opposite FRDE is also disabled */ | 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 | if (!(xcsr & FSL_SAI_CSR_FRDE)) { | 558 | if (!(xcsr & FSL_SAI_CSR_FRDE)) { |
| 551 | /* Disable both directions and reset their FIFOs */ | 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 | FSL_SAI_CSR_TERE, 0); | 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 | FSL_SAI_CSR_TERE, 0); | 563 | FSL_SAI_CSR_TERE, 0); |
| 556 | 564 | ||
| 557 | /* TERE will remain set till the end of current frame */ | 565 | /* TERE will remain set till the end of current frame */ |
| 558 | do { | 566 | do { |
| 559 | udelay(10); | 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 | } while (--count && xcsr & FSL_SAI_CSR_TERE); | 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 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); | 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 | FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); | 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 | if (!sai->is_slave_mode) { | 584 | if (!sai->is_slave_mode) { |
| 576 | /* Software Reset for both Tx and Rx */ | 585 | /* Software Reset for both Tx and Rx */ |
| 577 | regmap_write(sai->regmap, | 586 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), |
| 578 | FSL_SAI_TCSR, FSL_SAI_CSR_SR); | 587 | FSL_SAI_CSR_SR); |
| 579 | regmap_write(sai->regmap, | 588 | regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), |
| 580 | FSL_SAI_RCSR, FSL_SAI_CSR_SR); | 589 | FSL_SAI_CSR_SR); |
| 581 | /* Clear SR bit to finish the reset */ | 590 | /* Clear SR bit to finish the reset */ |
| 582 | regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | 591 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); |
| 583 | regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | 592 | regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); |
| 584 | } | 593 | } |
| 585 | } | 594 | } |
| 586 | break; | 595 | break; |
| @@ -595,10 +604,12 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, · 8 unmodified lines | |||
| 595 | struct snd_soc_dai *cpu_dai) | 604 | struct snd_soc_dai *cpu_dai) |
| 596 | { | 605 | { |
| 597 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 606 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 607 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 598 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 608 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 599 | int ret; | 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 | FSL_SAI_CR3_TRCE); | 613 | FSL_SAI_CR3_TRCE); |
| 603 | 614 | ||
| 604 | ret = snd_pcm_hw_constraint_list(substream->runtime, 0, | 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 | struct snd_soc_dai *cpu_dai) | 622 | struct snd_soc_dai *cpu_dai) |
| 612 | { | 623 | { |
| 613 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 624 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
| 625 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 614 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 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 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { | 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 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) | 643 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
| 631 | { | 644 | { |
| 632 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); | 645 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); |
| 646 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 633 | 647 | ||
| 634 | /* Software Reset for both Tx and Rx */ | 648 | /* Software Reset for both Tx and Rx */ |
| 635 | regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); | 649 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); |
| 636 | regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); | 650 | regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); |
| 637 | /* Clear SR bit to finish the reset */ | 651 | /* Clear SR bit to finish the reset */ |
| 638 | regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | 652 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); |
| 639 | regmap_write(sai->regmap, FSL_SAI_RCSR, 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, | 655 | regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), |
| 642 | FSL_SAI_MAXBURST_TX * 2); | 656 | FSL_SAI_CR1_RFW_MASK, |
| 643 | regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, | 657 | sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX); |
| 644 | FSL_SAI_MAXBURST_RX - 1); | 658 | regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs), |
| 659 | FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_RX - 1); | ||
| 645 | 660 | ||
| 646 | snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, | 661 | snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, |
| 647 | &sai->dma_params_rx); | 662 | &sai->dma_params_rx); |
| @@ -678,41 +693,89 @@ static const struct snd_soc_component_driver fsl_component = { · 30 unmodified lines | |||
| 678 | .name = "fsl-sai", | 693 | .name = "fsl-sai", |
| 679 | }; | 694 | }; |
| 680 | 695 | ||
| 681 | static struct reg_default fsl_sai_reg_defaults[] = { | 696 | static struct reg_default fsl_sai_reg_defaults_ofs0[] = { |
| 682 | {FSL_SAI_TCR1, 0}, | 697 | {FSL_SAI_TCR1(0), 0}, |
| 683 | {FSL_SAI_TCR2, 0}, | 698 | {FSL_SAI_TCR2(0), 0}, |
| 684 | {FSL_SAI_TCR3, 0}, | 699 | {FSL_SAI_TCR3(0), 0}, |
| 685 | {FSL_SAI_TCR4, 0}, | 700 | {FSL_SAI_TCR4(0), 0}, |
| 686 | {FSL_SAI_TCR5, 0}, | 701 | {FSL_SAI_TCR5(0), 0}, |
| 687 | {FSL_SAI_TDR, 0}, | 702 | {FSL_SAI_TDR0, 0}, |
| 688 | {FSL_SAI_TMR, 0}, | 703 | {FSL_SAI_TDR1, 0}, |
| 689 | {FSL_SAI_RCR1, 0}, | 704 | {FSL_SAI_TDR2, 0}, |
| 690 | {FSL_SAI_RCR2, 0}, | 705 | {FSL_SAI_TDR3, 0}, |
| 691 | {FSL_SAI_RCR3, 0}, | 706 | {FSL_SAI_TDR4, 0}, |
| 692 | {FSL_SAI_RCR4, 0}, | 707 | {FSL_SAI_TDR5, 0}, |
| 693 | {FSL_SAI_RCR5, 0}, | 708 | {FSL_SAI_TDR6, 0}, |
| 694 | {FSL_SAI_RMR, 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 | static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) | 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 | switch (reg) { | 753 | switch (reg) { |
| 700 | case FSL_SAI_TCSR: | 754 | case FSL_SAI_TFR0: |
| 701 | case FSL_SAI_TCR1: | 755 | case FSL_SAI_TFR1: |
| 702 | case FSL_SAI_TCR2: | 756 | case FSL_SAI_TFR2: |
| 703 | case FSL_SAI_TCR3: | 757 | case FSL_SAI_TFR3: |
| 704 | case FSL_SAI_TCR4: | 758 | case FSL_SAI_TFR4: |
| 705 | case FSL_SAI_TCR5: | 759 | case FSL_SAI_TFR5: |
| 706 | case FSL_SAI_TFR: | 760 | case FSL_SAI_TFR6: |
| 761 | case FSL_SAI_TFR7: | ||
| 707 | case FSL_SAI_TMR: | 762 | case FSL_SAI_TMR: |
| 708 | case FSL_SAI_RCSR: | 763 | case FSL_SAI_RDR0: |
| 709 | case FSL_SAI_RCR1: | 764 | case FSL_SAI_RDR1: |
| 710 | case FSL_SAI_RCR2: | 765 | case FSL_SAI_RDR2: |
| 711 | case FSL_SAI_RCR3: | 766 | case FSL_SAI_RDR3: |
| 712 | case FSL_SAI_RCR4: | 767 | case FSL_SAI_RDR4: |
| 713 | case FSL_SAI_RCR5: | 768 | case FSL_SAI_RDR5: |
| 714 | case FSL_SAI_RDR: | 769 | case FSL_SAI_RDR6: |
| 715 | case FSL_SAI_RFR: | 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 | case FSL_SAI_RMR: | 779 | case FSL_SAI_RMR: |
| 717 | return true; | 780 | return true; |
| 718 | default: | 781 | default: |
| @@ -722,12 +785,37 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) · 3 unmodified lines | |||
| 722 | 785 | ||
| 723 | static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) | 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 | switch (reg) { | 794 | switch (reg) { |
| 726 | case FSL_SAI_TCSR: | 795 | case FSL_SAI_TFR0: |
| 727 | case FSL_SAI_RCSR: | 796 | case FSL_SAI_TFR1: |
| 728 | case FSL_SAI_TFR: | 797 | case FSL_SAI_TFR2: |
| 729 | case FSL_SAI_RFR: | 798 | case FSL_SAI_TFR3: |
| 730 | case FSL_SAI_RDR: | 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 | return true; | 819 | return true; |
| 732 | default: | 820 | default: |
| 733 | return false; | 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 | static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) | 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 | switch (reg) { | 836 | switch (reg) { |
| 740 | case FSL_SAI_TCSR: | 837 | case FSL_SAI_TDR0: |
| 741 | case FSL_SAI_TCR1: | 838 | case FSL_SAI_TDR1: |
| 742 | case FSL_SAI_TCR2: | 839 | case FSL_SAI_TDR2: |
| 743 | case FSL_SAI_TCR3: | 840 | case FSL_SAI_TDR3: |
| 744 | case FSL_SAI_TCR4: | 841 | case FSL_SAI_TDR4: |
| 745 | case FSL_SAI_TCR5: | 842 | case FSL_SAI_TDR5: |
| 746 | case FSL_SAI_TDR: | 843 | case FSL_SAI_TDR6: |
| 844 | case FSL_SAI_TDR7: | ||
| 747 | case FSL_SAI_TMR: | 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 | case FSL_SAI_RMR: | 846 | case FSL_SAI_RMR: |
| 755 | return true; | 847 | return true; |
| 756 | default: | 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 | .reg_bits = 32, | 854 | .reg_bits = 32, |
| 763 | .reg_stride = 4, | 855 | .reg_stride = 4, |
| 764 | .val_bits = 32, | 856 | .val_bits = 32, |
| 857 | .fast_io = true, | ||
| 765 | 858 | ||
| 766 | .max_register = FSL_SAI_RMR, | 859 | .max_register = FSL_SAI_RMR, |
| 767 | .reg_defaults = fsl_sai_reg_defaults, | 860 | .reg_defaults = fsl_sai_reg_defaults_ofs0, |
| 768 | .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults), | 861 | .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0), |
| 769 | .readable_reg = fsl_sai_readable_reg, | 862 | .readable_reg = fsl_sai_readable_reg, |
| 770 | .volatile_reg = fsl_sai_volatile_reg, | 863 | .volatile_reg = fsl_sai_volatile_reg, |
| 771 | .writeable_reg = fsl_sai_writeable_reg, | 864 | .writeable_reg = fsl_sai_writeable_reg, |
| @@ -788,10 +881,7 @@ static int fsl_sai_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 788 | return -ENOMEM; | 881 | return -ENOMEM; |
| 789 | 882 | ||
| 790 | sai->pdev = pdev; | 883 | sai->pdev = pdev; |
| 791 | 884 | sai->soc_data = of_device_get_match_data(&pdev->dev); | |
| 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; | ||
| 795 | 885 | ||
| 796 | sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); | 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 | if (IS_ERR(base)) | 890 | if (IS_ERR(base)) |
| 801 | return PTR_ERR(base); | 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 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, | 899 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, |
| 804 | "bus", base, &fsl_sai_regmap_config); | 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 | irq = platform_get_irq(pdev, 0); | 930 | irq = platform_get_irq(pdev, 0); |
| 835 | if (irq < 0) { | 931 | if (irq < 0) |
| 836 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | ||
| 837 | return irq; | 932 | return irq; |
| 838 | } | ||
| 839 | 933 | ||
| 840 | ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); | 934 | ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); |
| 841 | if (ret) { | 935 | if (ret) { |
| @@ -886,8 +980,8 @@ static int fsl_sai_probe(struct platform_device *pdev) · 44 unmodified lines | |||
| 886 | MCLK_DIR(index)); | 980 | MCLK_DIR(index)); |
| 887 | } | 981 | } |
| 888 | 982 | ||
| 889 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; | 983 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; |
| 890 | sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; | 984 | sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; |
| 891 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; | 985 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; |
| 892 | sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; | 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 | if (ret) | 994 | if (ret) |
| 901 | return ret; | 995 | return ret; |
| 902 | 996 | ||
| 903 | if (sai->sai_on_imx) | 997 | if (sai->soc_data->use_imx_pcm) |
| 904 | return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); | 998 | return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); |
| 905 | else | 999 | else |
| 906 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); | 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 | return 0; | 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 | static const struct of_device_id fsl_sai_ids[] = { | 1040 | static const struct of_device_id fsl_sai_ids[] = { |
| 917 | { .compatible = "fsl,vf610-sai", }, | 1041 | { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, |
| 918 | { .compatible = "fsl,imx6sx-sai", }, | 1042 | { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, |
| 919 | { .compatible = "fsl,imx6ul-sai", }, | 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 | { /* sentinel */ } | 1047 | { /* sentinel */ } |
| 921 | }; | 1048 | }; |
| 922 | MODULE_DEVICE_TABLE(of, fsl_sai_ids); | 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 | static int fsl_sai_runtime_resume(struct device *dev) | 1070 | static int fsl_sai_runtime_resume(struct device *dev) |
| 944 | { | 1071 | { |
| 945 | struct fsl_sai *sai = dev_get_drvdata(dev); | 1072 | struct fsl_sai *sai = dev_get_drvdata(dev); |
| 1073 | unsigned int ofs = sai->soc_data->reg_offset; | ||
| 946 | int ret; | 1074 | int ret; |
| 947 | 1075 | ||
| 948 | ret = clk_prepare_enable(sai->bus_clk); | 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 | regcache_cache_only(sai->regmap, false); | 1094 | regcache_cache_only(sai->regmap, false); |
| 967 | regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); | 1095 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); |
| 968 | regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); | 1096 | regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); |
| 969 | usleep_range(1000, 2000); | 1097 | usleep_range(1000, 2000); |
| 970 | regmap_write(sai->regmap, FSL_SAI_TCSR, 0); | 1098 | regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); |
| 971 | regmap_write(sai->regmap, FSL_SAI_RCSR, 0); | 1099 | regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); |
| 972 | 1100 | ||
| 973 | ret = regcache_sync(sai->regmap); | 1101 | ret = regcache_sync(sai->regmap); |
| 974 | if (ret) | 1102 | if (ret) |
| @@ -14,33 +14,61 @@ · 13 unmodified lines | |||
| 14 | SNDRV_PCM_FMTBIT_S32_LE) | 14 | SNDRV_PCM_FMTBIT_S32_LE) |
| 15 | 15 | ||
| 16 | /* SAI Register Map Register */ | 16 | /* SAI Register Map Register */ |
| 17 | #define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ | 17 | #define FSL_SAI_TCSR(ofs) (0x00 + ofs) /* SAI Transmit Control */ |
| 18 | #define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ | 18 | #define FSL_SAI_TCR1(ofs) (0x04 + ofs) /* SAI Transmit Configuration 1 */ |
| 19 | #define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ | 19 | #define FSL_SAI_TCR2(ofs) (0x08 + ofs) /* SAI Transmit Configuration 2 */ |
| 20 | #define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ | 20 | #define FSL_SAI_TCR3(ofs) (0x0c + ofs) /* SAI Transmit Configuration 3 */ |
| 21 | #define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ | 21 | #define FSL_SAI_TCR4(ofs) (0x10 + ofs) /* SAI Transmit Configuration 4 */ |
| 22 | #define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ | 22 | #define FSL_SAI_TCR5(ofs) (0x14 + ofs) /* SAI Transmit Configuration 5 */ |
| 23 | #define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ | 23 | #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data 0 */ |
| 24 | #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ | 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 | #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ | 39 | #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ |
| 26 | #define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ | 40 | #define FSL_SAI_RCSR(ofs) (0x80 + ofs) /* SAI Receive Control */ |
| 27 | #define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ | 41 | #define FSL_SAI_RCR1(ofs) (0x84 + ofs)/* SAI Receive Configuration 1 */ |
| 28 | #define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ | 42 | #define FSL_SAI_RCR2(ofs) (0x88 + ofs) /* SAI Receive Configuration 2 */ |
| 29 | #define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ | 43 | #define FSL_SAI_RCR3(ofs) (0x8c + ofs) /* SAI Receive Configuration 3 */ |
| 30 | #define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ | 44 | #define FSL_SAI_RCR4(ofs) (0x90 + ofs) /* SAI Receive Configuration 4 */ |
| 31 | #define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ | 45 | #define FSL_SAI_RCR5(ofs) (0x94 + ofs) /* SAI Receive Configuration 5 */ |
| 32 | #define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ | 46 | #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data 0 */ |
| 33 | #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ | 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 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ | 62 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ |
| 35 | 63 | ||
| 36 | #define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) | 64 | #define FSL_SAI_xCSR(tx, ofs) (tx ? FSL_SAI_TCSR(ofs) : FSL_SAI_RCSR(ofs)) |
| 37 | #define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) | 65 | #define FSL_SAI_xCR1(tx, ofs) (tx ? FSL_SAI_TCR1(ofs) : FSL_SAI_RCR1(ofs)) |
| 38 | #define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) | 66 | #define FSL_SAI_xCR2(tx, ofs) (tx ? FSL_SAI_TCR2(ofs) : FSL_SAI_RCR2(ofs)) |
| 39 | #define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) | 67 | #define FSL_SAI_xCR3(tx, ofs) (tx ? FSL_SAI_TCR3(ofs) : FSL_SAI_RCR3(ofs)) |
| 40 | #define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) | 68 | #define FSL_SAI_xCR4(tx, ofs) (tx ? FSL_SAI_TCR4(ofs) : FSL_SAI_RCR4(ofs)) |
| 41 | #define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) | 69 | #define FSL_SAI_xCR5(tx, ofs) (tx ? FSL_SAI_TCR5(ofs) : FSL_SAI_RCR5(ofs)) |
| 42 | #define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) | 70 | #define FSL_SAI_xDR(tx, ofs) (tx ? FSL_SAI_TDR(ofs) : FSL_SAI_RDR(ofs)) |
| 43 | #define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) | 71 | #define FSL_SAI_xFR(tx, ofs) (tx ? FSL_SAI_TFR(ofs) : FSL_SAI_RFR(ofs)) |
| 44 | #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) | 72 | #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) |
| 45 | 73 | ||
| 46 | /* SAI Transmit/Receive Control Register */ | 74 | /* SAI Transmit/Receive Control Register */ |
| @@ -82,6 +110,7 @@ · 35 unmodified lines | |||
| 82 | 110 | ||
| 83 | /* SAI Transmit and Receive Configuration 3 Register */ | 111 | /* SAI Transmit and Receive Configuration 3 Register */ |
| 84 | #define FSL_SAI_CR3_TRCE BIT(16) | 112 | #define FSL_SAI_CR3_TRCE BIT(16) |
| 113 | #define FSL_SAI_CR3_TRCE_MASK GENMASK(23, 16) | ||
| 85 | #define FSL_SAI_CR3_WDFL(x) (x) | 114 | #define FSL_SAI_CR3_WDFL(x) (x) |
| 86 | #define FSL_SAI_CR3_WDFL_MASK 0x1f | 115 | #define FSL_SAI_CR3_WDFL_MASK 0x1f |
| 87 | 116 | ||
| @@ -126,6 +155,12 @@ · 38 unmodified lines | |||
| 126 | #define FSL_SAI_MAXBURST_TX 6 | 155 | #define FSL_SAI_MAXBURST_TX 6 |
| 127 | #define FSL_SAI_MAXBURST_RX 6 | 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 | struct fsl_sai { | 164 | struct fsl_sai { |
| 130 | struct platform_device *pdev; | 165 | struct platform_device *pdev; |
| 131 | struct regmap *regmap; | 166 | struct regmap *regmap; |
| @@ -135,7 +170,6 @@ struct fsl_sai { · 3 unmodified lines | |||
| 135 | bool is_slave_mode; | 170 | bool is_slave_mode; |
| 136 | bool is_lsb_first; | 171 | bool is_lsb_first; |
| 137 | bool is_dsp_mode; | 172 | bool is_dsp_mode; |
| 138 | bool sai_on_imx; | ||
| 139 | bool synchronous[2]; | 173 | bool synchronous[2]; |
| 140 | 174 | ||
| 141 | unsigned int mclk_id[2]; | 175 | unsigned int mclk_id[2]; |
| @@ -143,6 +177,7 @@ struct fsl_sai { · 1 unmodified line | |||
| 143 | unsigned int slots; | 177 | unsigned int slots; |
| 144 | unsigned int slot_width; | 178 | unsigned int slot_width; |
| 145 | 179 | ||
| 180 | const struct fsl_sai_soc_data *soc_data; | ||
| 146 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 181 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
| 147 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 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 | irq = platform_get_irq(pdev, 0); | 1250 | irq = platform_get_irq(pdev, 0); |
| 1251 | if (irq < 0) { | 1251 | if (irq < 0) |
| 1252 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | ||
| 1253 | return irq; | 1252 | return irq; |
| 1254 | } | ||
| 1255 | 1253 | ||
| 1256 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, | 1254 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, |
| 1257 | dev_name(&pdev->dev), spdif_priv); | 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 | ssi->irq = platform_get_irq(pdev, 0); | 1512 | ssi->irq = platform_get_irq(pdev, 0); |
| 1513 | if (ssi->irq < 0) { | 1513 | if (ssi->irq < 0) |
| 1514 | dev_err(dev, "no irq for node %s\n", pdev->name); | ||
| 1515 | return ssi->irq; | 1514 | return ssi->irq; |
| 1516 | } | ||
| 1517 | 1515 | ||
| 1518 | /* Set software limitations for synchronous mode except AC97 */ | 1516 | /* Set software limitations for synchronous mode except AC97 */ |
| 1519 | if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { | 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 | priv->card.num_configs = priv->num_dai_conf; | 325 | priv->card.num_configs = priv->num_dai_conf; |
| 326 | priv->card.dapm_routes = priv->dapm_routes; | 326 | priv->card.dapm_routes = priv->dapm_routes; |
| 327 | priv->card.num_dapm_routes = priv->num_dapm_routes; | 327 | priv->card.num_dapm_routes = priv->num_dapm_routes; |
| 328 | priv->card.dev = pdev->dev.parent; | 328 | priv->card.dev = &pdev->dev; |
| 329 | priv->card.owner = THIS_MODULE; | 329 | priv->card.owner = THIS_MODULE; |
| 330 | priv->card.name = "imx-audmix"; | 330 | priv->card.name = "imx-audmix"; |
| 331 | 331 | ||
| 332 | platform_set_drvdata(pdev, &priv->card); | 332 | platform_set_drvdata(pdev, &priv->card); |
| 333 | snd_soc_card_set_drvdata(&priv->card, priv); | 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 | if (ret) { | 336 | if (ret) { |
| 337 | dev_err(&pdev->dev, "snd_soc_register_card failed\n"); | 337 | dev_err(&pdev->dev, "snd_soc_register_card failed\n"); |
| 338 | return ret; | 338 | return ret; |
| @@ -300,12 +300,10 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, · 299 unmodified lines | |||
| 300 | 300 | ||
| 301 | static int imx_audmux_probe(struct platform_device *pdev) | 301 | static int imx_audmux_probe(struct platform_device *pdev) |
| 302 | { | 302 | { |
| 303 | struct resource *res; | ||
| 304 | const struct of_device_id *of_id = | 303 | const struct of_device_id *of_id = |
| 305 | of_match_device(imx_audmux_dt_ids, &pdev->dev); | 304 | of_match_device(imx_audmux_dt_ids, &pdev->dev); |
| 306 | 305 | ||
| 307 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 306 | audmux_base = devm_platform_ioremap_resource(pdev, 0); |
| 308 | audmux_base = devm_ioremap_resource(&pdev->dev, res); | ||
| 309 | if (IS_ERR(audmux_base)) | 307 | if (IS_ERR(audmux_base)) |
| 310 | return PTR_ERR(audmux_base); | 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 | ssi->irq = platform_get_irq(pdev, 0); | 522 | ssi->irq = platform_get_irq(pdev, 0); |
| 523 | if (ssi->irq < 0) { | 523 | if (ssi->irq < 0) |
| 524 | dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); | ||
| 525 | return ssi->irq; | 524 | return ssi->irq; |
| 526 | } | ||
| 527 | 525 | ||
| 528 | ssi->clk = devm_clk_get(&pdev->dev, NULL); | 526 | ssi->clk = devm_clk_get(&pdev->dev, NULL); |
| 529 | if (IS_ERR(ssi->clk)) { | 527 | if (IS_ERR(ssi->clk)) { |
| @@ -129,6 +129,25 @@ static int asoc_simple_parse_dai(struct device_node *ep, · 128 unmodified lines | |||
| 129 | args.args[0] = graph_get_dai_id(ep); | 129 | args.args[0] = graph_get_dai_id(ep); |
| 130 | args.args_count = (of_graph_get_endpoint_count(node) > 1); | 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 | ret = snd_soc_get_dai_name(&args, &dlc->dai_name); | 151 | ret = snd_soc_get_dai_name(&args, &dlc->dai_name); |
| 133 | if (ret < 0) | 152 | if (ret < 0) |
| 134 | return ret; | 153 | return ret; |
| @@ -213,10 +213,17 @@ EXPORT_SYMBOL_GPL(asoc_simple_startup); · 212 unmodified lines | |||
| 213 | void asoc_simple_shutdown(struct snd_pcm_substream *substream) | 213 | void asoc_simple_shutdown(struct snd_pcm_substream *substream) |
| 214 | { | 214 | { |
| 215 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 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 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); | 218 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
| 217 | struct simple_dai_props *dai_props = | 219 | struct simple_dai_props *dai_props = |
| 218 | simple_priv_to_props(priv, rtd->num); | 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 | asoc_simple_clk_disable(dai_props->cpu_dai); | 227 | asoc_simple_clk_disable(dai_props->cpu_dai); |
| 221 | 228 | ||
| 222 | asoc_simple_clk_disable(dai_props->codec_dai); | 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 | if (ret) | 46 | if (ret) |
| 47 | return ret; | 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 | ret = snd_soc_of_get_dai_name(node, &dlc->dai_name); | 68 | ret = snd_soc_of_get_dai_name(node, &dlc->dai_name); |
| 51 | if (ret < 0) | 69 | if (ret < 0) |
| 52 | return ret; | 70 | return ret; |
| @@ -424,7 +442,7 @@ static int simple_parse_aux_devs(struct device_node *node, · 371 unmodified lines | |||
| 424 | aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); | 442 | aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); |
| 425 | if (!aux_node) | 443 | if (!aux_node) |
| 426 | return -EINVAL; | 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 | card->num_aux_devs = n; | 448 | card->num_aux_devs = n; |
| @@ -215,6 +215,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON · 214 unmodified lines | |||
| 215 | select SND_SOC_INTEL_SST | 215 | select SND_SOC_INTEL_SST |
| 216 | select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC | 216 | select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC |
| 217 | select SND_SOC_ACPI_INTEL_MATCH | 217 | select SND_SOC_ACPI_INTEL_MATCH |
| 218 | select SND_INTEL_NHLT if ACPI | ||
| 218 | help | 219 | help |
| 219 | If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ | 220 | If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ |
| 220 | GeminiLake or CannonLake platform with the DSP enabled in the BIOS | 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 | static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) | 211 | static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) |
| 212 | { | 212 | { |
| 213 | struct sst_byt_stream *stream; | 213 | struct sst_byt_stream *stream; |
| 214 | u64 header = msg->header; | 214 | u64 header = msg->tx.header; |
| 215 | u8 stream_id = sst_byt_header_str_id(header); | 215 | u8 stream_id = sst_byt_header_str_id(header); |
| 216 | u8 stream_msg = sst_byt_header_msg_id(header); | 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 | if (msg == NULL) | 240 | if (msg == NULL) |
| 241 | return 1; | 241 | return 1; |
| 242 | 242 | ||
| 243 | msg->rx.header = header; | ||
| 243 | if (header & IPC_HEADER_LARGE(true)) { | 244 | if (header & IPC_HEADER_LARGE(true)) { |
| 244 | msg->rx_size = sst_byt_header_data(header); | 245 | msg->rx.size = sst_byt_header_data(header); |
| 245 | sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size); | 246 | sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size); |
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | /* update any stream states */ | 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 | int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream) | 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_ipc_message request, reply = {0}; |
| 411 | struct sst_byt_alloc_response *reply = &stream->reply; | ||
| 412 | u64 header; | ||
| 413 | int ret; | 412 | int ret; |
| 414 | 413 | ||
| 415 | header = sst_byt_header(IPC_IA_ALLOC_STREAM, | 414 | request.header = sst_byt_header(IPC_IA_ALLOC_STREAM, |
| 416 | sizeof(*str_req) + sizeof(u32), | 415 | sizeof(stream->request) + sizeof(u32), |
| 417 | true, stream->str_id); | 416 | true, stream->str_id); |
| 418 | ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req, | 417 | request.data = &stream->request; |
| 419 | sizeof(*str_req), | 418 | request.size = sizeof(stream->request); |
| 420 | reply, sizeof(*reply)); | 419 | reply.data = &stream->reply; |
| 420 | reply.size = sizeof(stream->reply); | ||
| 421 | |||
| 422 | ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply); | ||
| 421 | if (ret < 0) { | 423 | if (ret < 0) { |
| 422 | dev_err(byt->dev, "ipc: error stream commit failed\n"); | 424 | dev_err(byt->dev, "ipc: error stream commit failed\n"); |
| 423 | return ret; | 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 | int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream) | 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 | int ret = 0; | 436 | int ret = 0; |
| 435 | struct sst_dsp *sst = byt->dsp; | 437 | struct sst_dsp *sst = byt->dsp; |
| 436 | unsigned long flags; | 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 | if (!stream->commited) | 440 | if (!stream->commited) |
| 439 | goto out; | 441 | goto out; |
| 440 | 442 | ||
| 441 | header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); | 443 | request.header = sst_byt_header(IPC_IA_FREE_STREAM, |
| 442 | ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0); | 444 | 0, false, stream->str_id); |
| 445 | ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL); | ||
| 443 | if (ret < 0) { | 446 | if (ret < 0) { |
| 444 | dev_err(byt->dev, "ipc: free stream %d failed\n", | 447 | dev_err(byt->dev, "ipc: free stream %d failed\n", |
| 445 | stream->str_id); | 448 | stream->str_id); |
| @@ -459,15 +462,13 @@ out: · 13 unmodified lines | |||
| 459 | static int sst_byt_stream_operations(struct sst_byt *byt, int type, | 462 | static int sst_byt_stream_operations(struct sst_byt *byt, int type, |
| 460 | int stream_id, int wait) | 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 | if (wait) | 468 | if (wait) |
| 466 | return sst_ipc_tx_message_wait(&byt->ipc, header, NULL, | 469 | return sst_ipc_tx_message_wait(&byt->ipc, request, NULL); |
| 467 | 0, NULL, 0); | ||
| 468 | else | 470 | else |
| 469 | return sst_ipc_tx_message_nowait(&byt->ipc, header, | 471 | return sst_ipc_tx_message_nowait(&byt->ipc, request); |
| 470 | NULL, 0); | ||
| 471 | } | 472 | } |
| 472 | 473 | ||
| 473 | /* stream ALSA trigger operations */ | 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 | u32 start_offset) | 476 | u32 start_offset) |
| 476 | { | 477 | { |
| 477 | struct sst_byt_start_stream_params start_stream; | 478 | struct sst_byt_start_stream_params start_stream; |
| 478 | void *tx_msg; | 479 | struct sst_ipc_message request; |
| 479 | size_t size; | ||
| 480 | u64 header; | ||
| 481 | int ret; | 480 | int ret; |
| 482 | 481 | ||
| 483 | start_stream.byte_offset = start_offset; | 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 | sizeof(start_stream) + sizeof(u32), | 484 | sizeof(start_stream) + sizeof(u32), |
| 486 | true, stream->str_id); | 485 | true, stream->str_id); |
| 487 | tx_msg = &start_stream; | 486 | request.data = &start_stream; |
| 488 | size = sizeof(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 | if (ret < 0) | 490 | if (ret < 0) |
| 492 | dev_err(byt->dev, "ipc: error failed to start stream %d\n", | 491 | dev_err(byt->dev, "ipc: error failed to start stream %d\n", |
| 493 | stream->str_id); | 492 | stream->str_id); |
| @@ -623,10 +622,10 @@ EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); · 129 unmodified lines | |||
| 623 | 622 | ||
| 624 | static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) | 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)) | 625 | if (msg->tx.header & IPC_HEADER_LARGE(true)) |
| 627 | sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | 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 | static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text) | 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 | size_t tx_size) | 647 | size_t tx_size) |
| 649 | { | 648 | { |
| 650 | /* msg content = lower 32-bit of the header + data */ | 649 | /* msg content = lower 32-bit of the header + data */ |
| 651 | *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1); | 650 | *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1); |
| 652 | memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size); | 651 | memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size); |
| 653 | msg->tx_size += sizeof(u32); | 652 | msg->tx.size += sizeof(u32); |
| 654 | } | 653 | } |
| 655 | 654 | ||
| 656 | static u64 byt_reply_msg_match(u64 header, u64 *mask) | 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 | endif ## SND_SOC_INTEL_SKL | 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 | if SND_SOC_INTEL_APL | 266 | if SND_SOC_INTEL_APL |
| 260 | 267 | ||
| 261 | config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH | 268 | config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH |
| 262 | tristate "Broxton with DA7219 and MAX98357A in I2S Mode" | 269 | tristate "Broxton with DA7219 and MAX98357A in I2S Mode" |
| 263 | depends on I2C && ACPI | 270 | depends on I2C && ACPI |
| 264 | depends on MFD_INTEL_LPSS || COMPILE_TEST | 271 | depends on MFD_INTEL_LPSS || COMPILE_TEST |
| 265 | select SND_SOC_DA7219 | 272 | select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC |
| 266 | select SND_SOC_MAX98357A | ||
| 267 | select SND_SOC_DMIC | ||
| 268 | select SND_SOC_HDAC_HDMI | ||
| 269 | select SND_HDA_DSP_LOADER | 273 | select SND_HDA_DSP_LOADER |
| 270 | help | 274 | help |
| 271 | This adds support for ASoC machine driver for Broxton-P platforms | 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 | tristate "KBL with DA7219 and MAX98357A in I2S Mode" | 330 | tristate "KBL with DA7219 and MAX98357A in I2S Mode" |
| 327 | depends on I2C && ACPI | 331 | depends on I2C && ACPI |
| 328 | depends on MFD_INTEL_LPSS || COMPILE_TEST | 332 | depends on MFD_INTEL_LPSS || COMPILE_TEST |
| 329 | select SND_SOC_DA7219 | 333 | select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC |
| 330 | select SND_SOC_MAX98357A | ||
| 331 | select SND_SOC_DMIC | ||
| 332 | select SND_SOC_HDAC_HDMI | ||
| 333 | help | 334 | help |
| 334 | This adds support for ASoC Onboard Codec I2S machine driver. This will | 335 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
| 335 | create an alsa sound card for DA7219 + MAX98357A I2S audio codec. | 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 | config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH | 388 | config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH |
| 388 | tristate "SKL/KBL/BXT/APL with HDA Codecs" | 389 | tristate "SKL/KBL/BXT/APL with HDA Codecs" |
| 389 | select SND_SOC_HDAC_HDMI | 390 | select SND_SOC_HDAC_HDMI |
| 391 | select SND_SOC_DMIC | ||
| 390 | # SND_SOC_HDAC_HDA is already selected | 392 | # SND_SOC_HDAC_HDA is already selected |
| 391 | help | 393 | help |
| 392 | This adds support for ASoC machine driver for Intel platforms | 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 | If unsure select "N". | 414 | If unsure select "N". |
| 413 | endif ## SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL | 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 | endif ## SND_SOC_INTEL_MACH | 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 | struct bdw_rt5677_priv *bdw_rt5677; | 341 | struct bdw_rt5677_priv *bdw_rt5677; |
| 342 | struct snd_soc_acpi_mach *mach; | 342 | struct snd_soc_acpi_mach *mach; |
| 343 | const char *platform_name = NULL; | ||
| 344 | int ret; | 343 | int ret; |
| 345 | 344 | ||
| 346 | bdw_rt5677_card.dev = &pdev->dev; | 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 | /* override plaform name, if required */ | 355 | /* override plaform name, if required */ |
| 357 | mach = (&pdev->dev)->platform_data; | 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 | ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card, | 357 | ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card, |
| 362 | platform_name); | 358 | mach->mach_params.platform); |
| 363 | if (ret) | 359 | if (ret) |
| 364 | return ret; | 360 | return ret; |
| 365 | 361 | ||
| @@ -270,18 +270,14 @@ static struct snd_soc_card broadwell_rt286 = { · 269 unmodified lines | |||
| 270 | static int broadwell_audio_probe(struct platform_device *pdev) | 270 | static int broadwell_audio_probe(struct platform_device *pdev) |
| 271 | { | 271 | { |
| 272 | struct snd_soc_acpi_mach *mach; | 272 | struct snd_soc_acpi_mach *mach; |
| 273 | const char *platform_name = NULL; | ||
| 274 | int ret; | 273 | int ret; |
| 275 | 274 | ||
| 276 | broadwell_rt286.dev = &pdev->dev; | 275 | broadwell_rt286.dev = &pdev->dev; |
| 277 | 276 | ||
| 278 | /* override plaform name, if required */ | 277 | /* override plaform name, if required */ |
| 279 | mach = (&pdev->dev)->platform_data; | 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 | ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, | 279 | ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, |
| 284 | platform_name); | 280 | mach->mach_params.platform); |
| 285 | if (ret) | 281 | if (ret) |
| 286 | return ret; | 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 | int ret; | 179 | int ret; |
| 180 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 180 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 181 | struct snd_soc_component *component = rtd->codec_dai->component; | 181 | struct snd_soc_component *component = rtd->codec_dai->component; |
| 182 | int clk_freq; | ||
| 182 | 183 | ||
| 183 | /* Configure sysclk for codec */ | 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 | SND_SOC_CLOCK_IN); | 191 | SND_SOC_CLOCK_IN); |
| 192 | |||
| 186 | if (ret) { | 193 | if (ret) { |
| 187 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); | 194 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); |
| 188 | return ret; | 195 | return ret; |
| @@ -683,6 +690,25 @@ static int broxton_audio_probe(struct platform_device *pdev) · 494 unmodified lines | |||
| 683 | broxton_dais[i].cpus->dai_name = "SSP2 Pin"; | 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 | /* override plaform name, if required */ | 714 | /* override plaform name, if required */ |
| @@ -700,6 +726,7 @@ static int broxton_audio_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 700 | static const struct platform_device_id bxt_board_ids[] = { | 726 | static const struct platform_device_id bxt_board_ids[] = { |
| 701 | { .name = "bxt_da7219_max98357a" }, | 727 | { .name = "bxt_da7219_max98357a" }, |
| 702 | { .name = "glk_da7219_max98357a" }, | 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 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); | 747 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); |
| 721 | MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); | 748 | MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); |
| 722 | MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); | 749 | MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); |
| 750 | MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); | ||
| 723 | MODULE_LICENSE("GPL v2"); | 751 | MODULE_LICENSE("GPL v2"); |
| 724 | MODULE_ALIAS("platform:bxt_da7219_max98357a"); | 752 | MODULE_ALIAS("platform:bxt_da7219_max98357a"); |
| 725 | MODULE_ALIAS("platform:glk_da7219_max98357a"); | 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 | static struct snd_soc_aux_dev cht_max98090_headset_dev = { | 326 | static struct snd_soc_aux_dev cht_max98090_headset_dev = { |
| 327 | .name = "Headset Chip", | 327 | .dlc = COMP_AUX("i2c-104C227E:00"), |
| 328 | .init = cht_max98090_headset_init, | 328 | .init = cht_max98090_headset_init, |
| 329 | .codec_name = "i2c-104C227E:00", | ||
| 330 | }; | 329 | }; |
| 331 | 330 | ||
| 332 | SND_SOC_DAILINK_DEF(dummy, | 331 | SND_SOC_DAILINK_DEF(dummy, |
| @@ -188,18 +188,14 @@ static struct snd_soc_card haswell_rt5640 = { · 187 unmodified lines | |||
| 188 | static int haswell_audio_probe(struct platform_device *pdev) | 188 | static int haswell_audio_probe(struct platform_device *pdev) |
| 189 | { | 189 | { |
| 190 | struct snd_soc_acpi_mach *mach; | 190 | struct snd_soc_acpi_mach *mach; |
| 191 | const char *platform_name = NULL; | ||
| 192 | int ret; | 191 | int ret; |
| 193 | 192 | ||
| 194 | haswell_rt5640.dev = &pdev->dev; | 193 | haswell_rt5640.dev = &pdev->dev; |
| 195 | 194 | ||
| 196 | /* override plaform name, if required */ | 195 | /* override plaform name, if required */ |
| 197 | mach = (&pdev->dev)->platform_data; | 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 | ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, | 197 | ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, |
| 202 | platform_name); | 198 | mach->mach_params.platform); |
| 203 | if (ret) | 199 | if (ret) |
| 204 | return ret; | 200 | return ret; |
| 205 | 201 | ||
| @@ -147,6 +147,11 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card) · 146 unmodified lines | |||
| 147 | if (err) | 147 | if (err) |
| 148 | return err; | 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 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, | 155 | err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, |
| 151 | &pcm->hdmi_jack); | 156 | &pcm->hdmi_jack); |
| 152 | if (err < 0) | 157 | if (err < 0) |
| @@ -23,6 +23,7 @@ static const struct snd_soc_dapm_widget skl_hda_widgets[] = { · 22 unmodified lines | |||
| 23 | SND_SOC_DAPM_MIC("Alt Analog In", NULL), | 23 | SND_SOC_DAPM_MIC("Alt Analog In", NULL), |
| 24 | SND_SOC_DAPM_SPK("Digital Out", NULL), | 24 | SND_SOC_DAPM_SPK("Digital Out", NULL), |
| 25 | SND_SOC_DAPM_MIC("Digital In", NULL), | 25 | SND_SOC_DAPM_MIC("Digital In", NULL), |
| 26 | SND_SOC_DAPM_MIC("SoC DMIC", NULL), | ||
| 26 | }; | 27 | }; |
| 27 | 28 | ||
| 28 | static const struct snd_soc_dapm_route skl_hda_map[] = { | 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 | { "Codec Input Pin2", NULL, "Digital In" }, | 42 | { "Codec Input Pin2", NULL, "Digital In" }, |
| 42 | { "Codec Input Pin3", NULL, "Alt Analog In" }, | 43 | { "Codec Input Pin3", NULL, "Alt Analog In" }, |
| 43 | 44 | ||
| 45 | /* digital mics */ | ||
| 46 | {"DMic", NULL, "SoC DMIC"}, | ||
| 47 | |||
| 44 | /* CODEC BE connections */ | 48 | /* CODEC BE connections */ |
| 45 | { "Analog Codec Playback", NULL, "Analog CPU Playback" }, | 49 | { "Analog Codec Playback", NULL, "Analog CPU Playback" }, |
| 46 | { "Analog CPU Playback", NULL, "codec0_out" }, | 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 | .callback = sof_rt5682_quirk_cb, | 92 | .callback = sof_rt5682_quirk_cb, |
| 93 | .matches = { | 93 | .matches = { |
| 94 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | 94 | DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), |
| 95 | DMI_MATCH(DMI_PRODUCT_NAME, "Hatch"), | ||
| 96 | }, | 95 | }, |
| 97 | .driver_data = (void *)(SOF_RT5682_MCLK_EN | | 96 | .driver_data = (void *)(SOF_RT5682_MCLK_EN | |
| 98 | SOF_RT5682_MCLK_24MHZ | | 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 | soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ | 8 | soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ |
| 9 | soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ | 9 | soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ |
| 10 | soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \ | 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 | soc-acpi-intel-hda-match.o | 12 | soc-acpi-intel-hda-match.o |
| 12 | 13 | ||
| 13 | obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o | 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 | .codecs = {"10EC5682"} | 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 | struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { | 27 | struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { |
| 23 | { | 28 | { |
| 24 | .id = "INT34C2", | 29 | .id = "INT34C2", |
| @@ -28,6 +33,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { · 3 unmodified lines | |||
| 28 | .sof_fw_filename = "sof-cnl.ri", | 33 | .sof_fw_filename = "sof-cnl.ri", |
| 29 | .sof_tplg_filename = "sof-cnl-rt274.tplg", | 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 | .id = "MX98357A", | 44 | .id = "MX98357A", |
| 33 | .drv_name = "sof_rt5682", | 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 | SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT); | 36 | SOC_INTEL_IS_CPU(cht, INTEL_FAM6_ATOM_AIRMONT); |
| 37 | SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT); | 37 | SOC_INTEL_IS_CPU(apl, INTEL_FAM6_ATOM_GOLDMONT); |
| 38 | SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS); | 38 | SOC_INTEL_IS_CPU(glk, INTEL_FAM6_ATOM_GOLDMONT_PLUS); |
| 39 | SOC_INTEL_IS_CPU(cml, INTEL_FAM6_KABYLAKE_MOBILE); | ||
| 39 | 40 | ||
| 40 | static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) | 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 | return false; | 111 | return false; |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 114 | static inline bool soc_intel_is_cml(void) | ||
| 115 | { | ||
| 116 | return false; | ||
| 117 | } | ||
| 113 | #endif | 118 | #endif |
| 114 | 119 | ||
| 115 | #endif /* _SND_SOC_INTEL_QUIRKS_H */ | 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 | platform_set_drvdata(pdev, sst_acpi); | 143 | platform_set_drvdata(pdev, sst_acpi); |
| 144 | mach->pdata = sst_pdata; | ||
| 144 | 145 | ||
| 145 | /* register machine driver */ | 146 | /* register machine driver */ |
| 146 | sst_acpi->pdev_mach = | 147 | sst_acpi->pdev_mach = |
| 147 | platform_device_register_data(dev, mach->drv_name, -1, | 148 | platform_device_register_data(dev, mach->drv_name, -1, |
| 148 | sst_pdata, sizeof(*sst_pdata)); | 149 | mach, sizeof(*mach)); |
| 149 | if (IS_ERR(sst_acpi->pdev_mach)) | 150 | if (IS_ERR(sst_acpi->pdev_mach)) |
| 150 | return PTR_ERR(sst_acpi->pdev_mach); | 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 | static int tx_wait_done(struct sst_generic_ipc *ipc, | 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 | unsigned long flags; | 48 | unsigned long flags; |
| 49 | int ret; | 49 | int ret; |
| @@ -62,8 +62,11 @@ static int tx_wait_done(struct sst_generic_ipc *ipc, · 12 unmodified lines | |||
| 62 | } else { | 62 | } else { |
| 63 | 63 | ||
| 64 | /* copy the data returned from DSP */ | 64 | /* copy the data returned from DSP */ |
| 65 | if (rx_data) | 65 | if (reply) { |
| 66 | memcpy(rx_data, msg->rx_data, msg->rx_size); | 66 | reply->header = msg->rx.header; |
| 67 | if (reply->data) | ||
| 68 | memcpy(reply->data, msg->rx.data, msg->rx.size); | ||
| 69 | } | ||
| 67 | ret = msg->errno; | 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 | return ret; | 75 | return ret; |
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, | 78 | static int ipc_tx_message(struct sst_generic_ipc *ipc, |
| 76 | void *tx_data, size_t tx_bytes, void *rx_data, | 79 | struct sst_ipc_message request, |
| 77 | size_t rx_bytes, int wait) | 80 | struct sst_ipc_message *reply, int wait) |
| 78 | { | 81 | { |
| 79 | struct ipc_message *msg; | 82 | struct ipc_message *msg; |
| 80 | unsigned long flags; | 83 | unsigned long flags; |
| @@ -87,23 +90,24 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header, · 6 unmodified lines | |||
| 87 | return -EBUSY; | 90 | return -EBUSY; |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | msg->header = header; | 93 | msg->tx.header = request.header; |
| 91 | msg->tx_size = tx_bytes; | 94 | msg->tx.size = request.size; |
| 92 | msg->rx_size = rx_bytes; | 95 | msg->rx.header = 0; |
| 96 | msg->rx.size = reply ? reply->size : 0; | ||
| 93 | msg->wait = wait; | 97 | msg->wait = wait; |
| 94 | msg->errno = 0; | 98 | msg->errno = 0; |
| 95 | msg->pending = false; | 99 | msg->pending = false; |
| 96 | msg->complete = false; | 100 | msg->complete = false; |
| 97 | 101 | ||
| 98 | if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL)) | 102 | if ((request.size) && (ipc->ops.tx_data_copy != NULL)) |
| 99 | ipc->ops.tx_data_copy(msg, tx_data, tx_bytes); | 103 | ipc->ops.tx_data_copy(msg, request.data, request.size); |
| 100 | 104 | ||
| 101 | list_add_tail(&msg->list, &ipc->tx_list); | 105 | list_add_tail(&msg->list, &ipc->tx_list); |
| 102 | schedule_work(&ipc->kwork); | 106 | schedule_work(&ipc->kwork); |
| 103 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); | 107 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); |
| 104 | 108 | ||
| 105 | if (wait) | 109 | if (wait) |
| 106 | return tx_wait_done(ipc, msg, rx_data); | 110 | return tx_wait_done(ipc, msg, reply); |
| 107 | else | 111 | else |
| 108 | return 0; | 112 | return 0; |
| 109 | } | 113 | } |
| @@ -118,13 +122,13 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) · 8 unmodified lines | |||
| 118 | return -ENOMEM; | 122 | return -ENOMEM; |
| 119 | 123 | ||
| 120 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { | 124 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { |
| 121 | ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); | 125 | ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); |
| 122 | if (ipc->msg[i].tx_data == NULL) | 126 | if (ipc->msg[i].tx.data == NULL) |
| 123 | goto free_mem; | 127 | goto free_mem; |
| 124 | 128 | ||
| 125 | ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); | 129 | ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); |
| 126 | if (ipc->msg[i].rx_data == NULL) { | 130 | if (ipc->msg[i].rx.data == NULL) { |
| 127 | kfree(ipc->msg[i].tx_data); | 131 | kfree(ipc->msg[i].tx.data); |
| 128 | goto free_mem; | 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 | free_mem: | 141 | free_mem: |
| 138 | while (i > 0) { | 142 | while (i > 0) { |
| 139 | kfree(ipc->msg[i-1].tx_data); | 143 | kfree(ipc->msg[i-1].tx.data); |
| 140 | kfree(ipc->msg[i-1].rx_data); | 144 | kfree(ipc->msg[i-1].rx.data); |
| 141 | --i; | 145 | --i; |
| 142 | } | 146 | } |
| 143 | kfree(ipc->msg); | 147 | kfree(ipc->msg); |
| @@ -173,8 +177,8 @@ static void ipc_tx_msgs(struct work_struct *work) · 29 unmodified lines | |||
| 173 | spin_unlock_irq(&ipc->dsp->spinlock); | 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, | 180 | int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, |
| 177 | void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) | 181 | struct sst_ipc_message request, struct sst_ipc_message *reply) |
| 178 | { | 182 | { |
| 179 | int ret; | 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 | if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) | 191 | if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) |
| 188 | return -EIO; | 192 | return -EIO; |
| 189 | 193 | ||
| 190 | ret = ipc_tx_message(ipc, header, tx_data, tx_bytes, | 194 | ret = ipc_tx_message(ipc, request, reply, 1); |
| 191 | rx_data, rx_bytes, 1); | ||
| 192 | 195 | ||
| 193 | if (ipc->ops.check_dsp_lp_on) | 196 | if (ipc->ops.check_dsp_lp_on) |
| 194 | if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) | 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 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); | 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, | 204 | int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, |
| 202 | void *tx_data, size_t tx_bytes) | 205 | struct sst_ipc_message request) |
| 203 | { | 206 | { |
| 204 | return ipc_tx_message(ipc, header, tx_data, tx_bytes, | 207 | return ipc_tx_message(ipc, request, NULL, 0); |
| 205 | NULL, 0, 0); | ||
| 206 | } | 208 | } |
| 207 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); | 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, | 211 | int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, |
| 210 | void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes) | 212 | struct sst_ipc_message request, struct sst_ipc_message *reply) |
| 211 | { | 213 | { |
| 212 | return ipc_tx_message(ipc, header, tx_data, tx_bytes, | 214 | return ipc_tx_message(ipc, request, reply, 1); |
| 213 | rx_data, rx_bytes, 1); | ||
| 214 | } | 215 | } |
| 215 | EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); | 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 | list_for_each_entry(msg, &ipc->rx_list, list) { | 235 | list_for_each_entry(msg, &ipc->rx_list, list) { |
| 235 | if ((msg->header & mask) == header) | 236 | if ((msg->tx.header & mask) == header) |
| 236 | return msg; | 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 | if (ipc->msg) { | 308 | if (ipc->msg) { |
| 308 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { | 309 | for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { |
| 309 | kfree(ipc->msg[i].tx_data); | 310 | kfree(ipc->msg[i].tx.data); |
| 310 | kfree(ipc->msg[i].rx_data); | 311 | kfree(ipc->msg[i].rx.data); |
| 311 | } | 312 | } |
| 312 | kfree(ipc->msg); | 313 | kfree(ipc->msg); |
| 313 | } | 314 | } |
| @@ -17,15 +17,16 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define IPC_MAX_MAILBOX_BYTES 256 | 18 | #define IPC_MAX_MAILBOX_BYTES 256 |
| 19 | 19 | ||
| 20 | struct ipc_message { | 20 | struct sst_ipc_message { |
| 21 | struct list_head list; | ||
| 22 | u64 header; | 21 | u64 header; |
| 22 | void *data; | ||
| 23 | size_t size; | ||
| 24 | }; | ||
| 23 | 25 | ||
| 24 | /* direction wrt host CPU */ | 26 | struct ipc_message { |
| 25 | char *tx_data; | 27 | struct list_head list; |
| 26 | size_t tx_size; | 28 | struct sst_ipc_message tx; |
| 27 | char *rx_data; | 29 | struct sst_ipc_message rx; |
| 28 | size_t rx_size; | ||
| 29 | 30 | ||
| 30 | wait_queue_head_t waitq; | 31 | wait_queue_head_t waitq; |
| 31 | bool pending; | 32 | bool pending; |
| @@ -35,6 +36,7 @@ struct ipc_message { · 3 unmodified lines | |||
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | struct sst_generic_ipc; | 38 | struct sst_generic_ipc; |
| 39 | struct sst_dsp; | ||
| 38 | 40 | ||
| 39 | struct sst_plat_ipc_ops { | 41 | struct sst_plat_ipc_ops { |
| 40 | void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); | 42 | void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); |
| @@ -65,14 +67,14 @@ struct sst_generic_ipc { · 24 unmodified lines | |||
| 65 | struct sst_plat_ipc_ops ops; | 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, | 70 | int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, |
| 69 | void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); | 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, | 73 | int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, |
| 72 | void *tx_data, size_t tx_bytes); | 74 | struct sst_ipc_message request); |
| 73 | 75 | ||
| 74 | int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header, | 76 | int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, |
| 75 | void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes); | 77 | struct sst_ipc_message request, struct sst_ipc_message *reply); |
| 76 | 78 | ||
| 77 | struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, | 79 | struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, |
| 78 | u64 header); | 80 | u64 header); |
| @@ -511,7 +511,7 @@ static void hsw_notification_work(struct work_struct *work) · 510 unmodified lines | |||
| 511 | static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) | 511 | static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) |
| 512 | { | 512 | { |
| 513 | struct sst_hsw_stream *stream; | 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 | u32 stream_id = msg_get_stream_id(header); | 515 | u32 stream_id = msg_get_stream_id(header); |
| 516 | u32 stream_msg = msg_get_stream_type(header); | 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 | return -EIO; | 552 | return -EIO; |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | msg->rx.header = header; | ||
| 555 | /* first process the header */ | 556 | /* first process the header */ |
| 556 | switch (reply) { | 557 | switch (reply) { |
| 557 | case IPC_GLB_REPLY_PENDING: | 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 | case IPC_GLB_REPLY_SUCCESS: | 563 | case IPC_GLB_REPLY_SUCCESS: |
| 563 | if (msg->pending) { | 564 | if (msg->pending) { |
| 564 | trace_ipc_pending_reply("completed", header); | 565 | trace_ipc_pending_reply("completed", header); |
| 565 | sst_dsp_inbox_read(hsw->dsp, msg->rx_data, | 566 | sst_dsp_inbox_read(hsw->dsp, msg->rx.data, |
| 566 | msg->rx_size); | 567 | msg->rx.size); |
| 567 | hsw->ipc.pending = false; | 568 | hsw->ipc.pending = false; |
| 568 | } else { | 569 | } else { |
| 569 | /* copy data from the DSP */ | 570 | /* copy data from the DSP */ |
| 570 | sst_dsp_outbox_read(hsw->dsp, msg->rx_data, | 571 | sst_dsp_outbox_read(hsw->dsp, msg->rx.data, |
| 571 | msg->rx_size); | 572 | msg->rx.size); |
| 572 | } | 573 | } |
| 573 | break; | 574 | break; |
| 574 | /* these will be rare - but useful for debug */ | 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 | int sst_hsw_fw_get_version(struct sst_hsw *hsw, | 811 | int sst_hsw_fw_get_version(struct sst_hsw *hsw, |
| 811 | struct sst_hsw_ipc_fw_version *version) | 812 | struct sst_hsw_ipc_fw_version *version) |
| 812 | { | 813 | { |
| 814 | struct sst_ipc_message request = {0}, reply = {0}; | ||
| 813 | int ret; | 815 | int ret; |
| 814 | 816 | ||
| 815 | ret = sst_ipc_tx_message_wait(&hsw->ipc, | 817 | request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION); |
| 816 | IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), | 818 | reply.data = version; |
| 817 | NULL, 0, version, sizeof(*version)); | 819 | reply.size = sizeof(*version); |
| 820 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); | ||
| 818 | if (ret < 0) | 821 | if (ret < 0) |
| 819 | dev_err(hsw->dev, "error: get version failed\n"); | 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 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) | 843 | struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) |
| 841 | { | 844 | { |
| 842 | struct sst_hsw_ipc_volume_req *req; | 845 | struct sst_hsw_ipc_volume_req *req; |
| 843 | u32 header; | 846 | struct sst_ipc_message request; |
| 844 | int ret; | 847 | int ret; |
| 845 | 848 | ||
| 846 | trace_ipc_request("set stream volume", stream->reply.stream_hw_id); | 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 | if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) | 851 | if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL) |
| 849 | return -EINVAL; | 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 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); | 855 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); |
| 853 | header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); | 856 | request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT); |
| 854 | header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | 857 | request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); |
| 855 | header |= (stage_id << IPC_STG_ID_SHIFT); | 858 | request.header |= (stage_id << IPC_STG_ID_SHIFT); |
| 856 | 859 | ||
| 857 | req = &stream->vol_req; | 860 | req = &stream->vol_req; |
| 858 | req->target_volume = volume; | 861 | req->target_volume = volume; |
| @@ -877,8 +880,9 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw, · 18 unmodified lines | |||
| 877 | req->channel = channel; | 880 | req->channel = channel; |
| 878 | } | 881 | } |
| 879 | 882 | ||
| 880 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req, | 883 | request.data = req; |
| 881 | sizeof(*req), NULL, 0); | 884 | request.size = sizeof(*req); |
| 885 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | ||
| 882 | if (ret < 0) { | 886 | if (ret < 0) { |
| 883 | dev_err(hsw->dev, "error: set stream volume failed\n"); | 887 | dev_err(hsw->dev, "error: set stream volume failed\n"); |
| 884 | return ret; | 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 | u32 volume) | 909 | u32 volume) |
| 906 | { | 910 | { |
| 907 | struct sst_hsw_ipc_volume_req req; | 911 | struct sst_hsw_ipc_volume_req req; |
| 908 | u32 header; | 912 | struct sst_ipc_message request; |
| 909 | int ret; | 913 | int ret; |
| 910 | 914 | ||
| 911 | trace_ipc_request("set mixer volume", volume); | 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 | req.channel = channel; | 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 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); | 941 | IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE); |
| 938 | header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); | 942 | request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT); |
| 939 | header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); | 943 | request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT); |
| 940 | header |= (stage_id << IPC_STG_ID_SHIFT); | 944 | request.header |= (stage_id << IPC_STG_ID_SHIFT); |
| 941 | 945 | ||
| 942 | req.curve_duration = hsw->curve_duration; | 946 | req.curve_duration = hsw->curve_duration; |
| 943 | req.curve_type = hsw->curve_type; | 947 | req.curve_type = hsw->curve_type; |
| 944 | req.target_volume = volume; | 948 | req.target_volume = volume; |
| 945 | 949 | ||
| 946 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req, | 950 | request.data = &req; |
| 947 | sizeof(req), NULL, 0); | 951 | request.size = sizeof(req); |
| 952 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | ||
| 948 | if (ret < 0) { | 953 | if (ret < 0) { |
| 949 | dev_err(hsw->dev, "error: set mixer volume failed\n"); | 954 | dev_err(hsw->dev, "error: set mixer volume failed\n"); |
| 950 | return ret; | 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 | int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | 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 | int ret = 0; | 992 | int ret = 0; |
| 988 | struct sst_dsp *sst = hsw->dsp; | 993 | struct sst_dsp *sst = hsw->dsp; |
| 989 | unsigned long flags; | 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 | trace_ipc_request("stream free", stream->host_id); | 1005 | trace_ipc_request("stream free", stream->host_id); |
| 1001 | 1006 | ||
| 1002 | stream->free_req.stream_id = stream->reply.stream_hw_id; | 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, | 1012 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); |
| 1006 | sizeof(stream->free_req), NULL, 0); | ||
| 1007 | if (ret < 0) { | 1013 | if (ret < 0) { |
| 1008 | dev_err(hsw->dev, "error: free stream %d failed\n", | 1014 | dev_err(hsw->dev, "error: free stream %d failed\n", |
| 1009 | stream->free_req.stream_id); | 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 | int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream) | 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; | 1184 | struct sst_ipc_message request, reply = {0}; |
| 1179 | struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply; | ||
| 1180 | u32 header; | ||
| 1181 | int ret; | 1185 | int ret; |
| 1182 | 1186 | ||
| 1183 | if (!stream) { | 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 | trace_ipc_request("stream alloc", stream->host_id); | 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, | 1205 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); |
| 1198 | sizeof(*str_req), reply, sizeof(*reply)); | ||
| 1199 | if (ret < 0) { | 1206 | if (ret < 0) { |
| 1200 | dev_err(hsw->dev, "error: stream commit failed\n"); | 1207 | dev_err(hsw->dev, "error: stream commit failed\n"); |
| 1201 | return ret; | 1208 | return ret; |
| @@ -1235,23 +1242,22 @@ void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw, · 33 unmodified lines | |||
| 1235 | ABI to be opaque to client PCM drivers to cope with any future ABI changes */ | 1242 | ABI to be opaque to client PCM drivers to cope with any future ABI changes */ |
| 1236 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw) | 1243 | int sst_hsw_mixer_get_info(struct sst_hsw *hsw) |
| 1237 | { | 1244 | { |
| 1238 | struct sst_hsw_ipc_stream_info_reply *reply; | 1245 | struct sst_ipc_message request = {0}, reply = {0}; |
| 1239 | u32 header; | ||
| 1240 | int ret; | 1246 | int ret; |
| 1241 | 1247 | ||
| 1242 | reply = &hsw->mixer_info; | 1248 | request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO); |
| 1243 | 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 | trace_ipc_request("get global mixer info", 0); | 1252 | trace_ipc_request("get global mixer info", 0); |
| 1246 | 1253 | ||
| 1247 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, | 1254 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); |
| 1248 | reply, sizeof(*reply)); | ||
| 1249 | if (ret < 0) { | 1255 | if (ret < 0) { |
| 1250 | dev_err(hsw->dev, "error: get stream info failed\n"); | 1256 | dev_err(hsw->dev, "error: get stream info failed\n"); |
| 1251 | return ret; | 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 | return 0; | 1262 | return 0; |
| 1257 | } | 1263 | } |
| @@ -1260,16 +1266,15 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw) · 2 unmodified lines | |||
| 1260 | static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type, | 1266 | static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type, |
| 1261 | int stream_id, int wait) | 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); | 1271 | request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE); |
| 1266 | header |= (stream_id << IPC_STR_ID_SHIFT); | 1272 | request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT); |
| 1267 | 1273 | ||
| 1268 | if (wait) | 1274 | if (wait) |
| 1269 | return sst_ipc_tx_message_wait(&hsw->ipc, header, | 1275 | return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); |
| 1270 | NULL, 0, NULL, 0); | ||
| 1271 | else | 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 | /* Stream ALSA trigger operations */ | 1280 | /* Stream ALSA trigger operations */ |
| @@ -1377,8 +1382,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw, · 101 unmodified lines | |||
| 1377 | enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, | 1382 | enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, |
| 1378 | enum sst_hsw_device_mode mode, u32 clock_divider) | 1383 | enum sst_hsw_device_mode mode, u32 clock_divider) |
| 1379 | { | 1384 | { |
| 1385 | struct sst_ipc_message request; | ||
| 1380 | struct sst_hsw_ipc_device_config_req config; | 1386 | struct sst_hsw_ipc_device_config_req config; |
| 1381 | u32 header; | ||
| 1382 | int ret; | 1387 | int ret; |
| 1383 | 1388 | ||
| 1384 | trace_ipc_request("set device config", dev); | 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 | trace_hsw_device_config_req(&config); | 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, | 1406 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); |
| 1400 | sizeof(config), NULL, 0); | ||
| 1401 | if (ret < 0) | 1407 | if (ret < 0) |
| 1402 | dev_err(hsw->dev, "error: set device formats failed\n"); | 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 | int sst_hsw_dx_set_state(struct sst_hsw *hsw, | 1415 | int sst_hsw_dx_set_state(struct sst_hsw *hsw, |
| 1410 | enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx) | 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 | int ret, item; | 1420 | int ret, item; |
| 1414 | 1421 | ||
| 1415 | header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE); | ||
| 1416 | state_ = state; | 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 | trace_ipc_request("PM enter Dx state", state); | 1429 | trace_ipc_request("PM enter Dx state", state); |
| 1419 | 1430 | ||
| 1420 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_, | 1431 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply); |
| 1421 | sizeof(state_), dx, sizeof(*dx)); | ||
| 1422 | if (ret < 0) { | 1432 | if (ret < 0) { |
| 1423 | dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); | 1433 | dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); |
| 1424 | return ret; | 1434 | return ret; |
| @@ -1878,7 +1888,7 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, · 453 unmodified lines | |||
| 1878 | u32 module_id, u32 instance_id) | 1888 | u32 module_id, u32 instance_id) |
| 1879 | { | 1889 | { |
| 1880 | int ret; | 1890 | int ret; |
| 1881 | u32 header = 0; | 1891 | struct sst_ipc_message request; |
| 1882 | struct sst_hsw_ipc_module_config config; | 1892 | struct sst_hsw_ipc_module_config config; |
| 1883 | struct sst_module *module; | 1893 | struct sst_module *module; |
| 1884 | struct sst_module_runtime *runtime; | 1894 | struct sst_module_runtime *runtime; |
| @@ -1907,10 +1917,10 @@ int sst_hsw_module_enable(struct sst_hsw *hsw, · 22 unmodified lines | |||
| 1907 | return -ENXIO; | 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 | IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) | | 1921 | IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) | |
| 1912 | IPC_MODULE_ID(module_id); | 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 | config.map.module_entries_count = 1; | 1925 | config.map.module_entries_count = 1; |
| 1916 | config.map.module_entries[0].module_id = module->id; | 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 | config.scratch_mem.size, config.scratch_mem.offset, | 1942 | config.scratch_mem.size, config.scratch_mem.offset, |
| 1933 | config.map.module_entries[0].entry_point); | 1943 | config.map.module_entries[0].entry_point); |
| 1934 | 1944 | ||
| 1935 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, | 1945 | request.data = &config; |
| 1936 | &config, sizeof(config), NULL, 0); | 1946 | request.size = sizeof(config); |
| 1947 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); | ||
| 1937 | if (ret < 0) | 1948 | if (ret < 0) |
| 1938 | dev_err(dev, "ipc: module enable failed - %d\n", ret); | 1949 | dev_err(dev, "ipc: module enable failed - %d\n", ret); |
| 1939 | else | 1950 | else |
| @@ -1946,7 +1957,7 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, · 6 unmodified lines | |||
| 1946 | u32 module_id, u32 instance_id) | 1957 | u32 module_id, u32 instance_id) |
| 1947 | { | 1958 | { |
| 1948 | int ret; | 1959 | int ret; |
| 1949 | u32 header; | 1960 | struct sst_ipc_message request = {0}; |
| 1950 | struct sst_module *module; | 1961 | struct sst_module *module; |
| 1951 | struct device *dev = hsw->dev; | 1962 | struct device *dev = hsw->dev; |
| 1952 | struct sst_dsp *dsp = hsw->dsp; | 1963 | struct sst_dsp *dsp = hsw->dsp; |
| @@ -1967,11 +1978,11 @@ int sst_hsw_module_disable(struct sst_hsw *hsw, · 14 unmodified lines | |||
| 1967 | return -ENXIO; | 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 | IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) | | 1982 | IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) | |
| 1972 | IPC_MODULE_ID(module_id); | 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 | if (ret < 0) | 1986 | if (ret < 0) |
| 1976 | dev_err(dev, "module disable failed - %d\n", ret); | 1987 | dev_err(dev, "module disable failed - %d\n", ret); |
| 1977 | else | 1988 | else |
| @@ -1985,15 +1996,16 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw, · 7 unmodified lines | |||
| 1985 | u32 param_size, char *param) | 1996 | u32 param_size, char *param) |
| 1986 | { | 1997 | { |
| 1987 | int ret; | 1998 | int ret; |
| 1988 | u32 header = 0; | 1999 | struct sst_ipc_message request = {0}; |
| 1989 | u32 payload_size = 0, transfer_parameter_size = 0; | 2000 | u32 payload_size = 0; |
| 1990 | struct sst_hsw_transfer_parameter *parameter; | 2001 | struct sst_hsw_transfer_parameter *parameter; |
| 1991 | struct device *dev = hsw->dev; | 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 | IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) | | 2005 | IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) | |
| 1995 | IPC_MODULE_ID(module_id); | 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 | payload_size = param_size + | 2010 | payload_size = param_size + |
| 1999 | sizeof(struct sst_hsw_transfer_parameter) - | 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 | if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) { | 2016 | if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) { |
| 2005 | /* short parameter, mailbox can contain data */ | 2017 | /* short parameter, mailbox can contain data */ |
| 2006 | dev_dbg(dev, "transfer parameter size : %d\n", | 2018 | dev_dbg(dev, "transfer parameter size : %zu\n", |
| 2007 | transfer_parameter_size); | 2019 | request.size); |
| 2008 | 2020 | ||
| 2009 | transfer_parameter_size = ALIGN(payload_size, 4); | 2021 | request.size = ALIGN(payload_size, 4); |
| 2010 | dev_dbg(dev, "transfer parameter aligned size : %d\n", | 2022 | dev_dbg(dev, "transfer parameter aligned size : %zu\n", |
| 2011 | transfer_parameter_size); | 2023 | request.size); |
| 2012 | 2024 | ||
| 2013 | parameter = kzalloc(transfer_parameter_size, GFP_KERNEL); | 2025 | parameter = kzalloc(request.size, GFP_KERNEL); |
| 2014 | if (parameter == NULL) | 2026 | if (parameter == NULL) |
| 2015 | return -ENOMEM; | 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 | parameter->parameter_id = parameter_id; | 2035 | parameter->parameter_id = parameter_id; |
| 2024 | parameter->data_size = param_size; | 2036 | parameter->data_size = param_size; |
| 2037 | request.data = parameter; | ||
| 2025 | 2038 | ||
| 2026 | ret = sst_ipc_tx_message_wait(&hsw->ipc, header, | 2039 | ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL); |
| 2027 | parameter, transfer_parameter_size , NULL, 0); | ||
| 2028 | if (ret < 0) | 2040 | if (ret < 0) |
| 2029 | dev_err(dev, "ipc: module set parameter failed - %d\n", ret); | 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 | static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) | 2053 | static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) |
| 2042 | { | 2054 | { |
| 2043 | /* send the message */ | 2055 | /* send the message */ |
| 2044 | sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | 2056 | sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); |
| 2045 | sst_dsp_ipc_msg_tx(ipc->dsp, msg->header); | 2057 | sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header); |
| 2046 | } | 2058 | } |
| 2047 | 2059 | ||
| 2048 | static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text) | 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 | static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data, | 2075 | static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data, |
| 2064 | size_t tx_size) | 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 | static u64 hsw_reply_msg_match(u64 header, u64 *mask) | 2081 | static u64 hsw_reply_msg_match(u64 header, u64 *mask) |
| @@ -1,6 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \ | 2 | snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o skl-topology.o \ |
| 3 | 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 | ifdef CONFIG_DEBUG_FS | 6 | ifdef CONFIG_DEBUG_FS |
| 6 | snd-soc-skl-objs += skl-debug.o | 7 | snd-soc-skl-objs += skl-debug.o |
| @@ -8,13 +9,6 @@ endif · 1 unmodified line | |||
| 8 | 9 | ||
| 9 | obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o | 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 | #Skylake Clock device support | 12 | #Skylake Clock device support |
| 19 | snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o | 13 | snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o |
| 20 | 14 | ||
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include "../common/sst-dsp.h" | 15 | #include "../common/sst-dsp.h" |
| 16 | #include "../common/sst-dsp-priv.h" | 16 | #include "../common/sst-dsp-priv.h" |
| 17 | #include "skl-sst-ipc.h" | 17 | #include "skl.h" |
| 18 | 18 | ||
| 19 | #define BXT_BASEFW_TIMEOUT 3000 | 19 | #define BXT_BASEFW_TIMEOUT 3000 |
| 20 | #define BXT_INIT_TIMEOUT 300 | 20 | #define BXT_INIT_TIMEOUT 300 |
| @@ -49,7 +49,7 @@ static int · 28 unmodified lines | |||
| 49 | bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) | 49 | bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) |
| 50 | { | 50 | { |
| 51 | struct snd_dma_buffer dmab; | 51 | struct snd_dma_buffer dmab; |
| 52 | struct skl_sst *skl = ctx->thread_context; | 52 | struct skl_dev *skl = ctx->thread_context; |
| 53 | struct firmware stripped_fw; | 53 | struct firmware stripped_fw; |
| 54 | int ret = 0, i, dma_id, stream_tag; | 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 | static int bxt_load_base_firmware(struct sst_dsp *ctx) | 184 | static int bxt_load_base_firmware(struct sst_dsp *ctx) |
| 185 | { | 185 | { |
| 186 | struct firmware stripped_fw; | 186 | struct firmware stripped_fw; |
| 187 | struct skl_sst *skl = ctx->thread_context; | 187 | struct skl_dev *skl = ctx->thread_context; |
| 188 | int ret, i; | 188 | int ret, i; |
| 189 | 189 | ||
| 190 | if (ctx->fw == NULL) { | 190 | if (ctx->fw == NULL) { |
| @@ -268,7 +268,7 @@ sst_load_base_firmware_failed: · 77 unmodified lines | |||
| 268 | */ | 268 | */ |
| 269 | static int bxt_d0i3_target_state(struct sst_dsp *ctx) | 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 | struct skl_d0i3_data *d0i3 = &skl->d0i3; | 272 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 273 | 273 | ||
| 274 | if (skl->cores.state[SKL_DSP_CORE0_ID] != SKL_DSP_RUNNING) | 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 | int ret; | 289 | int ret; |
| 290 | struct skl_ipc_d0ix_msg msg; | 290 | struct skl_ipc_d0ix_msg msg; |
| 291 | struct skl_sst *skl = container_of(work, | 291 | struct skl_dev *skl = container_of(work, |
| 292 | struct skl_sst, d0i3.work.work); | 292 | struct skl_dev, d0i3.work.work); |
| 293 | struct sst_dsp *ctx = skl->dsp; | 293 | struct sst_dsp *ctx = skl->dsp; |
| 294 | struct skl_d0i3_data *d0i3 = &skl->d0i3; | 294 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 295 | int target_state; | 295 | int target_state; |
| @@ -331,7 +331,7 @@ static void bxt_set_dsp_D0i3(struct work_struct *work) · 35 unmodified lines | |||
| 331 | 331 | ||
| 332 | static int bxt_schedule_dsp_D0i3(struct sst_dsp *ctx) | 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 | struct skl_d0i3_data *d0i3 = &skl->d0i3; | 335 | struct skl_d0i3_data *d0i3 = &skl->d0i3; |
| 336 | 336 | ||
| 337 | /* Schedule D0i3 only if the usecase ref counts are appropriate */ | 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 | int ret; | 351 | int ret; |
| 352 | struct skl_ipc_d0ix_msg msg; | 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 | dev_dbg(ctx->dev, "In %s:\n", __func__); | 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 | static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) | 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 | int ret; | 393 | int ret; |
| 394 | struct skl_ipc_dxstate_info dx; | 394 | struct skl_ipc_dxstate_info dx; |
| 395 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 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 | int ret; | 487 | int ret; |
| 488 | struct skl_ipc_dxstate_info dx; | 488 | struct skl_ipc_dxstate_info dx; |
| 489 | struct skl_sst *skl = ctx->thread_context; | 489 | struct skl_dev *skl = ctx->thread_context; |
| 490 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 490 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 491 | 491 | ||
| 492 | dx.core_mask = core_mask; | 492 | dx.core_mask = core_mask; |
| @@ -548,9 +548,9 @@ static struct sst_dsp_device skl_dev = { · 55 unmodified lines | |||
| 548 | 548 | ||
| 549 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 549 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 550 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 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 | struct sst_dsp *sst; | 554 | struct sst_dsp *sst; |
| 555 | int ret; | 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 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | 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 | int ret; | 596 | int ret; |
| 597 | struct sst_dsp *sst = ctx->dsp; | 597 | struct sst_dsp *sst = skl->dsp; |
| 598 | 598 | ||
| 599 | ret = sst->fw_ops.load_fw(sst); | 599 | ret = sst->fw_ops.load_fw(sst); |
| 600 | if (ret < 0) { | 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 | skl_dsp_init_core_state(sst); | 605 | skl_dsp_init_core_state(sst); |
| 606 | 606 | ||
| 607 | if (ctx->lib_count > 1) { | 607 | if (skl->lib_count > 1) { |
| 608 | ret = sst->fw_ops.load_library(sst, ctx->lib_info, | 608 | ret = sst->fw_ops.load_library(sst, skl->lib_info, |
| 609 | ctx->lib_count); | 609 | skl->lib_count); |
| 610 | if (ret < 0) { | 610 | if (ret < 0) { |
| 611 | dev_err(dev, "Load Library failed : %x\n", ret); | 611 | dev_err(dev, "Load Library failed : %x\n", ret); |
| 612 | return ret; | 612 | return ret; |
| 613 | } | 613 | } |
| 614 | } | 614 | } |
| 615 | ctx->is_first_boot = false; | 615 | skl->is_first_boot = false; |
| 616 | 616 | ||
| 617 | return 0; | 617 | return 0; |
| 618 | } | 618 | } |
| 619 | EXPORT_SYMBOL_GPL(bxt_sst_init_fw); | 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); | 624 | skl_release_library(skl->lib_info, skl->lib_count); |
| 625 | if (ctx->dsp->fw) | 625 | if (skl->dsp->fw) |
| 626 | release_firmware(ctx->dsp->fw); | 626 | release_firmware(skl->dsp->fw); |
| 627 | skl_freeup_uuid_list(ctx); | 627 | skl_freeup_uuid_list(skl); |
| 628 | skl_ipc_free(&ctx->ipc); | 628 | skl_ipc_free(&skl->ipc); |
| 629 | ctx->dsp->ops->free(ctx->dsp); | 629 | skl->dsp->ops->free(skl->dsp); |
| 630 | } | 630 | } |
| 631 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); | 631 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); |
| 632 | 632 | ||
| @@ -9,7 +9,6 @@ · 8 unmodified lines | |||
| 9 | #define __CNL_SST_DSP_H__ | 9 | #define __CNL_SST_DSP_H__ |
| 10 | 10 | ||
| 11 | struct sst_dsp; | 11 | struct sst_dsp; |
| 12 | struct skl_sst; | ||
| 13 | struct sst_dsp_device; | 12 | struct sst_dsp_device; |
| 14 | struct sst_generic_ipc; | 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 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 97 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 99 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 98 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 100 | struct skl_sst **dsp); | 99 | struct skl_dev **dsp); |
| 101 | int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | 100 | int cnl_sst_init_fw(struct device *dev, struct skl_dev *skl); |
| 102 | void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 101 | void cnl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); |
| 103 | 102 | ||
| 104 | #endif /*__CNL_SST_DSP_H__*/ | 103 | #endif /*__CNL_SST_DSP_H__*/ |
| @@ -24,8 +24,7 @@ · 23 unmodified lines | |||
| 24 | #include "../common/sst-dsp-priv.h" | 24 | #include "../common/sst-dsp-priv.h" |
| 25 | #include "../common/sst-ipc.h" | 25 | #include "../common/sst-ipc.h" |
| 26 | #include "cnl-sst-dsp.h" | 26 | #include "cnl-sst-dsp.h" |
| 27 | #include "skl-sst-dsp.h" | 27 | #include "skl.h" |
| 28 | #include "skl-sst-ipc.h" | ||
| 29 | 28 | ||
| 30 | #define CNL_FW_ROM_INIT 0x1 | 29 | #define CNL_FW_ROM_INIT 0x1 |
| 31 | #define CNL_FW_INIT 0x5 | 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 | static int cnl_load_base_firmware(struct sst_dsp *ctx) | 108 | static int cnl_load_base_firmware(struct sst_dsp *ctx) |
| 110 | { | 109 | { |
| 111 | struct firmware stripped_fw; | 110 | struct firmware stripped_fw; |
| 112 | struct skl_sst *cnl = ctx->thread_context; | 111 | struct skl_dev *cnl = ctx->thread_context; |
| 113 | int ret; | 112 | int ret; |
| 114 | 113 | ||
| 115 | if (!ctx->fw) { | 114 | if (!ctx->fw) { |
| @@ -167,7 +166,7 @@ cnl_load_base_firmware_failed: · 51 unmodified lines | |||
| 167 | 166 | ||
| 168 | static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) | 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 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 170 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 172 | struct skl_ipc_dxstate_info dx; | 171 | struct skl_ipc_dxstate_info dx; |
| 173 | int ret; | 172 | int ret; |
| @@ -229,7 +228,7 @@ err: · 55 unmodified lines | |||
| 229 | 228 | ||
| 230 | static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) | 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 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 232 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 234 | struct skl_ipc_dxstate_info dx; | 233 | struct skl_ipc_dxstate_info dx; |
| 235 | int ret; | 234 | int ret; |
| @@ -293,7 +292,7 @@ static struct sst_ops cnl_ops = { · 57 unmodified lines | |||
| 293 | static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) | 292 | static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) |
| 294 | { | 293 | { |
| 295 | struct sst_dsp *dsp = context; | 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 | struct sst_generic_ipc *ipc = &cnl->ipc; | 296 | struct sst_generic_ipc *ipc = &cnl->ipc; |
| 298 | struct skl_ipc_header header = {0}; | 297 | struct skl_ipc_header header = {0}; |
| 299 | u32 hipcida, hipctdr, hipctdd; | 298 | u32 hipcida, hipctdr, hipctdd; |
| @@ -367,10 +366,10 @@ static struct sst_dsp_device cnl_dev = { · 67 unmodified lines | |||
| 367 | 366 | ||
| 368 | static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) | 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) | 371 | if (msg->tx.size) |
| 373 | sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | 372 | sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); |
| 374 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, | 373 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, |
| 375 | header->extension); | 374 | header->extension); |
| 376 | sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, | 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 | return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); | 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 | struct sst_generic_ipc *ipc; | 390 | struct sst_generic_ipc *ipc; |
| 392 | int err; | 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 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 415 | int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 417 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 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 | struct sst_dsp *sst; | 420 | struct sst_dsp *sst; |
| 422 | int ret; | 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 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); | 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 | int ret; | 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 | if (ret < 0) { | 462 | if (ret < 0) { |
| 464 | dev_err(dev, "load base fw failed: %d", ret); | 463 | dev_err(dev, "load base fw failed: %d", ret); |
| 465 | return ret; | 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 | skl_dsp_init_core_state(sst); | 467 | skl_dsp_init_core_state(sst); |
| 469 | 468 | ||
| 470 | ctx->is_first_boot = false; | 469 | skl->is_first_boot = false; |
| 471 | 470 | ||
| 472 | return 0; | 471 | return 0; |
| 473 | } | 472 | } |
| 474 | EXPORT_SYMBOL_GPL(cnl_sst_init_fw); | 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) | 477 | if (skl->dsp->fw) |
| 479 | release_firmware(ctx->dsp->fw); | 478 | release_firmware(skl->dsp->fw); |
| 480 | 479 | ||
| 481 | skl_freeup_uuid_list(ctx); | 480 | skl_freeup_uuid_list(skl); |
| 482 | cnl_ipc_free(&ctx->ipc); | 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 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); | 485 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); |
| 487 | 486 | ||
| @@ -20,7 +20,7 @@ · 19 unmodified lines | |||
| 20 | #define FW_REG_SIZE 0x60 | 20 | #define FW_REG_SIZE 0x60 |
| 21 | 21 | ||
| 22 | struct skl_debug { | 22 | struct skl_debug { |
| 23 | struct skl *skl; | 23 | struct skl_dev *skl; |
| 24 | struct device *dev; | 24 | struct device *dev; |
| 25 | 25 | ||
| 26 | struct dentry *fs; | 26 | struct dentry *fs; |
| @@ -66,6 +66,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf, · 39 unmodified lines | |||
| 66 | size_t count, loff_t *ppos) | 66 | size_t count, loff_t *ppos) |
| 67 | { | 67 | { |
| 68 | struct skl_module_cfg *mconfig = file->private_data; | 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 | char *buf; | 71 | char *buf; |
| 70 | ssize_t ret; | 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 | mconfig->id.pvt_id); | 81 | mconfig->id.pvt_id); |
| 80 | 82 | ||
| 81 | ret += snprintf(buf + ret, MOD_BUF - ret, | 83 | ret += snprintf(buf + ret, MOD_BUF - ret, |
| 82 | "Resources:\n\tMCPS %#x\n\tIBS %#x\n\tOBS %#x\t\n", | 84 | "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n", |
| 83 | mconfig->mcps, mconfig->ibs, mconfig->obs); | 85 | res->cpc, res->ibs, res->obs); |
| 84 | 86 | ||
| 85 | ret += snprintf(buf + ret, MOD_BUF - ret, | 87 | ret += snprintf(buf + ret, MOD_BUF - ret, |
| 86 | "Module data:\n\tCore %d\n\tIn queue %d\n\t" | 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 | struct snd_soc_dapm_widget *w, | 164 | struct snd_soc_dapm_widget *w, |
| 163 | struct skl_module_cfg *mconfig) | 165 | struct skl_module_cfg *mconfig) |
| 164 | { | 166 | { |
| 165 | if (!debugfs_create_file(w->name, 0444, | 167 | debugfs_create_file(w->name, 0444, d->modules, mconfig, |
| 166 | d->modules, mconfig, | 168 | &mcfg_fops); |
| 167 | &mcfg_fops)) | ||
| 168 | dev_err(d->dev, "%s: module debugfs init failed\n", w->name); | ||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, | 171 | static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, |
| 172 | size_t count, loff_t *ppos) | 172 | size_t count, loff_t *ppos) |
| 173 | { | 173 | { |
| 174 | struct skl_debug *d = file->private_data; | 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 | size_t w0_stat_sz = sst->addr.w0_stat_sz; | 176 | size_t w0_stat_sz = sst->addr.w0_stat_sz; |
| 177 | void __iomem *in_base = sst->mailbox.in_base; | 177 | void __iomem *in_base = sst->mailbox.in_base; |
| 178 | void __iomem *fw_reg_addr; | 178 | void __iomem *fw_reg_addr; |
| @@ -213,7 +213,7 @@ static const struct file_operations soft_regs_ctrl_fops = { · 34 unmodified lines | |||
| 213 | .llseek = default_llseek, | 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 | struct skl_debug *d; | 218 | struct skl_debug *d; |
| 219 | 219 | ||
| @@ -222,37 +222,21 @@ struct skl_debug *skl_debugfs_init(struct skl *skl) · 2 unmodified lines | |||
| 222 | return NULL; | 222 | return NULL; |
| 223 | 223 | ||
| 224 | /* create the debugfs dir with platform component's debugfs as parent */ | 224 | /* create the debugfs dir with platform component's debugfs as parent */ |
| 225 | d->fs = debugfs_create_dir("dsp", | 225 | d->fs = debugfs_create_dir("dsp", skl->component->debugfs_root); |
| 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 | } | ||
| 231 | 226 | ||
| 232 | d->skl = skl; | 227 | d->skl = skl; |
| 233 | d->dev = &skl->pci->dev; | 228 | d->dev = &skl->pci->dev; |
| 234 | 229 | ||
| 235 | /* now create the module dir */ | 230 | /* now create the module dir */ |
| 236 | d->modules = debugfs_create_dir("modules", d->fs); | 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, | 233 | debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d, |
| 243 | &soft_regs_ctrl_fops)) { | 234 | &soft_regs_ctrl_fops); |
| 244 | dev_err(d->dev, "fw soft regs control debugfs init failed\n"); | ||
| 245 | goto err; | ||
| 246 | } | ||
| 247 | 235 | ||
| 248 | return d; | 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 | struct skl_debug *d = skl->debugfs; | 241 | struct skl_debug *d = skl->debugfs; |
| 258 | 242 | ||
| @@ -25,29 +25,18 @@ · 24 unmodified lines | |||
| 25 | static int skl_alloc_dma_buf(struct device *dev, | 25 | static int skl_alloc_dma_buf(struct device *dev, |
| 26 | struct snd_dma_buffer *dmab, size_t size) | 26 | struct snd_dma_buffer *dmab, size_t size) |
| 27 | { | 27 | { |
| 28 | struct hdac_bus *bus = dev_get_drvdata(dev); | 28 | return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab); |
| 29 | |||
| 30 | if (!bus) | ||
| 31 | return -ENODEV; | ||
| 32 | |||
| 33 | return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab); | ||
| 34 | } | 29 | } |
| 35 | 30 | ||
| 36 | static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) | 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); | 33 | snd_dma_free_pages(dmab); |
| 39 | |||
| 40 | if (!bus) | ||
| 41 | return -ENODEV; | ||
| 42 | |||
| 43 | bus->io_ops->dma_free_pages(bus, dmab); | ||
| 44 | |||
| 45 | return 0; | 34 | return 0; |
| 46 | } | 35 | } |
| 47 | 36 | ||
| 48 | #define SKL_ASTATE_PARAM_ID 4 | 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 | struct skl_ipc_large_config_msg msg = {0}; | 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 | msg.param_data_size = (cnt * sizeof(struct skl_astate_param) + | 44 | msg.param_data_size = (cnt * sizeof(struct skl_astate_param) + |
| 56 | sizeof(cnt)); | 45 | sizeof(cnt)); |
| 57 | 46 | ||
| 58 | skl_ipc_set_large_config(&ctx->ipc, &msg, data); | 47 | skl_ipc_set_large_config(&skl->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); | ||
| 77 | } | 48 | } |
| 78 | 49 | ||
| 79 | static int skl_dsp_setup_spib(struct device *dev, unsigned int size, | 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 | return NULL; | 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 | void __iomem *mmio_base; | 253 | void __iomem *mmio_base; |
| 283 | struct hdac_bus *bus = skl_to_bus(skl); | 254 | struct hdac_bus *bus = skl_to_bus(skl); |
| @@ -307,13 +278,13 @@ int skl_init_dsp(struct skl *skl) · 23 unmodified lines | |||
| 307 | loader_ops = ops->loader_ops(); | 278 | loader_ops = ops->loader_ops(); |
| 308 | ret = ops->init(bus->dev, mmio_base, irq, | 279 | ret = ops->init(bus->dev, mmio_base, irq, |
| 309 | skl->fw_name, loader_ops, | 280 | skl->fw_name, loader_ops, |
| 310 | &skl->skl_sst); | 281 | &skl); |
| 311 | 282 | ||
| 312 | if (ret < 0) | 283 | if (ret < 0) |
| 313 | goto unmap_mmio; | 284 | goto unmap_mmio; |
| 314 | 285 | ||
| 315 | skl->skl_sst->dsp_ops = ops; | 286 | skl->dsp_ops = ops; |
| 316 | cores = &skl->skl_sst->cores; | 287 | cores = &skl->cores; |
| 317 | cores->count = ops->num_cores; | 288 | cores->count = ops->num_cores; |
| 318 | 289 | ||
| 319 | cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); | 290 | cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); |
| @@ -342,21 +313,20 @@ unmap_mmio: · 22 unmodified lines | |||
| 342 | return ret; | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 318 | struct hdac_bus *bus = skl_to_bus(skl); |
| 348 | struct skl_sst *ctx = skl->skl_sst; | ||
| 349 | 319 | ||
| 350 | /* disable ppcap interrupt */ | 320 | /* disable ppcap interrupt */ |
| 351 | snd_hdac_ext_bus_ppcap_int_enable(bus, false); | 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); | 325 | kfree(skl->cores.state); |
| 356 | kfree(ctx->cores.usage_count); | 326 | kfree(skl->cores.usage_count); |
| 357 | 327 | ||
| 358 | if (ctx->dsp->addr.lpe) | 328 | if (skl->dsp->addr.lpe) |
| 359 | iounmap(ctx->dsp->addr.lpe); | 329 | iounmap(skl->dsp->addr.lpe); |
| 360 | 330 | ||
| 361 | return 0; | 331 | return 0; |
| 362 | } | 332 | } |
| @@ -368,15 +338,14 @@ int skl_free_dsp(struct skl *skl) · 5 unmodified lines | |||
| 368 | * mode during system suspend. In the case of normal suspend, cancel | 338 | * mode during system suspend. In the case of normal suspend, cancel |
| 369 | * any pending D0i3 work. | 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 | struct delayed_work *dwork; | 343 | struct delayed_work *dwork; |
| 375 | 344 | ||
| 376 | if (!ctx) | 345 | if (!skl) |
| 377 | return 0; | 346 | return 0; |
| 378 | 347 | ||
| 379 | dwork = &ctx->d0i3.work; | 348 | dwork = &skl->d0i3.work; |
| 380 | 349 | ||
| 381 | if (dwork->work.func) { | 350 | if (dwork->work.func) { |
| 382 | if (skl->supend_active) | 351 | if (skl->supend_active) |
| @@ -388,9 +357,8 @@ int skl_suspend_late_dsp(struct skl *skl) · 5 unmodified lines | |||
| 388 | return 0; | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 362 | struct hdac_bus *bus = skl_to_bus(skl); |
| 395 | int ret; | 363 | int ret; |
| 396 | 364 | ||
| @@ -398,7 +366,7 @@ int skl_suspend_dsp(struct skl *skl) · 1 unmodified line | |||
| 398 | if (!bus->ppcap) | 366 | if (!bus->ppcap) |
| 399 | return 0; | 367 | return 0; |
| 400 | 368 | ||
| 401 | ret = skl_dsp_sleep(ctx->dsp); | 369 | ret = skl_dsp_sleep(skl->dsp); |
| 402 | if (ret < 0) | 370 | if (ret < 0) |
| 403 | return ret; | 371 | return ret; |
| 404 | 372 | ||
| @@ -409,9 +377,8 @@ int skl_suspend_dsp(struct skl *skl) · 4 unmodified lines | |||
| 409 | return 0; | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 382 | struct hdac_bus *bus = skl_to_bus(skl); |
| 416 | int ret; | 383 | int ret; |
| 417 | 384 | ||
| @@ -424,26 +391,24 @@ int skl_resume_dsp(struct skl *skl) · 6 unmodified lines | |||
| 424 | snd_hdac_ext_bus_ppcap_int_enable(bus, true); | 391 | snd_hdac_ext_bus_ppcap_int_enable(bus, true); |
| 425 | 392 | ||
| 426 | /* check if DSP 1st boot is done */ | 393 | /* check if DSP 1st boot is done */ |
| 427 | if (skl->skl_sst->is_first_boot) | 394 | if (skl->is_first_boot) |
| 428 | return 0; | 395 | return 0; |
| 429 | 396 | ||
| 430 | /* | 397 | /* |
| 431 | * Disable dynamic clock and power gating during firmware | 398 | * Disable dynamic clock and power gating during firmware |
| 432 | * and library download | 399 | * and library download |
| 433 | */ | 400 | */ |
| 434 | ctx->enable_miscbdcge(ctx->dev, false); | 401 | skl->enable_miscbdcge(skl->dev, false); |
| 435 | ctx->clock_power_gating(ctx->dev, false); | 402 | skl->clock_power_gating(skl->dev, false); |
| 436 | 403 | ||
| 437 | ret = skl_dsp_wake(ctx->dsp); | 404 | ret = skl_dsp_wake(skl->dsp); |
| 438 | ctx->enable_miscbdcge(ctx->dev, true); | 405 | skl->enable_miscbdcge(skl->dev, true); |
| 439 | ctx->clock_power_gating(ctx->dev, true); | 406 | skl->clock_power_gating(skl->dev, true); |
| 440 | if (ret < 0) | 407 | if (ret < 0) |
| 441 | return ret; | 408 | return ret; |
| 442 | 409 | ||
| 443 | skl_dsp_enable_notification(skl->skl_sst, false); | ||
| 444 | |||
| 445 | if (skl->cfg.astate_cfg != NULL) { | 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 | skl->cfg.astate_cfg); | 412 | skl->cfg.astate_cfg); |
| 448 | } | 413 | } |
| 449 | return ret; | 414 | return ret; |
| @@ -476,7 +441,7 @@ enum skl_bitdepth skl_get_bit_depth(int params) · 26 unmodified lines | |||
| 476 | * which are read from widget information passed through topology binary | 441 | * which are read from widget information passed through topology binary |
| 477 | * This is send when we create a module with INIT_INSTANCE IPC msg | 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 | struct skl_module_cfg *mconfig, | 445 | struct skl_module_cfg *mconfig, |
| 481 | struct skl_base_cfg *base_cfg) | 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 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; | 458 | base_cfg->audio_fmt.ch_cfg = format->ch_cfg; |
| 494 | base_cfg->audio_fmt.sample_type = format->sample_type; | 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 | format->bit_depth, format->valid_bit_depth, | 462 | format->bit_depth, format->valid_bit_depth, |
| 498 | format->ch_cfg); | 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 | base_cfg->audio_fmt.interleaving = format->interleaving_style; | 467 | base_cfg->audio_fmt.interleaving = format->interleaving_style; |
| 503 | 468 | ||
| 504 | base_cfg->cps = res->cps; | 469 | base_cfg->cpc = res->cpc; |
| 505 | base_cfg->ibs = res->ibs; | 470 | base_cfg->ibs = res->ibs; |
| 506 | base_cfg->obs = res->obs; | 471 | base_cfg->obs = res->obs; |
| 507 | base_cfg->is_pages = res->is_pages; | 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 | * Calculate the gatewat settings required for copier module, type of | 495 | * Calculate the gatewat settings required for copier module, type of |
| 531 | * gateway and index of gateway to use | 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 | struct skl_module_cfg *mconfig) | 499 | struct skl_module_cfg *mconfig) |
| 535 | { | 500 | { |
| 536 | union skl_connector_node_id node_id = {0}; | 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 | return node_id.val; | 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 | struct skl_module_cfg *mconfig, | 556 | struct skl_module_cfg *mconfig, |
| 592 | struct skl_cpr_cfg *cpr_mconfig) | 557 | struct skl_cpr_cfg *cpr_mconfig) |
| 593 | { | 558 | { |
| 594 | u32 dma_io_buf; | 559 | u32 dma_io_buf; |
| 595 | struct skl_module_res *res; | 560 | struct skl_module_res *res; |
| 596 | int res_idx = mconfig->res_idx; | 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 | if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { | 565 | if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { |
| 602 | cpr_mconfig->cpr_feature_mask = 0; | 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 | break; | 591 | break; |
| 628 | 592 | ||
| 629 | default: | 593 | default: |
| 630 | dev_warn(ctx->dev, "wrong connection type: %d\n", | 594 | dev_warn(skl->dev, "wrong connection type: %d\n", |
| 631 | mconfig->hw_conn_type); | 595 | mconfig->hw_conn_type); |
| 632 | return; | 596 | return; |
| 633 | } | 597 | } |
| @@ -653,7 +617,7 @@ skip_buf_size_calc: · 19 unmodified lines | |||
| 653 | #define DMA_CONTROL_ID 5 | 617 | #define DMA_CONTROL_ID 5 |
| 654 | #define DMA_I2S_BLOB_SIZE 21 | 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 | u32 caps_size, u32 node_id) | 621 | u32 caps_size, u32 node_id) |
| 658 | { | 622 | { |
| 659 | struct skl_dma_control *dma_ctrl; | 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 | memcpy(dma_ctrl->config_data, caps, caps_size); | 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 | kfree(dma_ctrl); | 655 | kfree(dma_ctrl); |
| 692 | return err; | 656 | return err; |
| 693 | } | 657 | } |
| 694 | EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control); | 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 | struct skl_module_cfg *mconfig, | 661 | struct skl_module_cfg *mconfig, |
| 698 | struct skl_audio_data_format *out_fmt) | 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 | out_fmt->interleaving = format->interleaving_style; | 675 | out_fmt->interleaving = format->interleaving_style; |
| 712 | out_fmt->sample_type = format->sample_type; | 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 | out_fmt->number_of_channels, format->s_freq, format->bit_depth); | 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 | * configuration and the target frequency as extra parameter passed as src | 684 | * configuration and the target frequency as extra parameter passed as src |
| 721 | * config | 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 | struct skl_module_cfg *mconfig, | 688 | struct skl_module_cfg *mconfig, |
| 725 | struct skl_src_module_cfg *src_mconfig) | 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 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; | 692 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; |
| 729 | struct skl_module_fmt *fmt = &iface->outputs[0].fmt; | 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 | (struct skl_base_cfg *)src_mconfig); | 696 | (struct skl_base_cfg *)src_mconfig); |
| 733 | 697 | ||
| 734 | src_mconfig->src_cfg = fmt->s_freq; | 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 | * module configuration and channel configuration | 703 | * module configuration and channel configuration |
| 740 | * It also take coefficients and now we have defaults applied here | 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 | struct skl_module_cfg *mconfig, | 707 | struct skl_module_cfg *mconfig, |
| 744 | struct skl_up_down_mixer_cfg *mixer_mconfig) | 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 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; | 711 | struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; |
| 748 | struct skl_module_fmt *fmt = &iface->outputs[0].fmt; | 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 | (struct skl_base_cfg *)mixer_mconfig); | 715 | (struct skl_base_cfg *)mixer_mconfig); |
| 752 | mixer_mconfig->out_ch_cfg = fmt->ch_cfg; | 716 | mixer_mconfig->out_ch_cfg = fmt->ch_cfg; |
| 753 | mixer_mconfig->ch_map = fmt->ch_map; | 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 | * format, gateway settings | 724 | * format, gateway settings |
| 761 | * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg | 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 | struct skl_module_cfg *mconfig, | 728 | struct skl_module_cfg *mconfig, |
| 765 | struct skl_cpr_cfg *cpr_mconfig) | 729 | struct skl_cpr_cfg *cpr_mconfig) |
| 766 | { | 730 | { |
| 767 | struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; | 731 | struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; |
| 768 | struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig; | 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); | 736 | skl_setup_out_format(skl, mconfig, out_fmt); |
| 773 | skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); | 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 | * configuration and params | 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 | struct skl_module_cfg *mconfig, | 746 | struct skl_module_cfg *mconfig, |
| 783 | struct skl_algo_cfg *algo_mcfg) | 747 | struct skl_algo_cfg *algo_mcfg) |
| 784 | { | 748 | { |
| 785 | struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; | 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 | if (mconfig->formats_config.caps_size == 0) | 753 | if (mconfig->formats_config.caps_size == 0) |
| 790 | return; | 754 | return; |
| @@ -802,7 +766,7 @@ static void skl_set_algo_format(struct skl_sst *ctx, · 11 unmodified lines | |||
| 802 | * Mic select module take base module configuration and out-format | 766 | * Mic select module take base module configuration and out-format |
| 803 | * configuration | 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 | struct skl_module_cfg *mconfig, | 770 | struct skl_module_cfg *mconfig, |
| 807 | struct skl_base_outfmt_cfg *base_outfmt_mcfg) | 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 | struct skl_base_cfg *base_cfg = | 774 | struct skl_base_cfg *base_cfg = |
| 811 | (struct skl_base_cfg *)base_outfmt_mcfg; | 775 | (struct skl_base_cfg *)base_outfmt_mcfg; |
| 812 | 776 | ||
| 813 | skl_set_base_module_format(ctx, mconfig, base_cfg); | 777 | skl_set_base_module_format(skl, mconfig, base_cfg); |
| 814 | skl_setup_out_format(ctx, mconfig, out_fmt); | 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 | struct skl_module_cfg *mconfig) | 782 | struct skl_module_cfg *mconfig) |
| 819 | { | 783 | { |
| 820 | u16 param_size; | 784 | u16 param_size; |
| @@ -859,14 +823,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx, · 38 unmodified lines | |||
| 859 | * base module format configuration | 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 | struct skl_module_cfg *module_config, | 827 | struct skl_module_cfg *module_config, |
| 864 | u16 *module_config_size, | 828 | u16 *module_config_size, |
| 865 | void **param_data) | 829 | void **param_data) |
| 866 | { | 830 | { |
| 867 | u16 param_size; | 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 | *param_data = kzalloc(param_size, GFP_KERNEL); | 835 | *param_data = kzalloc(param_size, GFP_KERNEL); |
| 872 | if (NULL == *param_data) | 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 | switch (module_config->m_type) { | 841 | switch (module_config->m_type) { |
| 878 | case SKL_MODULE_TYPE_COPIER: | 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 | break; | 844 | break; |
| 881 | 845 | ||
| 882 | case SKL_MODULE_TYPE_SRCINT: | 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 | break; | 848 | break; |
| 885 | 849 | ||
| 886 | case SKL_MODULE_TYPE_UPDWMIX: | 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 | break; | 852 | break; |
| 889 | 853 | ||
| 890 | case SKL_MODULE_TYPE_ALGO: | 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 | break; | 856 | break; |
| 893 | 857 | ||
| 894 | case SKL_MODULE_TYPE_BASE_OUTFMT: | 858 | case SKL_MODULE_TYPE_BASE_OUTFMT: |
| 895 | case SKL_MODULE_TYPE_MIC_SELECT: | 859 | case SKL_MODULE_TYPE_MIC_SELECT: |
| 896 | case SKL_MODULE_TYPE_KPB: | 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 | break; | 862 | break; |
| 899 | 863 | ||
| 900 | default: | 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 | break; | 866 | break; |
| 903 | 867 | ||
| 904 | } | 868 | } |
| 905 | 869 | ||
| 906 | dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", | 870 | dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n", |
| 907 | module_config->id.module_id, param_size); | 871 | module_config->m_type, module_config->id.module_id, |
| 872 | param_size); | ||
| 908 | print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, | 873 | print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, |
| 909 | *param_data, param_size, false); | 874 | *param_data, param_size, false); |
| 910 | return 0; | 875 | return 0; |
| @@ -1004,7 +969,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max, · 93 unmodified lines | |||
| 1004 | * We first calculate the module format, based on module type and then | 969 | * We first calculate the module format, based on module type and then |
| 1005 | * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper | 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 | struct skl_module_cfg *mconfig) | 973 | struct skl_module_cfg *mconfig) |
| 1009 | { | 974 | { |
| 1010 | u16 module_config_size = 0; | 975 | u16 module_config_size = 0; |
| @@ -1012,19 +977,19 @@ int skl_init_module(struct skl_sst *ctx, · 1 unmodified line | |||
| 1012 | int ret; | 977 | int ret; |
| 1013 | struct skl_ipc_init_instance_msg msg; | 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 | mconfig->id.module_id, mconfig->id.pvt_id); | 981 | mconfig->id.module_id, mconfig->id.pvt_id); |
| 1017 | 982 | ||
| 1018 | if (mconfig->pipe->state != SKL_PIPE_CREATED) { | 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 | mconfig->pipe->state, mconfig->pipe->ppl_id); | 985 | mconfig->pipe->state, mconfig->pipe->ppl_id); |
| 1021 | return -EIO; | 986 | return -EIO; |
| 1022 | } | 987 | } |
| 1023 | 988 | ||
| 1024 | ret = skl_set_module_format(ctx, mconfig, | 989 | ret = skl_set_module_format(skl, mconfig, |
| 1025 | &module_config_size, ¶m_data); | 990 | &module_config_size, ¶m_data); |
| 1026 | if (ret < 0) { | 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 | return ret; | 993 | return ret; |
| 1029 | } | 994 | } |
| 1030 | 995 | ||
| @@ -1035,9 +1000,9 @@ int skl_init_module(struct skl_sst *ctx, · 4 unmodified lines | |||
| 1035 | msg.core_id = mconfig->core_id; | 1000 | msg.core_id = mconfig->core_id; |
| 1036 | msg.domain = mconfig->domain; | 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 | if (ret < 0) { | 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 | kfree(param_data); | 1006 | kfree(param_data); |
| 1042 | return ret; | 1007 | return ret; |
| 1043 | } | 1008 | } |
| @@ -1046,15 +1011,15 @@ int skl_init_module(struct skl_sst *ctx, · 2 unmodified lines | |||
| 1046 | return ret; | 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 | *src_module, struct skl_module_cfg *dst_module) | 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 | __func__, src_module->id.module_id, src_module->id.pvt_id); | 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 | dst_module->id.module_id, dst_module->id.pvt_id); | 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 | src_module->m_state, dst_module->m_state); | 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 | * it is already bind. | 1028 | * it is already bind. |
| 1064 | * Find the pin allocated and unbind then using bind_unbind IPC | 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 | struct skl_module_cfg *src_mcfg, | 1032 | struct skl_module_cfg *src_mcfg, |
| 1068 | struct skl_module_cfg *dst_mcfg) | 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 | int out_max = src_mcfg->module->max_output_pins; | 1040 | int out_max = src_mcfg->module->max_output_pins; |
| 1076 | int src_index, dst_index, src_pin_state, dst_pin_state; | 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 | /* get src queue index */ | 1045 | /* get src queue index */ |
| 1081 | src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); | 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 | msg.dst_instance_id = dst_mcfg->id.pvt_id; | 1069 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
| 1105 | msg.bind = false; | 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 | if (!ret) { | 1073 | if (!ret) { |
| 1109 | /* free queue only if unbind is success */ | 1074 | /* free queue only if unbind is success */ |
| 1110 | skl_free_queue(src_mcfg->m_out_pin, src_index); | 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 | * This function finds the pins and then sends bund_unbind IPC message to | 1107 | * This function finds the pins and then sends bund_unbind IPC message to |
| 1143 | * DSP using IPC helper | 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 | struct skl_module_cfg *src_mcfg, | 1111 | struct skl_module_cfg *src_mcfg, |
| 1147 | struct skl_module_cfg *dst_mcfg) | 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 | struct skl_module *module; | 1121 | struct skl_module *module; |
| 1157 | struct skl_module_iface *fmt; | 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 | if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || | 1126 | if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || |
| 1162 | dst_mcfg->m_state < SKL_MODULE_INIT_DONE) | 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 | format = &fmt->outputs[src_index].fmt; | 1154 | format = &fmt->outputs[src_index].fmt; |
| 1190 | fill_pin_params(&(pin_fmt.dst_fmt), format); | 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 | sizeof(struct skl_cpr_pin_fmt), | 1157 | sizeof(struct skl_cpr_pin_fmt), |
| 1193 | CPR_SINK_FMT_PARAM_ID, src_mcfg); | 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 | msg.dst_queue = dst_index; | 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 | msg.src_queue, msg.dst_queue); | 1167 | msg.src_queue, msg.dst_queue); |
| 1203 | 1168 | ||
| 1204 | msg.module_id = src_mcfg->id.module_id; | 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 | msg.dst_instance_id = dst_mcfg->id.pvt_id; | 1172 | msg.dst_instance_id = dst_mcfg->id.pvt_id; |
| 1208 | msg.bind = true; | 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 | if (!ret) { | 1177 | if (!ret) { |
| 1213 | src_mcfg->m_state = SKL_MODULE_BIND_DONE; | 1178 | src_mcfg->m_state = SKL_MODULE_BIND_DONE; |
| @@ -1223,12 +1188,12 @@ out: · 9 unmodified lines | |||
| 1223 | return ret; | 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 | enum skl_ipc_pipeline_state state) | 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 | * This function creates pipeline, by sending create pipeline IPC messages | 1202 | * This function creates pipeline, by sending create pipeline IPC messages |
| 1238 | * to FW | 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 | int ret; | 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 | pipe->pipe_priority, pipe->ppl_id, | 1212 | pipe->pipe_priority, pipe->ppl_id, |
| 1248 | pipe->lp_mode); | 1213 | pipe->lp_mode); |
| 1249 | if (ret < 0) { | 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 | return ret; | 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 | * reset state. Finish the procedure by sending delete pipeline IPC. | 1227 | * reset state. Finish the procedure by sending delete pipeline IPC. |
| 1263 | * DSP will stop the DMA engines and release resources | 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 | int ret; | 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 | /* If pipe was not created in FW, do not try to delete it */ | 1236 | /* If pipe was not created in FW, do not try to delete it */ |
| 1272 | if (pipe->state < SKL_PIPE_CREATED) | 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 | /* If pipe is started, do stop the pipe in FW. */ | 1240 | /* If pipe is started, do stop the pipe in FW. */ |
| 1276 | if (pipe->state >= SKL_PIPE_STARTED) { | 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 | if (ret < 0) { | 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 | return ret; | 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 | /* reset pipe state before deletion */ | 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 | if (ret < 0) { | 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 | return ret; | 1255 | return ret; |
| 1291 | } | 1256 | } |
| 1292 | 1257 | ||
| 1293 | pipe->state = SKL_PIPE_RESET; | 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 | if (ret < 0) { | 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 | return ret; | 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 | * For processing data the pipe need to be run by sending IPC set pipe state | 1273 | * For processing data the pipe need to be run by sending IPC set pipe state |
| 1309 | * to DSP | 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 | int ret; | 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 | /* If pipe was not created in FW, do not try to pause or delete */ | 1282 | /* If pipe was not created in FW, do not try to pause or delete */ |
| 1318 | if (pipe->state < SKL_PIPE_CREATED) | 1283 | if (pipe->state < SKL_PIPE_CREATED) |
| 1319 | return 0; | 1284 | return 0; |
| 1320 | 1285 | ||
| 1321 | /* Pipe has to be paused before it is started */ | 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 | if (ret < 0) { | 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 | return ret; | 1290 | return ret; |
| 1326 | } | 1291 | } |
| 1327 | 1292 | ||
| 1328 | pipe->state = SKL_PIPE_PAUSED; | 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 | if (ret < 0) { | 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 | return ret; | 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 | * Stop the pipeline by sending set pipe state IPC | 1307 | * Stop the pipeline by sending set pipe state IPC |
| 1343 | * DSP doesnt implement stop so we always send pause message | 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 | int ret; | 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 | /* If pipe was not created in FW, do not try to pause or delete */ | 1316 | /* If pipe was not created in FW, do not try to pause or delete */ |
| 1352 | if (pipe->state < SKL_PIPE_PAUSED) | 1317 | if (pipe->state < SKL_PIPE_PAUSED) |
| 1353 | return 0; | 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 | if (ret < 0) { | 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 | return ret; | 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 | * Reset the pipeline by sending set pipe state IPC this will reset the DMA | 1332 | * Reset the pipeline by sending set pipe state IPC this will reset the DMA |
| 1368 | * from the DSP side | 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 | int ret; | 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 | if (pipe->state < SKL_PIPE_PAUSED) | 1340 | if (pipe->state < SKL_PIPE_PAUSED) |
| 1376 | return 0; | 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 | if (ret < 0) { | 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 | return ret; | 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 | /* Algo parameter set helper function */ | 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 | u32 param_id, struct skl_module_cfg *mcfg) | 1356 | u32 param_id, struct skl_module_cfg *mcfg) |
| 1392 | { | 1357 | { |
| 1393 | struct skl_ipc_large_config_msg msg; | 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 | msg.param_data_size = size; | 1362 | msg.param_data_size = size; |
| 1398 | msg.large_param_id = param_id; | 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 | u32 param_id, struct skl_module_cfg *mcfg) | 1369 | u32 param_id, struct skl_module_cfg *mcfg) |
| 1405 | { | 1370 | { |
| 1406 | struct skl_ipc_large_config_msg msg; | 1371 | struct skl_ipc_large_config_msg msg; |
| 1372 | size_t bytes = size; | ||
| 1407 | 1373 | ||
| 1408 | msg.module_id = mcfg->id.module_id; | 1374 | msg.module_id = mcfg->id.module_id; |
| 1409 | msg.instance_id = mcfg->id.pvt_id; | 1375 | msg.instance_id = mcfg->id.pvt_id; |
| 1410 | msg.param_data_size = size; | 1376 | msg.param_data_size = size; |
| 1411 | msg.large_param_id = param_id; | 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 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
| 12 | #include <sound/intel-nhlt.h> | ||
| 12 | #include "skl.h" | 13 | #include "skl.h" |
| 13 | #include "skl-i2s.h" | 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 | static struct nhlt_specific_cfg *skl_get_specific_cfg( | 16 | static struct nhlt_specific_cfg *skl_get_specific_cfg( |
| 64 | struct device *dev, struct nhlt_fmt *fmt, | 17 | struct device *dev, struct nhlt_fmt *fmt, |
| 65 | u8 no_ch, u32 rate, u16 bps, u8 linktype) | 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 | struct nhlt_specific_cfg | 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 | u8 s_fmt, u8 num_ch, u32 s_rate, | 83 | u8 s_fmt, u8 num_ch, u32 s_rate, |
| 131 | u8 dirn, u8 dev_type) | 84 | u8 dirn, u8 dev_type) |
| 132 | { | 85 | { |
| @@ -162,48 +115,6 @@ struct nhlt_specific_cfg · 29 unmodified lines | |||
| 162 | return NULL; | 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 | static void skl_nhlt_trim_space(char *trim) | 118 | static void skl_nhlt_trim_space(char *trim) |
| 208 | { | 119 | { |
| 209 | char *s = trim; | 120 | char *s = trim; |
| @@ -219,7 +130,7 @@ static void skl_nhlt_trim_space(char *trim) · 9 unmodified lines | |||
| 219 | s[cnt] = '\0'; | 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 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | 135 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 225 | struct hdac_bus *bus = skl_to_bus(skl); | 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 | struct pci_dev *pci = to_pci_dev(dev); | 155 | struct pci_dev *pci = to_pci_dev(dev); |
| 245 | struct hdac_bus *bus = pci_get_drvdata(pci); | 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 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | 158 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 248 | char platform_id[32]; | 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 | static DEVICE_ATTR(platform_id, 0444, skl_nhlt_platform_id_show, NULL); | 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 | struct device *dev = &skl->pci->dev; | 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 | return 0; | 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 | struct device *dev = &skl->pci->dev; | 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 | * stores all possible rates supported in a rate table for the corresponding | 190 | * stores all possible rates supported in a rate table for the corresponding |
| 280 | * sclk/sclkfs. | 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 | struct nhlt_fmt *fmt, u8 id) | 194 | struct nhlt_fmt *fmt, u8 id) |
| 284 | { | 195 | { |
| 285 | struct skl_i2s_config_blob_ext *i2s_config_ext; | 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 | struct nhlt_fmt *fmt, u8 id) | 292 | struct nhlt_fmt *fmt, u8 id) |
| 382 | { | 293 | { |
| 383 | struct skl_i2s_config_blob_ext *i2s_config_ext; | 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 | mclk[id].parent_name = parent->name; | 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 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | 337 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; |
| 427 | struct nhlt_endpoint *epnt; | 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 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); | 117 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 118 | struct snd_soc_dapm_widget *w; | 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 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 121 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 122 | w = dai->playback_widget; | 122 | w = dai->playback_widget; |
| @@ -132,7 +132,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, · 9 unmodified lines | |||
| 132 | int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) | 132 | int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) |
| 133 | { | 133 | { |
| 134 | struct hdac_bus *bus = dev_get_drvdata(dev); | 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 | unsigned int format_val; | 136 | unsigned int format_val; |
| 137 | struct hdac_stream *hstream; | 137 | struct hdac_stream *hstream; |
| 138 | struct hdac_ext_stream *stream; | 138 | struct hdac_ext_stream *stream; |
| @@ -224,7 +224,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream, · 85 unmodified lines | |||
| 224 | struct hdac_ext_stream *stream; | 224 | struct hdac_ext_stream *stream; |
| 225 | struct snd_pcm_runtime *runtime = substream->runtime; | 225 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 226 | struct skl_dma_params *dma_params; | 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 | struct skl_module_cfg *mconfig; | 228 | struct skl_module_cfg *mconfig; |
| 229 | 229 | ||
| 230 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); | 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 | static int skl_pcm_prepare(struct snd_pcm_substream *substream, | 271 | static int skl_pcm_prepare(struct snd_pcm_substream *substream, |
| 272 | struct snd_soc_dai *dai) | 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 | struct skl_module_cfg *mconfig; | 275 | struct skl_module_cfg *mconfig; |
| 276 | int ret; | 276 | int ret; |
| 277 | 277 | ||
| @@ -288,7 +288,7 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream, · 10 unmodified lines | |||
| 288 | mconfig->pipe->state == SKL_PIPE_CREATED || | 288 | mconfig->pipe->state == SKL_PIPE_CREATED || |
| 289 | mconfig->pipe->state == SKL_PIPE_PAUSED)) { | 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 | if (ret < 0) | 293 | if (ret < 0) |
| 294 | return ret; | 294 | return ret; |
| @@ -350,7 +350,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream, · 55 unmodified lines | |||
| 350 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); | 350 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); |
| 351 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); | 351 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 352 | struct skl_dma_params *dma_params = NULL; | 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 | struct skl_module_cfg *mconfig; | 354 | struct skl_module_cfg *mconfig; |
| 355 | 355 | ||
| 356 | dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); | 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 | * CGCTL.MISCBDCGE if disabled by driver | 370 | * CGCTL.MISCBDCGE if disabled by driver |
| 371 | */ | 371 | */ |
| 372 | if (!strncmp(dai->name, "Reference Pin", 13) && | 372 | if (!strncmp(dai->name, "Reference Pin", 13) && |
| 373 | skl->skl_sst->miscbdcg_disabled) { | 373 | skl->miscbdcg_disabled) { |
| 374 | skl->skl_sst->enable_miscbdcge(dai->dev, true); | 374 | skl->enable_miscbdcge(dai->dev, true); |
| 375 | skl->skl_sst->miscbdcg_disabled = false; | 375 | skl->miscbdcg_disabled = false; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); | 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 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); | 388 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 389 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); | 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 | struct skl_module_cfg *mconfig; | 391 | struct skl_module_cfg *mconfig; |
| 392 | int ret; | 392 | int ret; |
| 393 | 393 | ||
| @@ -396,7 +396,7 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 396 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); | 396 | mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); |
| 397 | 397 | ||
| 398 | if (mconfig) { | 398 | if (mconfig) { |
| 399 | ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe); | 399 | ret = skl_reset_pipe(skl, mconfig->pipe); |
| 400 | if (ret < 0) | 400 | if (ret < 0) |
| 401 | dev_err(dai->dev, "%s:Reset failed ret =%d", | 401 | dev_err(dai->dev, "%s:Reset failed ret =%d", |
| 402 | __func__, ret); | 402 | __func__, ret); |
| @@ -471,8 +471,7 @@ static int skl_decoupled_trigger(struct snd_pcm_substream *substream, · 68 unmodified lines | |||
| 471 | static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | 471 | static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, |
| 472 | struct snd_soc_dai *dai) | 472 | struct snd_soc_dai *dai) |
| 473 | { | 473 | { |
| 474 | struct skl *skl = get_skl_ctx(dai->dev); | 474 | struct skl_dev *skl = get_skl_ctx(dai->dev); |
| 475 | struct skl_sst *ctx = skl->skl_sst; | ||
| 476 | struct skl_module_cfg *mconfig; | 475 | struct skl_module_cfg *mconfig; |
| 477 | struct hdac_bus *bus = get_bus_ctx(substream); | 476 | struct hdac_bus *bus = get_bus_ctx(substream); |
| 478 | struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); | 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 | ret = skl_decoupled_trigger(substream, cmd); | 514 | ret = skl_decoupled_trigger(substream, cmd); |
| 516 | if (ret < 0) | 515 | if (ret < 0) |
| 517 | return ret; | 516 | return ret; |
| 518 | return skl_run_pipe(ctx, mconfig->pipe); | 517 | return skl_run_pipe(skl, mconfig->pipe); |
| 519 | break; | 518 | break; |
| 520 | 519 | ||
| 521 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 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 | * there are no underrun/overrun in the case if there is a delay | 525 | * there are no underrun/overrun in the case if there is a delay |
| 527 | * between the two operations. | 526 | * between the two operations. |
| 528 | */ | 527 | */ |
| 529 | ret = skl_stop_pipe(ctx, mconfig->pipe); | 528 | ret = skl_stop_pipe(skl, mconfig->pipe); |
| 530 | if (ret < 0) | 529 | if (ret < 0) |
| 531 | return ret; | 530 | return ret; |
| 532 | 531 | ||
| @@ -602,14 +601,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, · 69 unmodified lines | |||
| 602 | static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, | 601 | static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, |
| 603 | struct snd_soc_dai *dai) | 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 | struct skl_module_cfg *mconfig = NULL; | 605 | struct skl_module_cfg *mconfig = NULL; |
| 607 | 606 | ||
| 608 | /* In case of XRUN recovery, reset the FW pipe to clean state */ | 607 | /* In case of XRUN recovery, reset the FW pipe to clean state */ |
| 609 | mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); | 608 | mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); |
| 610 | if (mconfig && !mconfig->pipe->passthru && | 609 | if (mconfig && !mconfig->pipe->passthru && |
| 611 | (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN)) | 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 | return 0; | 613 | return 0; |
| 615 | } | 614 | } |
| @@ -1301,7 +1300,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) · 685 unmodified lines | |||
| 1301 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); | 1300 | struct hdac_bus *bus = dev_get_drvdata(dai->dev); |
| 1302 | struct snd_pcm *pcm = rtd->pcm; | 1301 | struct snd_pcm *pcm = rtd->pcm; |
| 1303 | unsigned int size; | 1302 | unsigned int size; |
| 1304 | struct skl *skl = bus_to_skl(bus); | 1303 | struct skl_dev *skl = bus_to_skl(bus); |
| 1305 | 1304 | ||
| 1306 | if (dai->driver->playback.channels_min || | 1305 | if (dai->driver->playback.channels_min || |
| 1307 | dai->driver->capture.channels_min) { | 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 | return 0; | 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 | struct skl_module_inst_id *pin_id; | 1323 | struct skl_module_inst_id *pin_id; |
| 1325 | guid_t *uuid_mod, *uuid_tplg; | 1324 | guid_t *uuid_mod, *uuid_tplg; |
| 1326 | struct skl_module *skl_module; | 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 | uuid_mod = (guid_t *)mconfig->guid; | 1329 | uuid_mod = (guid_t *)mconfig->guid; |
| 1331 | 1330 | ||
| 1332 | if (list_empty(&ctx->uuid_list)) { | 1331 | if (list_empty(&skl->uuid_list)) { |
| 1333 | dev_err(ctx->dev, "Module list is empty\n"); | 1332 | dev_err(skl->dev, "Module list is empty\n"); |
| 1334 | return -EIO; | 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 | if (guid_equal(uuid_mod, &module->uuid)) { | 1337 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 1339 | mconfig->id.module_id = module->id; | 1338 | mconfig->id.module_id = module->id; |
| 1340 | if (mconfig->module) | 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 | if (skl->nr_modules && ret) | 1360 | if (skl->nr_modules && ret) |
| 1362 | return ret; | 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 | for (i = 0; i < MAX_IN_QUEUE; i++) { | 1364 | for (i = 0; i < MAX_IN_QUEUE; i++) { |
| 1366 | pin_id = &mconfig->m_in_pin[i].id; | 1365 | pin_id = &mconfig->m_in_pin[i].id; |
| 1367 | if (guid_equal(&pin_id->mod_uuid, &module->uuid)) | 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 | return 0; | 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 | struct skl_pipeline *p; | 1382 | struct skl_pipeline *p; |
| 1384 | struct skl_pipe_module *m; | 1383 | struct skl_pipe_module *m; |
| @@ -1393,7 +1392,7 @@ static int skl_populate_modules(struct skl *skl) · 8 unmodified lines | |||
| 1393 | 1392 | ||
| 1394 | ret = skl_get_module_info(skl, mconfig); | 1393 | ret = skl_get_module_info(skl, mconfig); |
| 1395 | if (ret < 0) { | 1394 | if (ret < 0) { |
| 1396 | dev_err(skl->skl_sst->dev, | 1395 | dev_err(skl->dev, |
| 1397 | "query module info failed\n"); | 1396 | "query module info failed\n"); |
| 1398 | return ret; | 1397 | return ret; |
| 1399 | } | 1398 | } |
| @@ -1408,7 +1407,7 @@ static int skl_populate_modules(struct skl *skl) · 8 unmodified lines | |||
| 1408 | static int skl_platform_soc_probe(struct snd_soc_component *component) | 1407 | static int skl_platform_soc_probe(struct snd_soc_component *component) |
| 1409 | { | 1408 | { |
| 1410 | struct hdac_bus *bus = dev_get_drvdata(component->dev); | 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 | const struct skl_dsp_ops *ops; | 1411 | const struct skl_dsp_ops *ops; |
| 1413 | int ret; | 1412 | int ret; |
| 1414 | 1413 | ||
| @@ -1434,22 +1433,21 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) · 19 unmodified lines | |||
| 1434 | * Disable dynamic clock and power gating during firmware | 1433 | * Disable dynamic clock and power gating during firmware |
| 1435 | * and library download | 1434 | * and library download |
| 1436 | */ | 1435 | */ |
| 1437 | skl->skl_sst->enable_miscbdcge(component->dev, false); | 1436 | skl->enable_miscbdcge(component->dev, false); |
| 1438 | skl->skl_sst->clock_power_gating(component->dev, false); | 1437 | skl->clock_power_gating(component->dev, false); |
| 1439 | 1438 | ||
| 1440 | ret = ops->init_fw(component->dev, skl->skl_sst); | 1439 | ret = ops->init_fw(component->dev, skl); |
| 1441 | skl->skl_sst->enable_miscbdcge(component->dev, true); | 1440 | skl->enable_miscbdcge(component->dev, true); |
| 1442 | skl->skl_sst->clock_power_gating(component->dev, true); | 1441 | skl->clock_power_gating(component->dev, true); |
| 1443 | if (ret < 0) { | 1442 | if (ret < 0) { |
| 1444 | dev_err(component->dev, "Failed to boot first fw: %d\n", ret); | 1443 | dev_err(component->dev, "Failed to boot first fw: %d\n", ret); |
| 1445 | return ret; | 1444 | return ret; |
| 1446 | } | 1445 | } |
| 1447 | skl_populate_modules(skl); | 1446 | skl_populate_modules(skl); |
| 1448 | skl->skl_sst->update_d0i3c = skl_update_d0i3c; | 1447 | skl->update_d0i3c = skl_update_d0i3c; |
| 1449 | skl_dsp_enable_notification(skl->skl_sst, false); | ||
| 1450 | 1448 | ||
| 1451 | if (skl->cfg.astate_cfg != NULL) { | 1449 | if (skl->cfg.astate_cfg != NULL) { |
| 1452 | skl_dsp_set_astate_cfg(skl->skl_sst, | 1450 | skl_dsp_set_astate_cfg(skl, |
| 1453 | skl->cfg.astate_cfg->count, | 1451 | skl->cfg.astate_cfg->count, |
| 1454 | skl->cfg.astate_cfg); | 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 | static void skl_pcm_remove(struct snd_soc_component *component) | 1461 | static void skl_pcm_remove(struct snd_soc_component *component) |
| 1464 | { | 1462 | { |
| 1465 | struct hdac_bus *bus = dev_get_drvdata(component->dev); | 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 | skl_tplg_exit(component, bus); | 1466 | skl_tplg_exit(component, bus); |
| 1469 | 1467 | ||
| @@ -1486,7 +1484,7 @@ int skl_platform_register(struct device *dev) · 16 unmodified lines | |||
| 1486 | struct snd_soc_dai_driver *dais; | 1484 | struct snd_soc_dai_driver *dais; |
| 1487 | int num_dais = ARRAY_SIZE(skl_platform_dai); | 1485 | int num_dais = ARRAY_SIZE(skl_platform_dai); |
| 1488 | struct hdac_bus *bus = dev_get_drvdata(dev); | 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 | skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), | 1489 | skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), |
| 1492 | GFP_KERNEL); | 1490 | GFP_KERNEL); |
| @@ -1520,7 +1518,7 @@ err: · 27 unmodified lines | |||
| 1520 | int skl_platform_unregister(struct device *dev) | 1518 | int skl_platform_unregister(struct device *dev) |
| 1521 | { | 1519 | { |
| 1522 | struct hdac_bus *bus = dev_get_drvdata(dev); | 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 | struct skl_module_deferred_bind *modules, *tmp; | 1522 | struct skl_module_deferred_bind *modules, *tmp; |
| 1525 | 1523 | ||
| 1526 | if (!list_empty(&skl->bind_list)) { | 1524 | if (!list_empty(&skl->bind_list)) { |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 12 | #include <linux/clk-provider.h> | 12 | #include <linux/clk-provider.h> |
| 13 | #include <linux/clkdev.h> | 13 | #include <linux/clkdev.h> |
| 14 | #include <sound/intel-nhlt.h> | ||
| 14 | #include "skl.h" | 15 | #include "skl.h" |
| 15 | #include "skl-ssp-clk.h" | 16 | #include "skl-ssp-clk.h" |
| 16 | #include "skl-topology.h" | 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 | /* Sends dma control IPC to turn the clock ON/OFF */ | 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 | struct skl_clk_rate_cfg_table *rcfg, | 106 | struct skl_clk_rate_cfg_table *rcfg, |
| 106 | u32 vbus_id, u8 clk_type, | 107 | u32 vbus_id, u8 clk_type, |
| 107 | bool enable) | 108 | bool enable) |
| @@ -152,7 +153,7 @@ static int skl_send_clk_dma_control(struct skl *skl, · 44 unmodified lines | |||
| 152 | memcpy(i2s_config + sp_cfg->size, data, size); | 153 | memcpy(i2s_config + sp_cfg->size, data, size); |
| 153 | 154 | ||
| 154 | node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4)); | 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 | i2s_config_size, node_id); | 157 | i2s_config_size, node_id); |
| 157 | kfree(i2s_config); | 158 | kfree(i2s_config); |
| 158 | 159 | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include "../common/sst-dsp.h" | 12 | #include "../common/sst-dsp.h" |
| 13 | #include "../common/sst-ipc.h" | 13 | #include "../common/sst-ipc.h" |
| 14 | #include "../common/sst-dsp-priv.h" | 14 | #include "../common/sst-dsp-priv.h" |
| 15 | #include "skl-sst-ipc.h" | 15 | #include "skl.h" |
| 16 | 16 | ||
| 17 | /* various timeout values */ | 17 | /* various timeout values */ |
| 18 | #define SKL_DSP_PU_TO 50 | 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 | void skl_dsp_init_core_state(struct sst_dsp *ctx) | 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 | int i; | 37 | int i; |
| 38 | 38 | ||
| 39 | skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; | 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 | /* Get the mask for all enabled cores */ | 48 | /* Get the mask for all enabled cores */ |
| 49 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx) | 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 | unsigned int core_mask, en_cores_mask; | 52 | unsigned int core_mask, en_cores_mask; |
| 53 | u32 val; | 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 | int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) | 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 | int ret = 0; | 339 | int ret = 0; |
| 340 | 340 | ||
| 341 | if (core_id >= skl->cores.count) { | 341 | if (core_id >= skl->cores.count) { |
| @@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(skl_dsp_get_core); · 22 unmodified lines | |||
| 364 | 364 | ||
| 365 | int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id) | 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 | int ret = 0; | 368 | int ret = 0; |
| 369 | 369 | ||
| 370 | if (core_id >= skl->cores.count) { | 370 | if (core_id >= skl->cores.count) { |
| @@ -15,9 +15,9 @@ · 14 unmodified lines | |||
| 15 | #include "skl-sst-cldma.h" | 15 | #include "skl-sst-cldma.h" |
| 16 | 16 | ||
| 17 | struct sst_dsp; | 17 | struct sst_dsp; |
| 18 | struct skl_sst; | ||
| 19 | struct sst_dsp_device; | 18 | struct sst_dsp_device; |
| 20 | struct skl_lib_info; | 19 | struct skl_lib_info; |
| 20 | struct skl_dev; | ||
| 21 | 21 | ||
| 22 | /* Intel HD Audio General DSP Registers */ | 22 | /* Intel HD Audio General DSP Registers */ |
| 23 | #define SKL_ADSP_GEN_BASE 0x0 | 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 | int skl_dsp_boot(struct sst_dsp *ctx); | 222 | int skl_dsp_boot(struct sst_dsp *ctx); |
| 223 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 223 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 224 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 224 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 225 | struct skl_sst **dsp); | 225 | struct skl_dev **dsp); |
| 226 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 226 | int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, |
| 227 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, | 227 | const char *fw_name, struct skl_dsp_loader_ops dsp_ops, |
| 228 | struct skl_sst **dsp); | 228 | struct skl_dev **dsp); |
| 229 | int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx); | 229 | int skl_sst_init_fw(struct device *dev, struct skl_dev *skl); |
| 230 | int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx); | 230 | int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl); |
| 231 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 231 | void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); |
| 232 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); | 232 | void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); |
| 233 | 233 | ||
| 234 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, | 234 | int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, |
| 235 | unsigned int offset, int index); | 235 | unsigned int offset, int index); |
| 236 | int skl_get_pvt_id(struct skl_sst *ctx, guid_t *uuid_mod, int instance_id); | 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_sst *ctx, guid_t *uuid_mod, int *pvt_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_sst *ctx, | 238 | int skl_get_pvt_instance_id_map(struct skl_dev *skl, |
| 239 | int module_id, int instance_id); | 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 | int skl_dsp_strip_extended_manifest(struct firmware *fw); | 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 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, | 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 | struct sst_dsp_device *skl_dev); | 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 | struct firmware *stripped_fw, | 250 | struct firmware *stripped_fw, |
| 252 | unsigned int hdr_offset, int index); | 251 | unsigned int hdr_offset, int index); |
| 253 | void skl_release_library(struct skl_lib_info *linfo, int lib_count); | 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 | size_t tx_size) | 281 | size_t tx_size) |
| 282 | { | 282 | { |
| 283 | if (tx_size) | 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 | static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp) | 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 | /* Lock to be held by caller */ | 295 | /* Lock to be held by caller */ |
| 296 | static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) | 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) | 300 | if (msg->tx.size) |
| 301 | sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); | 301 | sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); |
| 302 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, | 302 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE, |
| 303 | header->extension); | 303 | header->extension); |
| 304 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, | 304 | sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI, |
| @@ -345,7 +345,7 @@ out: · 40 unmodified lines | |||
| 345 | int skl_ipc_process_notification(struct sst_generic_ipc *ipc, | 345 | int skl_ipc_process_notification(struct sst_generic_ipc *ipc, |
| 346 | struct skl_ipc_header header) | 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 | if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { | 350 | if (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { |
| 351 | switch (IPC_GLB_NOTIFY_TYPE(header.primary)) { | 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 | struct ipc_message *msg; | 436 | struct ipc_message *msg; |
| 437 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; | 437 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; |
| 438 | u64 *ipc_header = (u64 *)(&header); | 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 | unsigned long flags; | 440 | unsigned long flags; |
| 441 | 441 | ||
| 442 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); | 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 | return; | 447 | return; |
| 448 | } | 448 | } |
| 449 | 449 | ||
| 450 | msg->rx.header = *ipc_header; | ||
| 450 | /* first process the header */ | 451 | /* first process the header */ |
| 451 | if (reply == IPC_GLB_REPLY_SUCCESS) { | 452 | if (reply == IPC_GLB_REPLY_SUCCESS) { |
| 452 | dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); | 453 | dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); |
| 453 | /* copy the rx data from the mailbox */ | 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 | switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { | 456 | switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { |
| 456 | case IPC_GLB_LOAD_MULTIPLE_MODS: | 457 | case IPC_GLB_LOAD_MULTIPLE_MODS: |
| 457 | case IPC_GLB_LOAD_LIBRARY: | 458 | case IPC_GLB_LOAD_LIBRARY: |
| @@ -488,7 +489,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc, · 30 unmodified lines | |||
| 488 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) | 489 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) |
| 489 | { | 490 | { |
| 490 | struct sst_dsp *dsp = context; | 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 | struct sst_generic_ipc *ipc = &skl->ipc; | 493 | struct sst_generic_ipc *ipc = &skl->ipc; |
| 493 | struct skl_ipc_header header = {0}; | 494 | struct skl_ipc_header header = {0}; |
| 494 | u32 hipcie, hipct, hipcte; | 495 | u32 hipcie, hipct, hipcte; |
| @@ -595,7 +596,7 @@ bool skl_ipc_int_status(struct sst_dsp *ctx) · 100 unmodified lines | |||
| 595 | SKL_ADSP_REG_ADSPIS) & SKL_ADSPIS_IPC; | 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 | struct sst_generic_ipc *ipc; | 601 | struct sst_generic_ipc *ipc; |
| 601 | int err; | 602 | int err; |
| @@ -635,7 +636,7 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc, · 33 unmodified lines | |||
| 635 | u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode) | 636 | u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode) |
| 636 | { | 637 | { |
| 637 | struct skl_ipc_header header = {0}; | 638 | struct skl_ipc_header header = {0}; |
| 638 | u64 *ipc_header = (u64 *)(&header); | 639 | struct sst_ipc_message request = {0}; |
| 639 | int ret; | 640 | int ret; |
| 640 | 641 | ||
| 641 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size); | 647 | header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size); |
| 647 | 648 | ||
| 648 | header.extension = IPC_PPL_LP_MODE(lp_mode); | 649 | header.extension = IPC_PPL_LP_MODE(lp_mode); |
| 650 | request.header = *(u64 *)(&header); | ||
| 649 | 651 | ||
| 650 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); | 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 | if (ret < 0) { | 654 | if (ret < 0) { |
| 653 | dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); | 655 | dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret); |
| 654 | return ret; | 656 | return ret; |
| @@ -661,16 +663,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_create_pipeline); · 6 unmodified lines | |||
| 661 | int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) | 663 | int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) |
| 662 | { | 664 | { |
| 663 | struct skl_ipc_header header = {0}; | 665 | struct skl_ipc_header header = {0}; |
| 664 | u64 *ipc_header = (u64 *)(&header); | 666 | struct sst_ipc_message request = {0}; |
| 665 | int ret; | 667 | int ret; |
| 666 | 668 | ||
| 667 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 669 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| 668 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); | 670 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); |
| 669 | header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL); | 671 | header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL); |
| 670 | header.primary |= IPC_INSTANCE_ID(instance_id); | 672 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 673 | request.header = *(u64 *)(&header); | ||
| 671 | 674 | ||
| 672 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); | 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 | if (ret < 0) { | 677 | if (ret < 0) { |
| 675 | dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); | 678 | dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret); |
| 676 | return ret; | 679 | return ret; |
| @@ -684,7 +687,7 @@ int skl_ipc_set_pipeline_state(struct sst_generic_ipc *ipc, · 7 unmodified lines | |||
| 684 | u8 instance_id, enum skl_ipc_pipeline_state state) | 687 | u8 instance_id, enum skl_ipc_pipeline_state state) |
| 685 | { | 688 | { |
| 686 | struct skl_ipc_header header = {0}; | 689 | struct skl_ipc_header header = {0}; |
| 687 | u64 *ipc_header = (u64 *)(&header); | 690 | struct sst_ipc_message request = {0}; |
| 688 | int ret; | 691 | int ret; |
| 689 | 692 | ||
| 690 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE); | 695 | header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE); |
| 693 | header.primary |= IPC_INSTANCE_ID(instance_id); | 696 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 694 | header.primary |= IPC_PPL_STATE(state); | 697 | header.primary |= IPC_PPL_STATE(state); |
| 698 | request.header = *(u64 *)(&header); | ||
| 695 | 699 | ||
| 696 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); | 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 | if (ret < 0) { | 702 | if (ret < 0) { |
| 699 | dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); | 703 | dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret); |
| 700 | return ret; | 704 | return ret; |
| @@ -707,7 +711,7 @@ int · 6 unmodified lines | |||
| 707 | skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) | 711 | skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id) |
| 708 | { | 712 | { |
| 709 | struct skl_ipc_header header = {0}; | 713 | struct skl_ipc_header header = {0}; |
| 710 | u64 *ipc_header = (u64 *)(&header); | 714 | struct sst_ipc_message request = {0}; |
| 711 | int ret; | 715 | int ret; |
| 712 | 716 | ||
| 713 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_INSTANCE_ID(instance_id); | 720 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 717 | 721 | ||
| 718 | header.extension = IPC_DMA_ID(dma_id); | 722 | header.extension = IPC_DMA_ID(dma_id); |
| 723 | request.header = *(u64 *)(&header); | ||
| 724 | |||
| 719 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); | 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 | if (ret < 0) { | 727 | if (ret < 0) { |
| 722 | dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); | 728 | dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret); |
| 723 | return ret; | 729 | return ret; |
| @@ -730,16 +736,17 @@ EXPORT_SYMBOL_GPL(skl_ipc_save_pipeline); · 6 unmodified lines | |||
| 730 | int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) | 736 | int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id) |
| 731 | { | 737 | { |
| 732 | struct skl_ipc_header header = {0}; | 738 | struct skl_ipc_header header = {0}; |
| 733 | u64 *ipc_header = (u64 *)(&header); | 739 | struct sst_ipc_message request = {0}; |
| 734 | int ret; | 740 | int ret; |
| 735 | 741 | ||
| 736 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 742 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); |
| 737 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); | 743 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); |
| 738 | header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL); | 744 | header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL); |
| 739 | header.primary |= IPC_INSTANCE_ID(instance_id); | 745 | header.primary |= IPC_INSTANCE_ID(instance_id); |
| 746 | request.header = *(u64 *)(&header); | ||
| 740 | 747 | ||
| 741 | dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary); | 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 | if (ret < 0) { | 750 | if (ret < 0) { |
| 744 | dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); | 751 | dev_err(ipc->dev, "ipc: restore pipeline failed, err: %d\n", ret); |
| 745 | return ret; | 752 | return ret; |
| @@ -753,7 +760,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id, · 7 unmodified lines | |||
| 753 | u16 module_id, struct skl_ipc_dxstate_info *dx) | 760 | u16 module_id, struct skl_ipc_dxstate_info *dx) |
| 754 | { | 761 | { |
| 755 | struct skl_ipc_header header = {0}; | 762 | struct skl_ipc_header header = {0}; |
| 756 | u64 *ipc_header = (u64 *)(&header); | 763 | struct sst_ipc_message request; |
| 757 | int ret; | 764 | int ret; |
| 758 | 765 | ||
| 759 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); | 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 | header.primary |= IPC_MOD_INSTANCE_ID(instance_id); | 769 | header.primary |= IPC_MOD_INSTANCE_ID(instance_id); |
| 763 | header.primary |= IPC_MOD_ID(module_id); | 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 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, | 776 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
| 766 | header.primary, header.extension); | 777 | header.primary, header.extension); |
| 767 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | 778 | ret = sst_ipc_tx_message_wait(ipc, request, NULL); |
| 768 | dx, sizeof(*dx), NULL, 0); | ||
| 769 | if (ret < 0) { | 779 | if (ret < 0) { |
| 770 | dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); | 780 | dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); |
| 771 | return ret; | 781 | return ret; |
| @@ -779,7 +789,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc, · 7 unmodified lines | |||
| 779 | struct skl_ipc_init_instance_msg *msg, void *param_data) | 789 | struct skl_ipc_init_instance_msg *msg, void *param_data) |
| 780 | { | 790 | { |
| 781 | struct skl_ipc_header header = {0}; | 791 | struct skl_ipc_header header = {0}; |
| 782 | u64 *ipc_header = (u64 *)(&header); | 792 | struct sst_ipc_message request; |
| 783 | int ret; | 793 | int ret; |
| 784 | u32 *buffer = (u32 *)param_data; | 794 | u32 *buffer = (u32 *)param_data; |
| 785 | /* param_block_size must be in dwords */ | 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 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); | 809 | header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); |
| 800 | header.extension |= IPC_DOMAIN(msg->domain); | 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 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, | 816 | dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, |
| 803 | header.primary, header.extension); | 817 | header.primary, header.extension); |
| 804 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data, | 818 | ret = sst_ipc_tx_message_wait(ipc, request, NULL); |
| 805 | msg->param_data_size, NULL, 0); | ||
| 806 | 819 | ||
| 807 | if (ret < 0) { | 820 | if (ret < 0) { |
| 808 | dev_err(ipc->dev, "ipc: init instance failed\n"); | 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 | struct skl_ipc_bind_unbind_msg *msg) | 830 | struct skl_ipc_bind_unbind_msg *msg) |
| 818 | { | 831 | { |
| 819 | struct skl_ipc_header header = {0}; | 832 | struct skl_ipc_header header = {0}; |
| 820 | u64 *ipc_header = (u64 *)(&header); | 833 | struct sst_ipc_message request = {0}; |
| 821 | u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND; | 834 | u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND; |
| 822 | int ret; | 835 | int ret; |
| 823 | 836 | ||
| @@ -831,10 +844,11 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc, · 7 unmodified lines | |||
| 831 | header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id); | 844 | header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id); |
| 832 | header.extension |= IPC_DST_QUEUE(msg->dst_queue); | 845 | header.extension |= IPC_DST_QUEUE(msg->dst_queue); |
| 833 | header.extension |= IPC_SRC_QUEUE(msg->src_queue); | 846 | header.extension |= IPC_SRC_QUEUE(msg->src_queue); |
| 847 | request.header = *(u64 *)(&header); | ||
| 834 | 848 | ||
| 835 | dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, | 849 | dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary, |
| 836 | header.extension); | 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 | if (ret < 0) { | 852 | if (ret < 0) { |
| 839 | dev_err(ipc->dev, "ipc: bind/unbind failed\n"); | 853 | dev_err(ipc->dev, "ipc: bind/unbind failed\n"); |
| 840 | return ret; | 854 | return ret; |
| @@ -854,7 +868,7 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc, · 13 unmodified lines | |||
| 854 | u8 module_cnt, void *data) | 868 | u8 module_cnt, void *data) |
| 855 | { | 869 | { |
| 856 | struct skl_ipc_header header = {0}; | 870 | struct skl_ipc_header header = {0}; |
| 857 | u64 *ipc_header = (u64 *)(&header); | 871 | struct sst_ipc_message request; |
| 858 | int ret; | 872 | int ret; |
| 859 | 873 | ||
| 860 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); | 876 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); |
| 863 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); | 877 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); |
| 864 | 878 | ||
| 865 | ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data, | 879 | request.header = *(u64 *)(&header); |
| 866 | (sizeof(u16) * module_cnt)); | 880 | request.data = data; |
| 881 | request.size = sizeof(u16) * module_cnt; | ||
| 882 | |||
| 883 | ret = sst_ipc_tx_message_nowait(ipc, request); | ||
| 867 | if (ret < 0) | 884 | if (ret < 0) |
| 868 | dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); | 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 | void *data) | 892 | void *data) |
| 876 | { | 893 | { |
| 877 | struct skl_ipc_header header = {0}; | 894 | struct skl_ipc_header header = {0}; |
| 878 | u64 *ipc_header = (u64 *)(&header); | 895 | struct sst_ipc_message request; |
| 879 | int ret; | 896 | int ret; |
| 880 | 897 | ||
| 881 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS); | 900 | header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS); |
| 884 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); | 901 | header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); |
| 885 | 902 | ||
| 886 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, | 903 | request.header = *(u64 *)(&header); |
| 887 | (sizeof(u16) * module_cnt), NULL, 0); | 904 | request.data = data; |
| 905 | request.size = sizeof(u16) * module_cnt; | ||
| 906 | |||
| 907 | ret = sst_ipc_tx_message_wait(ipc, request, NULL); | ||
| 888 | if (ret < 0) | 908 | if (ret < 0) |
| 889 | dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret); | 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 | struct skl_ipc_large_config_msg *msg, u32 *param) | 916 | struct skl_ipc_large_config_msg *msg, u32 *param) |
| 897 | { | 917 | { |
| 898 | struct skl_ipc_header header = {0}; | 918 | struct skl_ipc_header header = {0}; |
| 899 | u64 *ipc_header = (u64 *)(&header); | 919 | struct sst_ipc_message request; |
| 900 | int ret = 0; | 920 | int ret = 0; |
| 901 | size_t sz_remaining, tx_size, data_offset; | 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 | header.primary, header.extension); | 943 | header.primary, header.extension); |
| 924 | dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", | 944 | dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n", |
| 925 | (unsigned)data_offset, (unsigned)tx_size); | 945 | (unsigned)data_offset, (unsigned)tx_size); |
| 926 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | 946 | |
| 927 | ((char *)param) + data_offset, | 947 | request.header = *(u64 *)(&header); |
| 928 | tx_size, NULL, 0); | 948 | request.data = ((char *)param) + data_offset; |
| 949 | request.size = tx_size; | ||
| 950 | ret = sst_ipc_tx_message_wait(ipc, request, NULL); | ||
| 929 | if (ret < 0) { | 951 | if (ret < 0) { |
| 930 | dev_err(ipc->dev, | 952 | dev_err(ipc->dev, |
| 931 | "ipc: set large config fail, err: %d\n", ret); | 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 | EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); | 969 | EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); |
| 948 | 970 | ||
| 949 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | 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 | struct skl_ipc_header header = {0}; | 975 | struct skl_ipc_header header = {0}; |
| 953 | u64 *ipc_header = (u64 *)(&header); | 976 | struct sst_ipc_message request, reply = {0}; |
| 954 | int ret = 0; | 977 | unsigned int *buf; |
| 955 | size_t sz_remaining, rx_size, data_offset; | 978 | int ret; |
| 979 | |||
| 980 | reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL); | ||
| 981 | if (!reply.data) | ||
| 982 | return -ENOMEM; | ||
| 956 | 983 | ||
| 957 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); | 984 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); |
| 958 | header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST); | 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 | header.extension |= IPC_FINAL_BLOCK(1); | 992 | header.extension |= IPC_FINAL_BLOCK(1); |
| 966 | header.extension |= IPC_INITIAL_BLOCK(1); | 993 | header.extension |= IPC_INITIAL_BLOCK(1); |
| 967 | 994 | ||
| 968 | sz_remaining = msg->param_data_size; | 995 | request.header = *(u64 *)&header; |
| 969 | data_offset = 0; | 996 | request.data = *payload; |
| 997 | request.size = *bytes; | ||
| 998 | reply.size = SKL_ADSP_W1_SZ; | ||
| 970 | 999 | ||
| 971 | while (sz_remaining != 0) { | 1000 | ret = sst_ipc_tx_message_wait(ipc, request, &reply); |
| 972 | rx_size = sz_remaining > SKL_ADSP_W1_SZ | 1001 | if (ret < 0) |
| 973 | ? SKL_ADSP_W1_SZ : sz_remaining; | 1002 | dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret); |
| 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; | ||
| 987 | 1003 | ||
| 988 | /* clear the fields */ | 1004 | reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK; |
| 989 | header.extension &= IPC_INITIAL_BLOCK_CLEAR; | 1005 | buf = krealloc(reply.data, reply.size, GFP_KERNEL); |
| 990 | header.extension &= IPC_DATA_OFFSET_SZ_CLEAR; | 1006 | if (!buf) |
| 991 | /* fill the fields */ | 1007 | return -ENOMEM; |
| 992 | header.extension |= IPC_INITIAL_BLOCK(1); | 1008 | *payload = buf; |
| 993 | header.extension |= IPC_DATA_OFFSET_SZ(data_offset); | 1009 | *bytes = reply.size; |
| 994 | } | ||
| 995 | 1010 | ||
| 996 | return ret; | 1011 | return ret; |
| 997 | } | 1012 | } |
| @@ -1001,7 +1016,7 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, · 3 unmodified lines | |||
| 1001 | u8 dma_id, u8 table_id, bool wait) | 1016 | u8 dma_id, u8 table_id, bool wait) |
| 1002 | { | 1017 | { |
| 1003 | struct skl_ipc_header header = {0}; | 1018 | struct skl_ipc_header header = {0}; |
| 1004 | u64 *ipc_header = (u64 *)(&header); | 1019 | struct sst_ipc_message request = {0}; |
| 1005 | int ret = 0; | 1020 | int ret = 0; |
| 1006 | 1021 | ||
| 1007 | header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG); | 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 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); | 1024 | header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY); |
| 1010 | header.primary |= IPC_MOD_INSTANCE_ID(table_id); | 1025 | header.primary |= IPC_MOD_INSTANCE_ID(table_id); |
| 1011 | header.primary |= IPC_MOD_ID(dma_id); | 1026 | header.primary |= IPC_MOD_ID(dma_id); |
| 1027 | request.header = *(u64 *)(&header); | ||
| 1012 | 1028 | ||
| 1013 | if (wait) | 1029 | if (wait) |
| 1014 | ret = sst_ipc_tx_message_wait(ipc, *ipc_header, | 1030 | ret = sst_ipc_tx_message_wait(ipc, request, NULL); |
| 1015 | NULL, 0, NULL, 0); | ||
| 1016 | else | 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 | if (ret < 0) | 1034 | if (ret < 0) |
| 1020 | dev_err(ipc->dev, "ipc: load lib failed\n"); | 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 | int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) | 1041 | int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg) |
| 1027 | { | 1042 | { |
| 1028 | struct skl_ipc_header header = {0}; | 1043 | struct skl_ipc_header header = {0}; |
| 1029 | u64 *ipc_header = (u64 *)(&header); | 1044 | struct sst_ipc_message request = {0}; |
| 1030 | int ret; | 1045 | int ret; |
| 1031 | 1046 | ||
| 1032 | header.primary = IPC_MSG_TARGET(IPC_MOD_MSG); | 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 | header.extension = IPC_D0IX_WAKE(msg->wake); | 1053 | header.extension = IPC_D0IX_WAKE(msg->wake); |
| 1039 | header.extension |= IPC_D0IX_STREAMING(msg->streaming); | 1054 | header.extension |= IPC_D0IX_STREAMING(msg->streaming); |
| 1055 | request.header = *(u64 *)(&header); | ||
| 1040 | 1056 | ||
| 1041 | dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, | 1057 | dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__, |
| 1042 | header.primary, header.extension); | 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 | * Use the nopm IPC here as we dont want it checking for D0iX | 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 | if (ret < 0) | 1064 | if (ret < 0) |
| 1049 | dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret); | 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 | #include <linux/irqreturn.h> | 11 | #include <linux/irqreturn.h> |
| 12 | #include "../common/sst-ipc.h" | 12 | #include "../common/sst-ipc.h" |
| 13 | #include "skl-sst-dsp.h" | ||
| 13 | 14 | ||
| 14 | struct sst_dsp; | 15 | struct sst_dsp; |
| 15 | struct skl_sst; | ||
| 16 | struct sst_generic_ipc; | 16 | struct sst_generic_ipc; |
| 17 | 17 | ||
| 18 | enum skl_ipc_pipeline_state { | 18 | enum skl_ipc_pipeline_state { |
| @@ -67,54 +67,6 @@ struct skl_lib_info { · 48 unmodified lines | |||
| 67 | const struct firmware *fw; | 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 | struct skl_ipc_init_instance_msg { | 70 | struct skl_ipc_init_instance_msg { |
| 119 | u32 module_id; | 71 | u32 module_id; |
| 120 | u32 instance_id; | 72 | u32 instance_id; |
| @@ -187,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, · 66 unmodified lines | |||
| 187 | struct skl_ipc_large_config_msg *msg, u32 *param); | 139 | struct skl_ipc_large_config_msg *msg, u32 *param); |
| 188 | 140 | ||
| 189 | int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, | 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 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, | 145 | int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, |
| 193 | u8 dma_id, u8 table_id, bool wait); | 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 | bool skl_ipc_int_status(struct sst_dsp *dsp); | 158 | bool skl_ipc_int_status(struct sst_dsp *dsp); |
| 206 | void skl_ipc_free(struct sst_generic_ipc *ipc); | 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 | void skl_clear_module_cnt(struct sst_dsp *ctx); | 161 | void skl_clear_module_cnt(struct sst_dsp *ctx); |
| 209 | 162 | ||
| 210 | void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | 163 | void skl_ipc_process_reply(struct sst_generic_ipc *ipc, |
| @@ -8,10 +8,9 @@ · 7 unmodified lines | |||
| 8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
| 9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
| 10 | #include <linux/uuid.h> | 10 | #include <linux/uuid.h> |
| 11 | #include "skl-sst-dsp.h" | ||
| 12 | #include "../common/sst-dsp.h" | 11 | #include "../common/sst-dsp.h" |
| 13 | #include "../common/sst-dsp-priv.h" | 12 | #include "../common/sst-dsp-priv.h" |
| 14 | #include "skl-sst-ipc.h" | 13 | #include "skl.h" |
| 15 | 14 | ||
| 16 | #define DEFAULT_HASH_SHA256_LEN 32 | 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 | return -EINVAL; | 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 | int module_id, int instance_id) | 102 | int module_id, int instance_id) |
| 104 | { | 103 | { |
| 105 | struct uuid_module *module; | 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 | if (module->id == module_id) | 107 | if (module->id == module_id) |
| 109 | return skl_get_pvtid_map(module, instance_id); | 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 | * skl_get_pvt_id: generate a private id for use as module id | 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 | * @uuid_mod: module's uuid | 166 | * @uuid_mod: module's uuid |
| 168 | * @instance_id: module's instance id | 167 | * @instance_id: module's instance id |
| 169 | * | 168 | * |
| 170 | * This generates a 128 bit private unique id for a module TYPE so that | 169 | * This generates a 128 bit private unique id for a module TYPE so that |
| 171 | * module instance is unique | 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 | struct uuid_module *module; | 174 | struct uuid_module *module; |
| 176 | int pvt_id; | 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 | if (guid_equal(uuid_mod, &module->uuid)) { | 178 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 180 | 179 | ||
| 181 | pvt_id = skl_pvtid_128(module); | 180 | pvt_id = skl_pvtid_128(module); |
| @@ -194,18 +193,18 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id); · 12 unmodified lines | |||
| 194 | /** | 193 | /** |
| 195 | * skl_put_pvt_id: free up the private id allocated | 194 | * skl_put_pvt_id: free up the private id allocated |
| 196 | * | 195 | * |
| 197 | * @ctx: driver context | 196 | * @skl: driver context |
| 198 | * @uuid_mod: module's uuid | 197 | * @uuid_mod: module's uuid |
| 199 | * @pvt_id: module pvt id | 198 | * @pvt_id: module pvt id |
| 200 | * | 199 | * |
| 201 | * This frees a 128 bit private unique id previously generated | 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 | int i; | 204 | int i; |
| 206 | struct uuid_module *module; | 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 | if (guid_equal(uuid_mod, &module->uuid)) { | 208 | if (guid_equal(uuid_mod, &module->uuid)) { |
| 210 | 209 | ||
| 211 | if (*pvt_id != 0) | 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 | struct adsp_module_entry *mod_entry; | 233 | struct adsp_module_entry *mod_entry; |
| 235 | int i, num_entry, size; | 234 | int i, num_entry, size; |
| 236 | const char *buf; | 235 | const char *buf; |
| 237 | struct skl_sst *skl = ctx->thread_context; | 236 | struct skl_dev *skl = ctx->thread_context; |
| 238 | struct uuid_module *module; | 237 | struct uuid_module *module; |
| 239 | struct firmware stripped_fw; | 238 | struct firmware stripped_fw; |
| 240 | unsigned int safe_file; | 239 | unsigned int safe_file; |
| @@ -317,11 +316,11 @@ free_uuid_list: · 76 unmodified lines | |||
| 317 | return ret; | 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 | struct uuid_module *uuid, *_uuid; | 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 | list_del(&uuid->list); | 324 | list_del(&uuid->list); |
| 326 | kfree(uuid); | 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 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, | 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 | struct sst_dsp_device *skl_dev) | 358 | struct sst_dsp_device *skl_dev) |
| 360 | { | 359 | { |
| 361 | struct skl_sst *skl; | 360 | struct skl_dev *skl = *dsp; |
| 362 | struct sst_dsp *sst; | 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 | skl->dev = dev; | 363 | skl->dev = dev; |
| 369 | skl_dev->thread_context = skl; | 364 | skl_dev->thread_context = skl; |
| 370 | INIT_LIST_HEAD(&skl->uuid_list); | 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 | INIT_LIST_HEAD(&sst->module_list); | 376 | INIT_LIST_HEAD(&sst->module_list); |
| 382 | 377 | ||
| 383 | skl->is_first_boot = true; | 378 | skl->is_first_boot = true; |
| 384 | if (dsp) | ||
| 385 | *dsp = skl; | ||
| 386 | 379 | ||
| 387 | return 0; | 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 | struct firmware *stripped_fw, | 384 | struct firmware *stripped_fw, |
| 392 | unsigned int hdr_offset, int index) | 385 | unsigned int hdr_offset, int index) |
| 393 | { | 386 | { |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include "../common/sst-dsp.h" | 16 | #include "../common/sst-dsp.h" |
| 17 | #include "../common/sst-dsp-priv.h" | 17 | #include "../common/sst-dsp-priv.h" |
| 18 | #include "../common/sst-ipc.h" | 18 | #include "../common/sst-ipc.h" |
| 19 | #include "skl-sst-ipc.h" | 19 | #include "skl.h" |
| 20 | 20 | ||
| 21 | #define SKL_BASEFW_TIMEOUT 300 | 21 | #define SKL_BASEFW_TIMEOUT 300 |
| 22 | #define SKL_INIT_TIMEOUT 1000 | 22 | #define SKL_INIT_TIMEOUT 1000 |
| @@ -66,7 +66,7 @@ static int skl_transfer_firmware(struct sst_dsp *ctx, · 43 unmodified lines | |||
| 66 | static int skl_load_base_firmware(struct sst_dsp *ctx) | 66 | static int skl_load_base_firmware(struct sst_dsp *ctx) |
| 67 | { | 67 | { |
| 68 | int ret = 0, i; | 68 | int ret = 0, i; |
| 69 | struct skl_sst *skl = ctx->thread_context; | 69 | struct skl_dev *skl = ctx->thread_context; |
| 70 | struct firmware stripped_fw; | 70 | struct firmware stripped_fw; |
| 71 | u32 reg; | 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 | int ret; | 162 | int ret; |
| 163 | struct skl_ipc_dxstate_info dx; | 163 | struct skl_ipc_dxstate_info dx; |
| 164 | struct skl_sst *skl = ctx->thread_context; | 164 | struct skl_dev *skl = ctx->thread_context; |
| 165 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 165 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 166 | 166 | ||
| 167 | /* If core0 is being turned on, we need to load the FW */ | 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 | int ret; | 216 | int ret; |
| 217 | struct skl_ipc_dxstate_info dx; | 217 | struct skl_ipc_dxstate_info dx; |
| 218 | struct skl_sst *skl = ctx->thread_context; | 218 | struct skl_dev *skl = ctx->thread_context; |
| 219 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); | 219 | unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); |
| 220 | 220 | ||
| 221 | dx.core_mask = core_mask; | 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 | u32 size, u16 mod_id, u8 table_id, bool is_module) | 332 | u32 size, u16 mod_id, u8 table_id, bool is_module) |
| 333 | { | 333 | { |
| 334 | int ret, bytes_left, curr_pos; | 334 | int ret, bytes_left, curr_pos; |
| 335 | struct skl_sst *skl = ctx->thread_context; | 335 | struct skl_dev *skl = ctx->thread_context; |
| 336 | skl->mod_load_complete = false; | 336 | skl->mod_load_complete = false; |
| 337 | 337 | ||
| 338 | bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); | 338 | bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false); |
| @@ -384,7 +384,7 @@ out: · 45 unmodified lines | |||
| 384 | static int | 384 | static int |
| 385 | skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) | 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 | struct firmware stripped_fw; | 388 | struct firmware stripped_fw; |
| 389 | int ret, i; | 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 | int ret = 0; | 413 | int ret = 0; |
| 414 | char mod_name[64]; /* guid str = 32 chars + 4 hyphens */ | 414 | char mod_name[64]; /* guid str = 32 chars + 4 hyphens */ |
| 415 | 415 | ||
| 416 | snprintf(mod_name, sizeof(mod_name), "%s%pUL%s", | 416 | snprintf(mod_name, sizeof(mod_name), "intel/dsp_fw_%pUL.bin", guid); |
| 417 | "intel/dsp_fw_", guid, ".bin"); | ||
| 418 | 417 | ||
| 419 | module_entry = skl_module_get_from_id(ctx, mod_id); | 418 | module_entry = skl_module_get_from_id(ctx, mod_id); |
| 420 | if (module_entry == NULL) { | 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 | static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id) | 442 | static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id) |
| 444 | { | 443 | { |
| 445 | int usage_cnt; | 444 | int usage_cnt; |
| 446 | struct skl_sst *skl = ctx->thread_context; | 445 | struct skl_dev *skl = ctx->thread_context; |
| 447 | int ret = 0; | 446 | int ret = 0; |
| 448 | 447 | ||
| 449 | usage_cnt = skl_put_module(ctx, mod_id); | 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 | int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | 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 | struct sst_dsp *sst; | 524 | struct sst_dsp *sst; |
| 525 | int ret; | 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 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | 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 | int ret; | 559 | int ret; |
| 560 | struct sst_dsp *sst = ctx->dsp; | 560 | struct sst_dsp *sst = skl->dsp; |
| 561 | 561 | ||
| 562 | ret = sst->fw_ops.load_fw(sst); | 562 | ret = sst->fw_ops.load_fw(sst); |
| 563 | if (ret < 0) { | 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 | skl_dsp_init_core_state(sst); | 568 | skl_dsp_init_core_state(sst); |
| 569 | 569 | ||
| 570 | if (ctx->lib_count > 1) { | 570 | if (skl->lib_count > 1) { |
| 571 | ret = sst->fw_ops.load_library(sst, ctx->lib_info, | 571 | ret = sst->fw_ops.load_library(sst, skl->lib_info, |
| 572 | ctx->lib_count); | 572 | skl->lib_count); |
| 573 | if (ret < 0) { | 573 | if (ret < 0) { |
| 574 | dev_err(dev, "Load Library failed : %x\n", ret); | 574 | dev_err(dev, "Load Library failed : %x\n", ret); |
| 575 | return ret; | 575 | return ret; |
| 576 | } | 576 | } |
| 577 | } | 577 | } |
| 578 | ctx->is_first_boot = false; | 578 | skl->is_first_boot = false; |
| 579 | 579 | ||
| 580 | return 0; | 580 | return 0; |
| 581 | } | 581 | } |
| 582 | EXPORT_SYMBOL_GPL(skl_sst_init_fw); | 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) | 587 | if (skl->dsp->fw) |
| 588 | release_firmware(ctx->dsp->fw); | 588 | release_firmware(skl->dsp->fw); |
| 589 | skl_clear_module_table(ctx->dsp); | 589 | skl_clear_module_table(skl->dsp); |
| 590 | skl_freeup_uuid_list(ctx); | 590 | skl_freeup_uuid_list(skl); |
| 591 | skl_ipc_free(&ctx->ipc); | 591 | skl_ipc_free(&skl->ipc); |
| 592 | ctx->dsp->ops->free(ctx->dsp); | 592 | skl->dsp->ops->free(skl->dsp); |
| 593 | if (ctx->boot_complete) { | 593 | if (skl->boot_complete) { |
| 594 | ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); | 594 | skl->dsp->cl_dev.ops.cl_cleanup_controller(skl->dsp); |
| 595 | skl_cldma_int_disable(ctx->dsp); | 595 | skl_cldma_int_disable(skl->dsp); |
| 596 | } | 596 | } |
| 597 | } | 597 | } |
| 598 | EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); | 598 | EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #include <linux/firmware.h> | 13 | #include <linux/firmware.h> |
| 14 | #include <linux/uuid.h> | 14 | #include <linux/uuid.h> |
| 15 | #include <sound/intel-nhlt.h> | ||
| 15 | #include <sound/soc.h> | 16 | #include <sound/soc.h> |
| 16 | #include <sound/soc-topology.h> | 17 | #include <sound/soc-topology.h> |
| 17 | #include <uapi/sound/snd_sst_tokens.h> | 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 | #define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ | 46 | #define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ |
| 46 | ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq)) | 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 | switch (caps) { | 53 | switch (caps) { |
| 53 | case SKL_D0I3_NONE: | 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 | switch (caps) { | 72 | switch (caps) { |
| 72 | case SKL_D0I3_NONE: | 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 | static void skl_dump_mconfig(struct skl_dev *skl, struct skl_module_cfg *mcfg) |
| 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) | ||
| 208 | { | 114 | { |
| 209 | struct skl_module_iface *iface = &mcfg->module->formats[0]; | 115 | struct skl_module_iface *iface = &mcfg->module->formats[0]; |
| 210 | 116 | ||
| 211 | dev_dbg(ctx->dev, "Dumping config\n"); | 117 | dev_dbg(skl->dev, "Dumping config\n"); |
| 212 | dev_dbg(ctx->dev, "Input Format:\n"); | 118 | dev_dbg(skl->dev, "Input Format:\n"); |
| 213 | dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels); | 119 | dev_dbg(skl->dev, "channels = %d\n", iface->inputs[0].fmt.channels); |
| 214 | dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); | 120 | dev_dbg(skl->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); | 121 | dev_dbg(skl->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); |
| 216 | dev_dbg(ctx->dev, "valid bit depth = %d\n", | 122 | dev_dbg(skl->dev, "valid bit depth = %d\n", |
| 217 | iface->inputs[0].fmt.valid_bit_depth); | 123 | iface->inputs[0].fmt.valid_bit_depth); |
| 218 | dev_dbg(ctx->dev, "Output Format:\n"); | 124 | dev_dbg(skl->dev, "Output Format:\n"); |
| 219 | dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels); | 125 | dev_dbg(skl->dev, "channels = %d\n", iface->outputs[0].fmt.channels); |
| 220 | dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); | 126 | dev_dbg(skl->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); |
| 221 | dev_dbg(ctx->dev, "valid bit depth = %d\n", | 127 | dev_dbg(skl->dev, "valid bit depth = %d\n", |
| 222 | iface->outputs[0].fmt.valid_bit_depth); | 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 | static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) | 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 | * params, so once we have calculate params, we need buffer calculation as | 228 | * params, so once we have calculate params, we need buffer calculation as |
| 323 | * well. | 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 | struct skl_module_cfg *mcfg) | 232 | struct skl_module_cfg *mcfg) |
| 327 | { | 233 | { |
| 328 | int multiplier = 1; | 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 | static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *m_cfg = w->priv; | 285 | struct skl_module_cfg *m_cfg = w->priv; |
| 380 | int link_type, dir; | 286 | int link_type, dir; |
| 381 | u32 ch, s_freq, s_fmt; | 287 | u32 ch, s_freq, s_fmt; |
| 382 | struct nhlt_specific_cfg *cfg; | 288 | struct nhlt_specific_cfg *cfg; |
| 383 | struct skl *skl = get_skl_ctx(ctx->dev); | ||
| 384 | u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); | 289 | u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); |
| 385 | int fmt_idx = m_cfg->fmt_idx; | 290 | int fmt_idx = m_cfg->fmt_idx; |
| 386 | struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; | 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 | if (m_cfg->formats_config.caps_size > 0) | 294 | if (m_cfg->formats_config.caps_size > 0) |
| 390 | return 0; | 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 | switch (m_cfg->dev_type) { | 298 | switch (m_cfg->dev_type) { |
| 394 | case SKL_DEVICE_DMIC: | 299 | case SKL_DEVICE_DMIC: |
| 395 | link_type = NHLT_LINK_DMIC; | 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 | m_cfg->formats_config.caps_size = cfg->size; | 330 | m_cfg->formats_config.caps_size = cfg->size; |
| 426 | m_cfg->formats_config.caps = (u32 *) &cfg->caps; | 331 | m_cfg->formats_config.caps = (u32 *) &cfg->caps; |
| 427 | } else { | 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 | m_cfg->vbus_id, link_type, dir); | 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 | ch, s_freq, s_fmt); | 336 | ch, s_freq, s_fmt); |
| 432 | return -EIO; | 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 | static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *m_cfg = w->priv; | 346 | struct skl_module_cfg *m_cfg = w->priv; |
| 442 | struct skl_pipe_params *params = m_cfg->pipe->p_params; | 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 | if (!m_cfg->params_fixup) | 351 | if (!m_cfg->params_fixup) |
| 447 | return; | 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 | w->name); | 355 | w->name); |
| 451 | 356 | ||
| 452 | skl_dump_mconfig(ctx, m_cfg); | 357 | skl_dump_mconfig(skl, m_cfg); |
| 453 | 358 | ||
| 454 | if (p_conn_type == SKL_PIPE_CONN_TYPE_FE) | 359 | if (p_conn_type == SKL_PIPE_CONN_TYPE_FE) |
| 455 | is_fe = true; | 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 | is_fe = false; | 362 | is_fe = false; |
| 458 | 363 | ||
| 459 | skl_tplg_update_params_fixup(m_cfg, params, is_fe); | 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 | w->name); | 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 | * set module params will be done after module is initialised. | 376 | * set module params will be done after module is initialised. |
| 472 | */ | 377 | */ |
| 473 | static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, | 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 | int i, ret; | 381 | int i, ret; |
| 477 | struct skl_module_cfg *mconfig = w->priv; | 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 | if (mconfig->formats_config.caps_size > 0 && | 388 | if (mconfig->formats_config.caps_size > 0 && |
| 484 | mconfig->formats_config.set_params == SKL_PARAM_SET) { | 389 | mconfig->formats_config.set_params == SKL_PARAM_SET) { |
| 485 | sp_cfg = &mconfig->formats_config; | 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 | sp_cfg->caps_size, | 392 | sp_cfg->caps_size, |
| 488 | sp_cfg->param_id, mconfig); | 393 | sp_cfg->param_id, mconfig); |
| 489 | if (ret < 0) | 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 | bc = (struct skl_algo_data *)sb->dobj.private; | 402 | bc = (struct skl_algo_data *)sb->dobj.private; |
| 498 | 403 | ||
| 499 | if (bc->set_params == SKL_PARAM_SET) { | 404 | if (bc->set_params == SKL_PARAM_SET) { |
| 500 | ret = skl_set_module_params(ctx, | 405 | ret = skl_set_module_params(skl, |
| 501 | (u32 *)bc->params, bc->size, | 406 | (u32 *)bc->params, bc->size, |
| 502 | bc->param_id, mconfig); | 407 | bc->param_id, mconfig); |
| 503 | if (ret < 0) | 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 | return 0; | 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 | struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg) | 451 | struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg) |
| 547 | { | 452 | { |
| 548 | switch (mcfg->dev_type) { | 453 | switch (mcfg->dev_type) { |
| 549 | case SKL_DEVICE_HDAHOST: | 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 | case SKL_DEVICE_HDALINK: | 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 | return 0; | 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 | * skl_init_module() routine, so invoke that for all modules in a pipeline | 467 | * skl_init_module() routine, so invoke that for all modules in a pipeline |
| 563 | */ | 468 | */ |
| 564 | static int | 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 | struct skl_pipe_module *w_module; | 472 | struct skl_pipe_module *w_module; |
| 568 | struct snd_soc_dapm_widget *w; | 473 | struct snd_soc_dapm_widget *w; |
| 569 | struct skl_module_cfg *mconfig; | 474 | struct skl_module_cfg *mconfig; |
| 570 | struct skl_sst *ctx = skl->skl_sst; | ||
| 571 | u8 cfg_idx; | 475 | u8 cfg_idx; |
| 572 | int ret = 0; | 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 | /* check if module ids are populated */ | 483 | /* check if module ids are populated */ |
| 580 | if (mconfig->id.module_id < 0) { | 484 | if (mconfig->id.module_id < 0) { |
| 581 | dev_err(skl->skl_sst->dev, | 485 | dev_err(skl->dev, |
| 582 | "module %pUL id not populated\n", | 486 | "module %pUL id not populated\n", |
| 583 | (guid_t *)mconfig->guid); | 487 | (guid_t *)mconfig->guid); |
| 584 | return -EIO; | 488 | return -EIO; |
| @@ -588,12 +492,8 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 3 unmodified lines | |||
| 588 | mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; | 492 | mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; |
| 589 | mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; | 493 | mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; |
| 590 | 494 | ||
| 591 | /* check resource available */ | 495 | if (mconfig->module->loadable && skl->dsp->fw_ops.load_mod) { |
| 592 | if (!skl_is_pipe_mcps_avail(skl, mconfig)) | 496 | ret = skl->dsp->fw_ops.load_mod(skl->dsp, |
| 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, | ||
| 597 | mconfig->id.module_id, mconfig->guid); | 497 | mconfig->id.module_id, mconfig->guid); |
| 598 | if (ret < 0) | 498 | if (ret < 0) |
| 599 | return ret; | 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 | /* prepare the DMA if the module is gateway cpr */ | 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 | if (ret < 0) | 506 | if (ret < 0) |
| 607 | return ret; | 507 | return ret; |
| 608 | 508 | ||
| 609 | /* update blob if blob is null for be with default value */ | 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 | * apply fix/conversion to module params based on | 513 | * apply fix/conversion to module params based on |
| 614 | * FE/BE params | 514 | * FE/BE params |
| 615 | */ | 515 | */ |
| 616 | skl_tplg_update_module_params(w, ctx); | 516 | skl_tplg_update_module_params(w, skl); |
| 617 | uuid_mod = (guid_t *)mconfig->guid; | 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 | mconfig->id.instance_id); | 519 | mconfig->id.instance_id); |
| 620 | if (mconfig->id.pvt_id < 0) | 520 | if (mconfig->id.pvt_id < 0) |
| 621 | return ret; | 521 | return ret; |
| 622 | skl_tplg_set_module_init_data(w); | 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 | if (ret < 0) { | 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 | mconfig->core_id, ret); | 527 | mconfig->core_id, ret); |
| 628 | return ret; | 528 | return ret; |
| 629 | } | 529 | } |
| 630 | 530 | ||
| 631 | ret = skl_init_module(ctx, mconfig); | 531 | ret = skl_init_module(skl, mconfig); |
| 632 | if (ret < 0) { | 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 | goto err; | 534 | goto err; |
| 635 | } | 535 | } |
| 636 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | 536 | |
| 637 | ret = skl_tplg_set_module_params(w, ctx); | 537 | ret = skl_tplg_set_module_params(w, skl); |
| 638 | if (ret < 0) | 538 | if (ret < 0) |
| 639 | goto err; | 539 | goto err; |
| 640 | } | 540 | } |
| 641 | 541 | ||
| 642 | return 0; | 542 | return 0; |
| 643 | err: | 543 | err: |
| 644 | skl_dsp_put_core(ctx->dsp, mconfig->core_id); | 544 | skl_dsp_put_core(skl->dsp, mconfig->core_id); |
| 645 | return ret; | 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 | struct skl_pipe *pipe) | 549 | struct skl_pipe *pipe) |
| 650 | { | 550 | { |
| 651 | int ret = 0; | 551 | int ret = 0; |
| @@ -657,19 +557,19 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, · 5 unmodified lines | |||
| 657 | mconfig = w_module->w->priv; | 557 | mconfig = w_module->w->priv; |
| 658 | uuid_mod = (guid_t *)mconfig->guid; | 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 | mconfig->m_state > SKL_MODULE_UNINIT) { | 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 | mconfig->id.module_id); | 563 | mconfig->id.module_id); |
| 664 | if (ret < 0) | 564 | if (ret < 0) |
| 665 | return -EIO; | 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 | if (ret < 0) { | 570 | if (ret < 0) { |
| 671 | /* don't return; continue with other modules */ | 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 | mconfig->core_id, ret); | 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 | * 0th configuratation by default for such pipes. | 586 | * 0th configuratation by default for such pipes. |
| 687 | */ | 587 | */ |
| 688 | static int | 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 | struct skl_pipe *pipe = mconfig->pipe; | 591 | struct skl_pipe *pipe = mconfig->pipe; |
| 693 | struct skl_pipe_params *params = pipe->p_params; | 592 | struct skl_pipe_params *params = pipe->p_params; |
| 694 | struct skl_path_config *pconfig = &pipe->configs[0]; | 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 | if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) { | 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 | pipe->cur_config_idx = 0; | 605 | pipe->cur_config_idx = 0; |
| 707 | pipe->memory_pages = pconfig->mem_pages; | 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 | fmt->channels, fmt->freq, fmt->bps)) { | 625 | fmt->channels, fmt->freq, fmt->bps)) { |
| 727 | pipe->cur_config_idx = i; | 626 | pipe->cur_config_idx = i; |
| 728 | pipe->memory_pages = pconfig->mem_pages; | 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 | return 0; | 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 | params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); | 635 | params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); |
| 737 | return -EINVAL; | 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 | * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we | 640 | * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we |
| 742 | * need create the pipeline. So we do following: | 641 | * need create the pipeline. So we do following: |
| 743 | * - check the resources | ||
| 744 | * - Create the pipeline | 642 | * - Create the pipeline |
| 745 | * - Initialize the modules in pipeline | 643 | * - Initialize the modules in pipeline |
| 746 | * - finally bind all modules together | 644 | * - finally bind all modules together |
| 747 | */ | 645 | */ |
| 748 | static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | 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 | int ret; | 649 | int ret; |
| 752 | struct skl_module_cfg *mconfig = w->priv; | 650 | struct skl_module_cfg *mconfig = w->priv; |
| 753 | struct skl_pipe_module *w_module; | 651 | struct skl_pipe_module *w_module; |
| 754 | struct skl_pipe *s_pipe = mconfig->pipe; | 652 | struct skl_pipe *s_pipe = mconfig->pipe; |
| 755 | struct skl_module_cfg *src_module = NULL, *dst_module, *module; | 653 | struct skl_module_cfg *src_module = NULL, *dst_module, *module; |
| 756 | struct skl_sst *ctx = skl->skl_sst; | ||
| 757 | struct skl_module_deferred_bind *modules; | 654 | struct skl_module_deferred_bind *modules; |
| 758 | 655 | ||
| 759 | ret = skl_tplg_get_pipe_config(skl, mconfig); | 656 | ret = skl_tplg_get_pipe_config(skl, mconfig); |
| 760 | if (ret < 0) | 657 | if (ret < 0) |
| 761 | return ret; | 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 | * Create a list of modules for pipe. | 661 | * Create a list of modules for pipe. |
| 772 | * This list contains modules from source to sink | 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 | if (ret < 0) | 665 | if (ret < 0) |
| 776 | return ret; | 666 | return ret; |
| 777 | 667 | ||
| 778 | skl_tplg_alloc_pipe_mem(skl, mconfig); | ||
| 779 | skl_tplg_alloc_pipe_mcps(skl, mconfig); | ||
| 780 | |||
| 781 | /* Init all pipe modules from source to sink */ | 668 | /* Init all pipe modules from source to sink */ |
| 782 | ret = skl_tplg_init_pipe_modules(skl, s_pipe); | 669 | ret = skl_tplg_init_pipe_modules(skl, s_pipe); |
| 783 | if (ret < 0) | 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 | continue; | 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 | if (ret < 0) | 683 | if (ret < 0) |
| 797 | return ret; | 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 | list_for_each_entry(modules, &skl->bind_list, node) { | 697 | list_for_each_entry(modules, &skl->bind_list, node) { |
| 811 | module = w_module->w->priv; | 698 | module = w_module->w->priv; |
| 812 | if (modules->dst == module) | 699 | if (modules->dst == module) |
| 813 | skl_bind_modules(ctx, modules->src, | 700 | skl_bind_modules(skl, modules->src, |
| 814 | modules->dst); | 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 | return 0; | 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 | int size, struct skl_module_cfg *mcfg) | 709 | int size, struct skl_module_cfg *mcfg) |
| 823 | { | 710 | { |
| 824 | int i, pvt_id; | 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 | struct skl_mod_inst_map *inst = kpb_params->u.map; | 716 | struct skl_mod_inst_map *inst = kpb_params->u.map; |
| 830 | 717 | ||
| 831 | for (i = 0; i < kpb_params->num_modules; i++) { | 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 | inst->inst_id); | 720 | inst->inst_id); |
| 834 | if (pvt_id < 0) | 721 | if (pvt_id < 0) |
| 835 | return -EINVAL; | 722 | return -EINVAL; |
| @@ -849,7 +736,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, · 13 unmodified lines | |||
| 849 | * send params after binding | 736 | * send params after binding |
| 850 | */ | 737 | */ |
| 851 | static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, | 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 | int i, ret; | 741 | int i, ret; |
| 855 | struct skl_module_cfg *mconfig = w->priv; | 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 | if (mconfig->formats_config.caps_size > 0 && | 763 | if (mconfig->formats_config.caps_size > 0 && |
| 877 | mconfig->formats_config.set_params == SKL_PARAM_BIND) { | 764 | mconfig->formats_config.set_params == SKL_PARAM_BIND) { |
| 878 | sp_cfg = &mconfig->formats_config; | 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 | sp_cfg->caps_size, | 767 | sp_cfg->caps_size, |
| 881 | sp_cfg->param_id, mconfig); | 768 | sp_cfg->param_id, mconfig); |
| 882 | if (ret < 0) | 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 | if (!params) | 781 | if (!params) |
| 895 | return -ENOMEM; | 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 | mconfig); | 785 | mconfig); |
| 899 | 786 | ||
| 900 | ret = skl_set_module_params(ctx, params, | 787 | ret = skl_set_module_params(skl, params, |
| 901 | bc->max, bc->param_id, mconfig); | 788 | bc->max, bc->param_id, mconfig); |
| 902 | kfree(params); | 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 | return 0; | 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 | struct uuid_module *module; | 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 | if (guid_equal(uuid, &module->uuid)) | 805 | if (guid_equal(uuid, &module->uuid)) |
| 919 | return module->id; | 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 | return -EINVAL; | 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 | const struct snd_kcontrol_new *k) | 813 | const struct snd_kcontrol_new *k) |
| 927 | { | 814 | { |
| 928 | struct soc_bytes_ext *sb = (void *) k->private_value; | 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 | params->num_modules = uuid_params->num_modules; | 829 | params->num_modules = uuid_params->num_modules; |
| 943 | 830 | ||
| 944 | for (i = 0; i < uuid_params->num_modules; i++) { | 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 | &uuid_params->u.map_uuid[i].mod_uuid); | 833 | &uuid_params->u.map_uuid[i].mod_uuid); |
| 947 | if (module_id < 0) { | 834 | if (module_id < 0) { |
| 948 | devm_kfree(bus->dev, params); | 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 | * Retrieve the module id from UUID mentioned in the | 853 | * Retrieve the module id from UUID mentioned in the |
| 967 | * post bind params | 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 | struct snd_soc_dapm_widget *w) | 857 | struct snd_soc_dapm_widget *w) |
| 971 | { | 858 | { |
| 972 | struct skl_module_cfg *mconfig = w->priv; | 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 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && | 872 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && |
| 986 | (skl_tplg_find_moduleid_from_uuid(skl, | 873 | (skl_tplg_find_moduleid_from_uuid(skl, |
| 987 | &w->kcontrol_news[i]) < 0)) | 874 | &w->kcontrol_news[i]) < 0)) |
| 988 | dev_err(skl->skl_sst->dev, | 875 | dev_err(skl->dev, |
| 989 | "%s: invalid kpb post bind params\n", | 876 | "%s: invalid kpb post bind params\n", |
| 990 | __func__); | 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 | struct skl_module_cfg *src, struct skl_module_cfg *dst) | 881 | struct skl_module_cfg *src, struct skl_module_cfg *dst) |
| 995 | { | 882 | { |
| 996 | struct skl_module_deferred_bind *m_list, *modules; | 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 | static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, | 917 | static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, |
| 1031 | struct skl *skl, | 918 | struct skl_dev *skl, |
| 1032 | struct snd_soc_dapm_widget *src_w, | 919 | struct snd_soc_dapm_widget *src_w, |
| 1033 | struct skl_module_cfg *src_mconfig) | 920 | struct skl_module_cfg *src_mconfig) |
| 1034 | { | 921 | { |
| 1035 | struct snd_soc_dapm_path *p; | 922 | struct snd_soc_dapm_path *p; |
| 1036 | struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL; | 923 | struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL; |
| 1037 | struct skl_module_cfg *sink_mconfig; | 924 | struct skl_module_cfg *sink_mconfig; |
| 1038 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1039 | int ret; | 925 | int ret; |
| 1040 | 926 | ||
| 1041 | snd_soc_dapm_widget_for_each_sink_path(w, p) { | 927 | snd_soc_dapm_widget_for_each_sink_path(w, p) { |
| 1042 | if (!p->connect) | 928 | if (!p->connect) |
| 1043 | continue; | 929 | continue; |
| 1044 | 930 | ||
| 1045 | dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); | 931 | dev_dbg(skl->dev, |
| 1046 | dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); | 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 | next_sink = p->sink; | 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 | return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig); | 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 | * they are ones used for SKL so check that first | 944 | * they are ones used for SKL so check that first |
| 1057 | */ | 945 | */ |
| 1058 | if ((p->sink->priv != NULL) && | 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 | sink = p->sink; | 949 | sink = p->sink; |
| 1062 | sink_mconfig = sink->priv; | 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 | continue; | 976 | continue; |
| 1089 | 977 | ||
| 1090 | /* Bind source to sink, mixin is always source */ | 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 | if (ret) | 980 | if (ret) |
| 1093 | return ret; | 981 | return ret; |
| 1094 | 982 | ||
| 1095 | /* set module params after bind */ | 983 | /* set module params after bind */ |
| 1096 | skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx); | 984 | skl_tplg_set_module_bind_params(src_w, |
| 1097 | skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); | 985 | src_mconfig, skl); |
| 986 | skl_tplg_set_module_bind_params(sink, | ||
| 987 | sink_mconfig, skl); | ||
| 1098 | 988 | ||
| 1099 | /* Start sinks pipe first */ | 989 | /* Start sinks pipe first */ |
| 1100 | if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { | 990 | if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { |
| 1101 | if (sink_mconfig->pipe->conn_type != | 991 | if (sink_mconfig->pipe->conn_type != |
| 1102 | SKL_PIPE_CONN_TYPE_FE) | 992 | SKL_PIPE_CONN_TYPE_FE) |
| 1103 | ret = skl_run_pipe(ctx, | 993 | ret = skl_run_pipe(skl, |
| 1104 | sink_mconfig->pipe); | 994 | sink_mconfig->pipe); |
| 1105 | if (ret) | 995 | if (ret) |
| 1106 | return ret; | 996 | return ret; |
| @@ -1125,10 +1015,9 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, · 18 unmodified lines | |||
| 1125 | * - Then run current pipe | 1015 | * - Then run current pipe |
| 1126 | */ | 1016 | */ |
| 1127 | static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *src_mconfig; | 1020 | struct skl_module_cfg *src_mconfig; |
| 1131 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1132 | int ret = 0; | 1021 | int ret = 0; |
| 1133 | 1022 | ||
| 1134 | src_mconfig = w->priv; | 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 | /* Start source pipe last after starting all sinks */ | 1034 | /* Start source pipe last after starting all sinks */ |
| 1146 | if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) | 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 | return 0; | 1038 | return 0; |
| 1150 | } | 1039 | } |
| 1151 | 1040 | ||
| 1152 | static struct snd_soc_dapm_widget *skl_get_src_dsp_widget( | 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 | struct snd_soc_dapm_path *p; | 1044 | struct snd_soc_dapm_path *p; |
| 1156 | struct snd_soc_dapm_widget *src_w = NULL; | 1045 | struct snd_soc_dapm_widget *src_w = NULL; |
| 1157 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1158 | 1046 | ||
| 1159 | snd_soc_dapm_widget_for_each_source_path(w, p) { | 1047 | snd_soc_dapm_widget_for_each_source_path(w, p) { |
| 1160 | src_w = p->source; | 1048 | src_w = p->source; |
| 1161 | if (!p->connect) | 1049 | if (!p->connect) |
| 1162 | continue; | 1050 | continue; |
| 1163 | 1051 | ||
| 1164 | dev_dbg(ctx->dev, "sink widget=%s\n", w->name); | 1052 | dev_dbg(skl->dev, "sink widget=%s\n", w->name); |
| 1165 | dev_dbg(ctx->dev, "src widget=%s\n", p->source->name); | 1053 | dev_dbg(skl->dev, "src widget=%s\n", p->source->name); |
| 1166 | 1054 | ||
| 1167 | /* | 1055 | /* |
| 1168 | * here we will check widgets in sink pipelines, so that can | 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 | * ones used for SKL so check that first | 1058 | * ones used for SKL so check that first |
| 1171 | */ | 1059 | */ |
| 1172 | if ((p->source->priv != NULL) && | 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 | return p->source; | 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 | * - start this pipeline | 1079 | * - start this pipeline |
| 1192 | */ | 1080 | */ |
| 1193 | static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, | 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 | int ret = 0; | 1084 | int ret = 0; |
| 1197 | struct snd_soc_dapm_widget *source, *sink; | 1085 | struct snd_soc_dapm_widget *source, *sink; |
| 1198 | struct skl_module_cfg *src_mconfig, *sink_mconfig; | 1086 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1199 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1200 | int src_pipe_started = 0; | 1087 | int src_pipe_started = 0; |
| 1201 | 1088 | ||
| 1202 | sink = w; | 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 | if (src_pipe_started) { | 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 | if (ret) | 1113 | if (ret) |
| 1227 | return ret; | 1114 | return ret; |
| 1228 | 1115 | ||
| 1229 | /* set module params after bind */ | 1116 | /* set module params after bind */ |
| 1230 | skl_tplg_set_module_bind_params(source, src_mconfig, ctx); | 1117 | skl_tplg_set_module_bind_params(source, src_mconfig, skl); |
| 1231 | skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx); | 1118 | skl_tplg_set_module_bind_params(sink, sink_mconfig, skl); |
| 1232 | 1119 | ||
| 1233 | if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) | 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 | return ret; | 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 | * - unbind with source pipelines if still connected | 1131 | * - unbind with source pipelines if still connected |
| 1245 | */ | 1132 | */ |
| 1246 | static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *src_mconfig, *sink_mconfig; | 1136 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1250 | int ret = 0, i; | 1137 | int ret = 0, i; |
| 1251 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1252 | 1138 | ||
| 1253 | sink_mconfig = w->priv; | 1139 | sink_mconfig = w->priv; |
| 1254 | 1140 | ||
| 1255 | /* Stop the pipe */ | 1141 | /* Stop the pipe */ |
| 1256 | ret = skl_stop_pipe(ctx, sink_mconfig->pipe); | 1142 | ret = skl_stop_pipe(skl, sink_mconfig->pipe); |
| 1257 | if (ret) | 1143 | if (ret) |
| 1258 | return ret; | 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 | if (!src_mconfig) | 1149 | if (!src_mconfig) |
| 1264 | continue; | 1150 | continue; |
| 1265 | 1151 | ||
| 1266 | ret = skl_unbind_modules(ctx, | 1152 | ret = skl_unbind_modules(skl, |
| 1267 | src_mconfig, sink_mconfig); | 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 | * in the Post-PMD event of mixer we need to do following: | 1161 | * in the Post-PMD event of mixer we need to do following: |
| 1276 | * - Free the mcps used | ||
| 1277 | * - Free the mem used | ||
| 1278 | * - Unbind the modules within the pipeline | 1162 | * - Unbind the modules within the pipeline |
| 1279 | * - Delete the pipeline (modules are not required to be explicitly | 1163 | * - Delete the pipeline (modules are not required to be explicitly |
| 1280 | * deleted, pipeline delete is enough here | 1164 | * deleted, pipeline delete is enough here |
| 1281 | */ | 1165 | */ |
| 1282 | static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *mconfig = w->priv; | 1169 | struct skl_module_cfg *mconfig = w->priv; |
| 1286 | struct skl_pipe_module *w_module; | 1170 | struct skl_pipe_module *w_module; |
| 1287 | struct skl_module_cfg *src_module = NULL, *dst_module; | 1171 | struct skl_module_cfg *src_module = NULL, *dst_module; |
| 1288 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1289 | struct skl_pipe *s_pipe = mconfig->pipe; | 1172 | struct skl_pipe *s_pipe = mconfig->pipe; |
| 1290 | struct skl_module_deferred_bind *modules, *tmp; | 1173 | struct skl_module_deferred_bind *modules, *tmp; |
| 1291 | 1174 | ||
| 1292 | if (s_pipe->state == SKL_PIPE_INVALID) | 1175 | if (s_pipe->state == SKL_PIPE_INVALID) |
| 1293 | return -EINVAL; | 1176 | return -EINVAL; |
| 1294 | 1177 | ||
| 1295 | skl_tplg_free_pipe_mcps(skl, mconfig); | ||
| 1296 | skl_tplg_free_pipe_mem(skl, mconfig); | ||
| 1297 | |||
| 1298 | list_for_each_entry(w_module, &s_pipe->w_list, node) { | 1178 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1299 | if (list_empty(&skl->bind_list)) | 1179 | if (list_empty(&skl->bind_list)) |
| 1300 | break; | 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 | * modules from deferred bind list. | 1187 | * modules from deferred bind list. |
| 1308 | */ | 1188 | */ |
| 1309 | if (modules->dst == src_module) { | 1189 | if (modules->dst == src_module) { |
| 1310 | skl_unbind_modules(ctx, modules->src, | 1190 | skl_unbind_modules(skl, modules->src, |
| 1311 | modules->dst); | 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 | list_for_each_entry(w_module, &s_pipe->w_list, node) { | 1207 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1328 | dst_module = w_module->w->priv; | 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 | if (src_module == NULL) { | 1210 | if (src_module == NULL) { |
| 1333 | src_module = dst_module; | 1211 | src_module = dst_module; |
| 1334 | continue; | 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 | src_module = dst_module; | 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 | list_for_each_entry(w_module, &s_pipe->w_list, node) { | 1221 | list_for_each_entry(w_module, &s_pipe->w_list, node) { |
| 1344 | src_module = w_module->w->priv; | 1222 | src_module = w_module->w->priv; |
| 1345 | src_module->m_state = SKL_MODULE_UNINIT; | 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 | * in the Post-PMD event of PGA we need to do following: | 1230 | * in the Post-PMD event of PGA we need to do following: |
| 1353 | * - Free the mcps used | ||
| 1354 | * - Stop the pipeline | 1231 | * - Stop the pipeline |
| 1355 | * - In source pipe is connected, unbind with source pipelines | 1232 | * - In source pipe is connected, unbind with source pipelines |
| 1356 | */ | 1233 | */ |
| 1357 | static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, | 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 | struct skl_module_cfg *src_mconfig, *sink_mconfig; | 1237 | struct skl_module_cfg *src_mconfig, *sink_mconfig; |
| 1361 | int ret = 0, i; | 1238 | int ret = 0, i; |
| 1362 | struct skl_sst *ctx = skl->skl_sst; | ||
| 1363 | 1239 | ||
| 1364 | src_mconfig = w->priv; | 1240 | src_mconfig = w->priv; |
| 1365 | 1241 | ||
| 1366 | /* Stop the pipe since this is a mixin module */ | 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 | if (ret) | 1244 | if (ret) |
| 1369 | return ret; | 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 | * This is a connecter and if path is found that means | 1253 | * This is a connecter and if path is found that means |
| 1378 | * unbind between source and sink has not happened yet | 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 | sink_mconfig); | 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 | struct snd_kcontrol *k, int event) | 1271 | struct snd_kcontrol *k, int event) |
| 1396 | { | 1272 | { |
| 1397 | struct snd_soc_dapm_context *dapm = w->dapm; | 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 | switch (event) { | 1276 | switch (event) { |
| 1401 | case SND_SOC_DAPM_PRE_PMU: | 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 | struct snd_soc_dapm_context *dapm = w->dapm; | 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 | switch (event) { | 1306 | switch (event) { |
| 1431 | case SND_SOC_DAPM_PRE_PMU: | 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 | struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; | 1322 | struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; |
| 1447 | struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); | 1323 | struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol); |
| 1448 | struct skl_module_cfg *mconfig = w->priv; | 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 | if (w->power) | 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 | bc->size, bc->param_id, mconfig); | 1329 | bc->size, bc->param_id, mconfig); |
| 1454 | 1330 | ||
| 1455 | /* decrement size for TLV header */ | 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 | struct soc_bytes_ext *sb = | 1357 | struct soc_bytes_ext *sb = |
| 1482 | (struct soc_bytes_ext *)kcontrol->private_value; | 1358 | (struct soc_bytes_ext *)kcontrol->private_value; |
| 1483 | struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private; | 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 | if (ac->params) { | 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 | return -EFAULT; | 1374 | return -EFAULT; |
| 1499 | 1375 | ||
| 1500 | if (w->power) | 1376 | if (w->power) |
| 1501 | return skl_set_module_params(skl->skl_sst, | 1377 | return skl_set_module_params(skl, |
| 1502 | (u32 *)ac->params, ac->size, | 1378 | (u32 *)ac->params, ac->size, |
| 1503 | ac->param_id, mconfig); | 1379 | ac->param_id, mconfig); |
| 1504 | } | 1380 | } |
| @@ -1659,7 +1535,7 @@ int skl_tplg_update_pipe_params(struct device *dev, · 154 unmodified lines | |||
| 1659 | struct skl_pipe_params *params) | 1535 | struct skl_pipe_params *params) |
| 1660 | { | 1536 | { |
| 1661 | struct skl_module_res *res = &mconfig->module->resources[0]; | 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 | struct skl_module_fmt *format = NULL; | 1539 | struct skl_module_fmt *format = NULL; |
| 1664 | u8 cfg_idx = mconfig->pipe->cur_config_idx; | 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 | struct skl_pipe_params *params) | 1732 | struct skl_pipe_params *params) |
| 1857 | { | 1733 | { |
| 1858 | struct nhlt_specific_cfg *cfg; | 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 | int link_type = skl_tplg_be_link_type(mconfig->dev_type); | 1736 | int link_type = skl_tplg_be_link_type(mconfig->dev_type); |
| 1861 | u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type); | 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 | * Return an existing pipe if the pipe already exists. | 1946 | * Return an existing pipe if the pipe already exists. |
| 2071 | */ | 1947 | */ |
| 2072 | static int skl_tplg_add_pipe(struct device *dev, | 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 | struct snd_soc_tplg_vendor_value_elem *tkn_elem) | 1950 | struct snd_soc_tplg_vendor_value_elem *tkn_elem) |
| 2075 | { | 1951 | { |
| 2076 | struct skl_pipeline *ppl; | 1952 | struct skl_pipeline *ppl; |
| @@ -2330,10 +2206,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 253 unmodified lines | |||
| 2330 | return -EINVAL; | 2206 | return -EINVAL; |
| 2331 | 2207 | ||
| 2332 | switch (tkn_elem->token) { | 2208 | switch (tkn_elem->token) { |
| 2333 | case SKL_TKN_MM_U32_CPS: | ||
| 2334 | res->cps = tkn_elem->value; | ||
| 2335 | break; | ||
| 2336 | |||
| 2337 | case SKL_TKN_MM_U32_DMA_SIZE: | 2209 | case SKL_TKN_MM_U32_DMA_SIZE: |
| 2338 | res->dma_buffer_size = tkn_elem->value; | 2210 | res->dma_buffer_size = tkn_elem->value; |
| 2339 | break; | 2211 | break; |
| @@ -2354,10 +2226,6 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 14 unmodified lines | |||
| 2354 | res->ibs = tkn_elem->value; | 2226 | res->ibs = tkn_elem->value; |
| 2355 | break; | 2227 | break; |
| 2356 | 2228 | ||
| 2357 | case SKL_TKN_U32_MAX_MCPS: | ||
| 2358 | res->cps = tkn_elem->value; | ||
| 2359 | break; | ||
| 2360 | |||
| 2361 | case SKL_TKN_MM_U32_RES_PIN_ID: | 2229 | case SKL_TKN_MM_U32_RES_PIN_ID: |
| 2362 | case SKL_TKN_MM_U32_PIN_BUF: | 2230 | case SKL_TKN_MM_U32_PIN_BUF: |
| 2363 | ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res, | 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 | return ret; | 2234 | return ret; |
| 2367 | break; | 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 | default: | 2242 | default: |
| 2370 | dev_err(dev, "Not a res type token: %d", tkn_elem->token); | 2243 | dev_err(dev, "Not a res type token: %d", tkn_elem->token); |
| 2371 | return -EINVAL; | 2244 | return -EINVAL; |
| @@ -2381,7 +2254,7 @@ static int skl_tplg_fill_res_tkn(struct device *dev, · 9 unmodified lines | |||
| 2381 | */ | 2254 | */ |
| 2382 | static int skl_tplg_get_token(struct device *dev, | 2255 | static int skl_tplg_get_token(struct device *dev, |
| 2383 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | 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 | int tkn_count = 0; | 2259 | int tkn_count = 0; |
| 2387 | int ret; | 2260 | int ret; |
| @@ -2631,7 +2504,7 @@ static int skl_tplg_get_token(struct device *dev, · 243 unmodified lines | |||
| 2631 | * module private data | 2504 | * module private data |
| 2632 | */ | 2505 | */ |
| 2633 | static int skl_tplg_get_tokens(struct device *dev, | 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 | struct skl_module_cfg *mconfig, int block_size) | 2508 | struct skl_module_cfg *mconfig, int block_size) |
| 2636 | { | 2509 | { |
| 2637 | struct snd_soc_tplg_vendor_array *array; | 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 | * Otherwise we create a new instance and add into driver list | 2600 | * Otherwise we create a new instance and add into driver list |
| 2728 | */ | 2601 | */ |
| 2729 | static int skl_tplg_add_pipe_v4(struct device *dev, | 2602 | static int skl_tplg_add_pipe_v4(struct device *dev, |
| 2730 | struct skl_module_cfg *mconfig, struct skl *skl, | 2603 | struct skl_module_cfg *mconfig, struct skl_dev *skl, |
| 2731 | struct skl_dfw_v4_pipe *dfw_pipe) | 2604 | struct skl_dfw_v4_pipe *dfw_pipe) |
| 2732 | { | 2605 | { |
| 2733 | struct skl_pipeline *ppl; | 2606 | struct skl_pipeline *ppl; |
| 2734 | struct skl_pipe *pipe; | 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 | static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, | 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 | struct skl_module_cfg *mconfig) | 2681 | struct skl_module_cfg *mconfig) |
| 2809 | { | 2682 | { |
| 2810 | struct skl_dfw_v4_module *dfw = | 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 | return ret; | 2691 | return ret; |
| 2819 | mconfig->id.module_id = -1; | 2692 | mconfig->id.module_id = -1; |
| 2820 | mconfig->id.instance_id = dfw->instance_id; | 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 | mconfig->module->resources[0].ibs = dfw->ibs; | 2695 | mconfig->module->resources[0].ibs = dfw->ibs; |
| 2823 | mconfig->module->resources[0].obs = dfw->obs; | 2696 | mconfig->module->resources[0].obs = dfw->obs; |
| 2824 | mconfig->core_id = dfw->core_id; | 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 | * for the type and size of the suceeding data block. | 2759 | * for the type and size of the suceeding data block. |
| 2887 | */ | 2760 | */ |
| 2888 | static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, | 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 | struct skl_module_cfg *mconfig) | 2763 | struct skl_module_cfg *mconfig) |
| 2891 | { | 2764 | { |
| 2892 | struct snd_soc_tplg_vendor_array *array; | 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 | struct snd_soc_component *soc_component = skl->component; | 2859 | struct snd_soc_component *soc_component = skl->component; |
| 2988 | struct snd_soc_dapm_widget *w; | 2860 | struct snd_soc_dapm_widget *w; |
| 2989 | struct snd_soc_card *card; | 2861 | struct snd_soc_card *card; |
| @@ -2995,15 +2867,12 @@ void skl_cleanup_resources(struct skl *skl) · 5 unmodified lines | |||
| 2995 | if (!card || !card->instantiated) | 2867 | if (!card || !card->instantiated) |
| 2996 | return; | 2868 | return; |
| 2997 | 2869 | ||
| 2998 | skl->resource.mem = 0; | ||
| 2999 | skl->resource.mcps = 0; | ||
| 3000 | |||
| 3001 | list_for_each_entry(w, &card->widgets, list) { | 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 | skl_clear_pin_config(soc_component, w); | 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 | int ret; | 2889 | int ret; |
| 3021 | struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); | 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 | struct skl_module_cfg *mconfig; | 2892 | struct skl_module_cfg *mconfig; |
| 3024 | 2893 | ||
| 3025 | if (!tplg_w->priv.size) | 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 | static int skl_tplg_fill_str_mfest_tkn(struct device *dev, | 3033 | static int skl_tplg_fill_str_mfest_tkn(struct device *dev, |
| 3165 | struct snd_soc_tplg_vendor_string_elem *str_elem, | 3034 | struct snd_soc_tplg_vendor_string_elem *str_elem, |
| 3166 | struct skl *skl) | 3035 | struct skl_dev *skl) |
| 3167 | { | 3036 | { |
| 3168 | int tkn_count = 0; | 3037 | int tkn_count = 0; |
| 3169 | static int ref_count; | 3038 | static int ref_count; |
| 3170 | 3039 | ||
| 3171 | switch (str_elem->token) { | 3040 | switch (str_elem->token) { |
| 3172 | case SKL_TKN_STR_LIB_NAME: | 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 | ref_count = 0; | 3043 | ref_count = 0; |
| 3175 | return -EINVAL; | 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 | str_elem->string, | 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 | ref_count++; | 3050 | ref_count++; |
| 3182 | break; | 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 | static int skl_tplg_get_str_tkn(struct device *dev, | 3062 | static int skl_tplg_get_str_tkn(struct device *dev, |
| 3194 | struct snd_soc_tplg_vendor_array *array, | 3063 | struct snd_soc_tplg_vendor_array *array, |
| 3195 | struct skl *skl) | 3064 | struct skl_dev *skl) |
| 3196 | { | 3065 | { |
| 3197 | int tkn_count = 0, ret; | 3066 | int tkn_count = 0, ret; |
| 3198 | struct snd_soc_tplg_vendor_string_elem *str_elem; | 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 | static int skl_tplg_get_int_tkn(struct device *dev, | 3169 | static int skl_tplg_get_int_tkn(struct device *dev, |
| 3301 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | 3170 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
| 3302 | struct skl *skl) | 3171 | struct skl_dev *skl) |
| 3303 | { | 3172 | { |
| 3304 | int tkn_count = 0, ret; | 3173 | int tkn_count = 0, ret; |
| 3305 | static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; | 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 | switch (tkn_elem->token) { | 3189 | switch (tkn_elem->token) { |
| 3321 | case SKL_TKN_U32_LIB_COUNT: | 3190 | case SKL_TKN_U32_LIB_COUNT: |
| 3322 | skl->skl_sst->lib_count = tkn_elem->value; | 3191 | skl->lib_count = tkn_elem->value; |
| 3323 | break; | 3192 | break; |
| 3324 | 3193 | ||
| 3325 | case SKL_TKN_U8_NUM_MOD: | 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 | return tkn_count; | 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 | * Fill the manifest structure by parsing the tokens based on the | 3338 | * Fill the manifest structure by parsing the tokens based on the |
| 3489 | * type. | 3339 | * type. |
| 3490 | */ | 3340 | */ |
| 3491 | static int skl_tplg_get_manifest_tkn(struct device *dev, | 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 | int block_size) | 3343 | int block_size) |
| 3494 | { | 3344 | { |
| 3495 | int tkn_count = 0, ret; | 3345 | int tkn_count = 0, ret; |
| 3496 | int off = 0, tuple_size = 0; | 3346 | int off = 0, tuple_size = 0; |
| 3347 | u8 uuid_index = 0; | ||
| 3497 | struct snd_soc_tplg_vendor_array *array; | 3348 | struct snd_soc_tplg_vendor_array *array; |
| 3498 | struct snd_soc_tplg_vendor_value_elem *tkn_elem; | 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 | continue; | 3367 | continue; |
| 3517 | 3368 | ||
| 3518 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: | 3369 | case SND_SOC_TPLG_TUPLE_TYPE_UUID: |
| 3519 | ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid); | 3370 | if (array->uuid->token != SKL_TKN_UUID) { |
| 3520 | if (ret < 0) | 3371 | dev_err(dev, "Not an UUID token: %d\n", |
| 3521 | return ret; | 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 | tuple_size += sizeof(*array->uuid); | 3382 | tuple_size += sizeof(*array->uuid); |
| 3524 | continue; | 3383 | continue; |
| @@ -3550,7 +3409,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, · 25 unmodified lines | |||
| 3550 | * preceded by descriptors for type and size of data block. | 3409 | * preceded by descriptors for type and size of data block. |
| 3551 | */ | 3410 | */ |
| 3552 | static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, | 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 | struct snd_soc_tplg_vendor_array *array; | 3414 | struct snd_soc_tplg_vendor_array *array; |
| 3556 | int num_blocks, block_size = 0, block_type, off = 0; | 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 | struct snd_soc_tplg_manifest *manifest) | 3471 | struct snd_soc_tplg_manifest *manifest) |
| 3613 | { | 3472 | { |
| 3614 | struct hdac_bus *bus = snd_soc_component_get_drvdata(cmpnt); | 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 | /* proceed only if we have private data defined */ | 3476 | /* proceed only if we have private data defined */ |
| 3618 | if (manifest->priv.size == 0) | 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 | skl_tplg_get_manifest_data(manifest, bus->dev, skl); | 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 | dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", | 3483 | dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", |
| 3625 | skl->skl_sst->lib_count); | 3484 | skl->lib_count); |
| 3626 | return -EINVAL; | 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 | return 0; | 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 | struct skl_pipe_module *w_module; | 3535 | struct skl_pipe_module *w_module; |
| 3677 | struct snd_soc_dapm_widget *w; | 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 | pipe->passthru = false; | 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 | * SKL topology init routine | 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 | int ret; | 3561 | int ret; |
| 3707 | const struct firmware *fw; | 3562 | const struct firmware *fw; |
| 3708 | struct skl *skl = bus_to_skl(bus); | 3563 | struct skl_dev *skl = bus_to_skl(bus); |
| 3709 | struct skl_pipeline *ppl; | 3564 | struct skl_pipeline *ppl; |
| 3710 | 3565 | ||
| 3711 | ret = request_firmware(&fw, skl->tplg_name, bus->dev); | 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 | * The complete tplg for SKL is loaded as index 0, we don't use | 3579 | * The complete tplg for SKL is loaded as index 0, we don't use |
| 3725 | * any other index | 3580 | * any other index |
| 3726 | */ | 3581 | */ |
| 3727 | ret = snd_soc_tplg_component_load(component, | 3582 | ret = snd_soc_tplg_component_load(component, &skl_tplg_ops, fw, 0); |
| 3728 | &skl_tplg_ops, fw, 0); | ||
| 3729 | if (ret < 0) { | 3583 | if (ret < 0) { |
| 3730 | dev_err(bus->dev, "tplg component load failed%d\n", ret); | 3584 | dev_err(bus->dev, "tplg component load failed%d\n", ret); |
| 3731 | release_firmware(fw); | 3585 | goto err; |
| 3732 | return -EINVAL; | ||
| 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 | ret = skl_tplg_create_pipe_widget_list(component); | 3588 | ret = skl_tplg_create_pipe_widget_list(component); |
| 3740 | if (ret < 0) | 3589 | if (ret < 0) { |
| 3741 | return ret; | 3590 | dev_err(bus->dev, "tplg create pipe widget list failed%d\n", |
| 3591 | ret); | ||
| 3592 | goto err; | ||
| 3593 | } | ||
| 3742 | 3594 | ||
| 3743 | list_for_each_entry(ppl, &skl->ppl_list, node) | 3595 | list_for_each_entry(ppl, &skl->ppl_list, node) |
| 3744 | skl_tplg_set_pipe_type(skl, ppl->pipe); | 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 | void skl_tplg_exit(struct snd_soc_component *component, struct hdac_bus *bus) | 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 | struct skl_pipeline *ppl, *tmp; | 3606 | struct skl_pipeline *ppl, *tmp; |
| 3753 | 3607 | ||
| 3754 | if (!list_empty(&skl->ppl_list)) | 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 | /* clean up topology */ | 3612 | /* clean up topology */ |
| 3759 | snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); | 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 | } __packed; | 101 | } __packed; |
| 102 | 102 | ||
| 103 | struct skl_base_cfg { | 103 | struct skl_base_cfg { |
| 104 | u32 cps; | 104 | u32 cpc; |
| 105 | u32 ibs; | 105 | u32 ibs; |
| 106 | u32 obs; | 106 | u32 obs; |
| 107 | u32 is_pages; | 107 | u32 is_pages; |
| @@ -140,11 +140,6 @@ struct skl_src_module_cfg { · 32 unmodified lines | |||
| 140 | enum skl_s_freq src_cfg; | 140 | enum skl_s_freq src_cfg; |
| 141 | } __packed; | 141 | } __packed; |
| 142 | 142 | ||
| 143 | struct notification_mask { | ||
| 144 | u32 notify; | ||
| 145 | u32 enable; | ||
| 146 | } __packed; | ||
| 147 | |||
| 148 | struct skl_up_down_mixer_cfg { | 143 | struct skl_up_down_mixer_cfg { |
| 149 | struct skl_base_cfg base_cfg; | 144 | struct skl_base_cfg base_cfg; |
| 150 | enum skl_ch_cfg out_ch_cfg; | 145 | enum skl_ch_cfg out_ch_cfg; |
| @@ -348,7 +343,6 @@ struct skl_module_pin_resources { · 197 unmodified lines | |||
| 348 | struct skl_module_res { | 343 | struct skl_module_res { |
| 349 | u8 id; | 344 | u8 id; |
| 350 | u32 is_pages; | 345 | u32 is_pages; |
| 351 | u32 cps; | ||
| 352 | u32 ibs; | 346 | u32 ibs; |
| 353 | u32 obs; | 347 | u32 obs; |
| 354 | u32 dma_buffer_size; | 348 | u32 dma_buffer_size; |
| @@ -389,9 +383,6 @@ struct skl_module_cfg { · 34 unmodified lines | |||
| 389 | u8 out_queue_mask; | 383 | u8 out_queue_mask; |
| 390 | u8 in_queue; | 384 | u8 in_queue; |
| 391 | u8 out_queue; | 385 | u8 out_queue; |
| 392 | u32 mcps; | ||
| 393 | u32 ibs; | ||
| 394 | u32 obs; | ||
| 395 | u8 is_loadable; | 386 | u8 is_loadable; |
| 396 | u8 core_id; | 387 | u8 core_id; |
| 397 | u8 dev_type; | 388 | u8 dev_type; |
| @@ -447,7 +438,7 @@ enum skl_channel { · 49 unmodified lines | |||
| 447 | SKL_CH_QUATRO = 4, | 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 | struct hdac_bus *bus = dev_get_drvdata(dev); | 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 | int skl_tplg_be_update_params(struct snd_soc_dai *dai, | 448 | int skl_tplg_be_update_params(struct snd_soc_dai *dai, |
| 458 | struct skl_pipe_params *params); | 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 | u32 caps_size, u32 node_id); | 451 | u32 caps_size, u32 node_id); |
| 461 | void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, | 452 | void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, |
| 462 | struct skl_pipe_params *params, int stream); | 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 | int skl_tplg_update_pipe_params(struct device *dev, | 460 | int skl_tplg_update_pipe_params(struct device *dev, |
| 470 | struct skl_module_cfg *mconfig, struct skl_pipe_params *params); | 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); | 463 | void skl_tplg_d0i3_get(struct skl_dev *skl, enum d0i3_capability caps); |
| 473 | void skl_tplg_d0i3_put(struct skl *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 | *src_module, struct skl_module_cfg *dst_module); | 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 | *src_module, struct skl_module_cfg *dst_module); | 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 | u32 param_id, struct skl_module_cfg *mcfg); | 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 | u32 param_id, struct skl_module_cfg *mcfg); | 489 | u32 param_id, struct skl_module_cfg *mcfg); |
| 499 | 490 | ||
| 500 | struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, | 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 | int skl_dai_load(struct snd_soc_component *cmp, int index, | 499 | int skl_dai_load(struct snd_soc_component *cmp, int index, |
| 509 | struct snd_soc_dai_driver *dai_drv, | 500 | struct snd_soc_dai_driver *dai_drv, |
| 510 | struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai); | 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 | struct snd_soc_dapm_widget *w); | 503 | struct snd_soc_dapm_widget *w); |
| 513 | #endif | 504 | #endif |
| @@ -26,9 +26,11 @@ · 25 unmodified lines | |||
| 26 | #include <sound/hdaudio.h> | 26 | #include <sound/hdaudio.h> |
| 27 | #include <sound/hda_i915.h> | 27 | #include <sound/hda_i915.h> |
| 28 | #include <sound/hda_codec.h> | 28 | #include <sound/hda_codec.h> |
| 29 | #include <sound/intel-nhlt.h> | ||
| 29 | #include "skl.h" | 30 | #include "skl.h" |
| 30 | #include "skl-sst-dsp.h" | 31 | #include "skl-sst-dsp.h" |
| 31 | #include "skl-sst-ipc.h" | 32 | #include "skl-sst-ipc.h" |
| 33 | |||
| 32 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) | 34 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 33 | #include "../../../soc/codecs/hdac_hda.h" | 35 | #include "../../../soc/codecs/hdac_hda.h" |
| 34 | #endif | 36 | #endif |
| @@ -50,7 +52,7 @@ static void skl_update_pci_byte(struct pci_dev *pci, unsigned int reg, · 15 unmodified lines | |||
| 50 | pci_write_config_byte(pci, reg, data); | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 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 | /* Reset stream-to-link mapping */ | 135 | /* Reset stream-to-link mapping */ |
| 134 | list_for_each_entry(hlink, &bus->hlink_list, list) | 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 | skl_enable_miscbdcge(bus->dev, true); | 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 | static int skl_acquire_irq(struct hdac_bus *bus, int do_disconnect) | 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 | int ret; | 258 | int ret; |
| 257 | 259 | ||
| 258 | ret = request_threaded_irq(skl->pci->irq, skl_interrupt, | 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 | struct pci_dev *pci = to_pci_dev(dev); | 279 | struct pci_dev *pci = to_pci_dev(dev); |
| 278 | struct hdac_bus *bus = pci_get_drvdata(pci); | 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 | return skl_suspend_late_dsp(skl); | 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 | #ifdef CONFIG_PM | 286 | #ifdef CONFIG_PM |
| 285 | static int _skl_suspend(struct hdac_bus *bus) | 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 | struct pci_dev *pci = to_pci_dev(bus->dev); | 290 | struct pci_dev *pci = to_pci_dev(bus->dev); |
| 289 | int ret; | 291 | int ret; |
| 290 | 292 | ||
| @@ -307,7 +309,7 @@ static int _skl_suspend(struct hdac_bus *bus) · 16 unmodified lines | |||
| 307 | 309 | ||
| 308 | static int _skl_resume(struct hdac_bus *bus) | 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 | skl_init_pci(skl); | 314 | skl_init_pci(skl); |
| 313 | skl_dum_set(bus); | 315 | skl_dum_set(bus); |
| @@ -325,7 +327,7 @@ static int skl_suspend(struct device *dev) · 11 unmodified lines | |||
| 325 | { | 327 | { |
| 326 | struct pci_dev *pci = to_pci_dev(dev); | 328 | struct pci_dev *pci = to_pci_dev(dev); |
| 327 | struct hdac_bus *bus = pci_get_drvdata(pci); | 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 | int ret; | 331 | int ret; |
| 330 | 332 | ||
| 331 | /* | 333 | /* |
| @@ -345,7 +347,7 @@ static int skl_suspend(struct device *dev) · 13 unmodified lines | |||
| 345 | ret = _skl_suspend(bus); | 347 | ret = _skl_suspend(bus); |
| 346 | if (ret < 0) | 348 | if (ret < 0) |
| 347 | return ret; | 349 | return ret; |
| 348 | skl->skl_sst->fw_loaded = false; | 350 | skl->fw_loaded = false; |
| 349 | } | 351 | } |
| 350 | 352 | ||
| 351 | return 0; | 353 | return 0; |
| @@ -355,7 +357,7 @@ static int skl_resume(struct device *dev) · 3 unmodified lines | |||
| 355 | { | 357 | { |
| 356 | struct pci_dev *pci = to_pci_dev(dev); | 358 | struct pci_dev *pci = to_pci_dev(dev); |
| 357 | struct hdac_bus *bus = pci_get_drvdata(pci); | 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 | struct hdac_ext_link *hlink = NULL; | 361 | struct hdac_ext_link *hlink = NULL; |
| 360 | int ret; | 362 | int ret; |
| 361 | 363 | ||
| @@ -430,7 +432,7 @@ static const struct dev_pm_ops skl_pm = { · 68 unmodified lines | |||
| 430 | */ | 432 | */ |
| 431 | static int skl_free(struct hdac_bus *bus) | 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 | skl->init_done = 0; /* to be sure */ | 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 | {.name = "ssp5_sclkfs"}, | 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 | struct snd_soc_acpi_mach *machines) | 481 | struct snd_soc_acpi_mach *machines) |
| 480 | { | 482 | { |
| 481 | struct hdac_bus *bus = skl_to_bus(skl); | 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 | return mach; | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 501 | struct hdac_bus *bus = skl_to_bus(skl); |
| 500 | struct snd_soc_acpi_mach *mach = driver_data; | 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 | if (pdata) { | 519 | if (pdata) { |
| 518 | skl->use_tplg_pcm = pdata->use_tplg_pcm; | 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 | return 0; | 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 | struct snd_soc_acpi_mach *mach = skl->mach; | 531 | struct snd_soc_acpi_mach *mach = skl->mach; |
| 528 | struct hdac_bus *bus = skl_to_bus(skl); | 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 | return 0; | 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 | if (skl->i2s_dev) | 567 | if (skl->i2s_dev) |
| 564 | platform_device_unregister(skl->i2s_dev); | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 573 | struct hdac_bus *bus = skl_to_bus(skl); |
| 570 | struct platform_device *pdev; | 574 | struct platform_device *pdev; |
| @@ -588,7 +592,7 @@ static int skl_dmic_device_register(struct skl *skl) · 17 unmodified lines | |||
| 588 | return 0; | 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 | if (skl->dmic_dev) | 597 | if (skl->dmic_dev) |
| 594 | platform_device_unregister(skl->dmic_dev); | 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 | struct platform_device_info pdevinfo = {NULL}; | 635 | struct platform_device_info pdevinfo = {NULL}; |
| 632 | struct skl_clk_pdata *clk_pdata; | 636 | struct skl_clk_pdata *clk_pdata; |
| @@ -656,7 +660,7 @@ static int skl_clock_device_register(struct skl *skl) · 23 unmodified lines | |||
| 656 | return PTR_ERR_OR_ZERO(skl->clk_dev); | 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 | if (skl->clk_dev) | 665 | if (skl->clk_dev) |
| 662 | platform_device_unregister(skl->clk_dev); | 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 | unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | | 696 | unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | |
| 693 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; | 697 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; |
| 694 | unsigned int res = -1; | 698 | unsigned int res = -1; |
| 695 | struct skl *skl = bus_to_skl(bus); | 699 | struct skl_dev *skl = bus_to_skl(bus); |
| 696 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) | 700 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 697 | struct hdac_hda_priv *hda_codec; | 701 | struct hdac_hda_priv *hda_codec; |
| 698 | int err; | 702 | int err; |
| @@ -792,7 +796,7 @@ static int skl_i915_init(struct hdac_bus *bus) · 93 unmodified lines | |||
| 792 | 796 | ||
| 793 | static void skl_probe_work(struct work_struct *work) | 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 | struct hdac_bus *bus = skl_to_bus(skl); | 800 | struct hdac_bus *bus = skl_to_bus(skl); |
| 797 | struct hdac_ext_link *hlink = NULL; | 801 | struct hdac_ext_link *hlink = NULL; |
| 798 | int err; | 802 | int err; |
| @@ -854,11 +858,10 @@ out_err: · 55 unmodified lines | |||
| 854 | * constructor | 858 | * constructor |
| 855 | */ | 859 | */ |
| 856 | static int skl_create(struct pci_dev *pci, | 860 | static int skl_create(struct pci_dev *pci, |
| 857 | const struct hdac_io_ops *io_ops, | 861 | struct skl_dev **rskl) |
| 858 | struct skl **rskl) | ||
| 859 | { | 862 | { |
| 860 | struct hdac_ext_bus_ops *ext_ops = NULL; | 863 | struct hdac_ext_bus_ops *ext_ops = NULL; |
| 861 | struct skl *skl; | 864 | struct skl_dev *skl; |
| 862 | struct hdac_bus *bus; | 865 | struct hdac_bus *bus; |
| 863 | struct hda_bus *hbus; | 866 | struct hda_bus *hbus; |
| 864 | int err; | 867 | int err; |
| @@ -884,7 +887,7 @@ static int skl_create(struct pci_dev *pci, · 19 unmodified lines | |||
| 884 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) | 887 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
| 885 | ext_ops = snd_soc_hdac_hda_get_ops(); | 888 | ext_ops = snd_soc_hdac_hda_get_ops(); |
| 886 | #endif | 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 | bus->use_posbuf = 1; | 891 | bus->use_posbuf = 1; |
| 889 | skl->pci = pci; | 892 | skl->pci = pci; |
| 890 | INIT_WORK(&skl->probe_work, skl_probe_work); | 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 | static int skl_first_init(struct hdac_bus *bus) | 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 | struct pci_dev *pci = skl->pci; | 909 | struct pci_dev *pci = skl->pci; |
| 907 | int err; | 910 | int err; |
| 908 | unsigned short gcap; | 911 | unsigned short gcap; |
| @@ -978,7 +981,7 @@ static int skl_first_init(struct hdac_bus *bus) · 69 unmodified lines | |||
| 978 | static int skl_probe(struct pci_dev *pci, | 981 | static int skl_probe(struct pci_dev *pci, |
| 979 | const struct pci_device_id *pci_id) | 982 | const struct pci_device_id *pci_id) |
| 980 | { | 983 | { |
| 981 | struct skl *skl; | 984 | struct skl_dev *skl; |
| 982 | struct hdac_bus *bus = NULL; | 985 | struct hdac_bus *bus = NULL; |
| 983 | int err; | 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 | /* we use ext core ops, so provide NULL for ops here */ | 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 | if (err < 0) | 1020 | if (err < 0) |
| 1018 | return err; | 1021 | return err; |
| 1019 | 1022 | ||
| @@ -1029,7 +1032,7 @@ static int skl_probe(struct pci_dev *pci, · 9 unmodified lines | |||
| 1029 | 1032 | ||
| 1030 | device_disable_async_suspend(bus->dev); | 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 | if (skl->nhlt == NULL) { | 1037 | if (skl->nhlt == NULL) { |
| 1035 | #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) | 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 | dev_dbg(bus->dev, "error failed to register dsp\n"); | 1074 | dev_dbg(bus->dev, "error failed to register dsp\n"); |
| 1072 | goto out_nhlt_free; | 1075 | goto out_nhlt_free; |
| 1073 | } | 1076 | } |
| 1074 | skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; | 1077 | skl->enable_miscbdcge = skl_enable_miscbdcge; |
| 1075 | skl->skl_sst->clock_power_gating = skl_clock_power_gating; | 1078 | skl->clock_power_gating = skl_clock_power_gating; |
| 1076 | 1079 | ||
| 1077 | if (bus->mlcap) | 1080 | if (bus->mlcap) |
| 1078 | snd_hdac_ext_bus_get_ml_capabilities(bus); | 1081 | snd_hdac_ext_bus_get_ml_capabilities(bus); |
| @@ -1095,7 +1098,7 @@ out_dsp_free: · 16 unmodified lines | |||
| 1095 | out_clk_free: | 1098 | out_clk_free: |
| 1096 | skl_clock_device_unregister(skl); | 1099 | skl_clock_device_unregister(skl); |
| 1097 | out_nhlt_free: | 1100 | out_nhlt_free: |
| 1098 | skl_nhlt_free(skl->nhlt); | 1101 | intel_nhlt_free(skl->nhlt); |
| 1099 | out_free: | 1102 | out_free: |
| 1100 | skl_free(bus); | 1103 | skl_free(bus); |
| 1101 | 1104 | ||
| @@ -1107,7 +1110,7 @@ static void skl_shutdown(struct pci_dev *pci) · 5 unmodified lines | |||
| 1107 | struct hdac_bus *bus = pci_get_drvdata(pci); | 1110 | struct hdac_bus *bus = pci_get_drvdata(pci); |
| 1108 | struct hdac_stream *s; | 1111 | struct hdac_stream *s; |
| 1109 | struct hdac_ext_stream *stream; | 1112 | struct hdac_ext_stream *stream; |
| 1110 | struct skl *skl; | 1113 | struct skl_dev *skl; |
| 1111 | 1114 | ||
| 1112 | if (!bus) | 1115 | if (!bus) |
| 1113 | return; | 1116 | return; |
| @@ -1129,7 +1132,7 @@ static void skl_shutdown(struct pci_dev *pci) · 15 unmodified lines | |||
| 1129 | static void skl_remove(struct pci_dev *pci) | 1132 | static void skl_remove(struct pci_dev *pci) |
| 1130 | { | 1133 | { |
| 1131 | struct hdac_bus *bus = pci_get_drvdata(pci); | 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 | cancel_work_sync(&skl->probe_work); | 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 | skl_dmic_device_unregister(skl); | 1147 | skl_dmic_device_unregister(skl); |
| 1145 | skl_clock_device_unregister(skl); | 1148 | skl_clock_device_unregister(skl); |
| 1146 | skl_nhlt_remove_sysfs(skl); | 1149 | skl_nhlt_remove_sysfs(skl); |
| 1147 | skl_nhlt_free(skl->nhlt); | 1150 | intel_nhlt_free(skl->nhlt); |
| 1148 | skl_free(bus); | 1151 | skl_free(bus); |
| 1149 | dev_set_drvdata(&pci->dev, NULL); | 1152 | dev_set_drvdata(&pci->dev, NULL); |
| 1150 | } | 1153 | } |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | |||
| 16 | #include <sound/hdaudio_ext.h> | 16 | #include <sound/hdaudio_ext.h> |
| 17 | #include <sound/hda_codec.h> | 17 | #include <sound/hda_codec.h> |
| 18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
| 19 | #include "skl-nhlt.h" | ||
| 20 | #include "skl-ssp-clk.h" | 19 | #include "skl-ssp-clk.h" |
| 20 | #include "skl-sst-ipc.h" | ||
| 21 | 21 | ||
| 22 | #define SKL_SUSPEND_DELAY 2000 | 22 | #define SKL_SUSPEND_DELAY 2000 |
| 23 | 23 | ||
| @@ -40,13 +40,6 @@ · 16 unmodified lines | |||
| 40 | #define AZX_VS_EM2_DUM BIT(23) | 40 | #define AZX_VS_EM2_DUM BIT(23) |
| 41 | #define AZX_REG_VS_EM2_L1SEN BIT(13) | 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 | struct skl_debug; | 43 | struct skl_debug; |
| 51 | 44 | ||
| 52 | struct skl_astate_param { | 45 | struct skl_astate_param { |
| @@ -63,7 +56,7 @@ struct skl_fw_config { · 10 unmodified lines | |||
| 63 | struct skl_astate_config *astate_cfg; | 56 | struct skl_astate_config *astate_cfg; |
| 64 | }; | 57 | }; |
| 65 | 58 | ||
| 66 | struct skl { | 59 | struct skl_dev { |
| 67 | struct hda_bus hbus; | 60 | struct hda_bus hbus; |
| 68 | struct pci_dev *pci; | 61 | struct pci_dev *pci; |
| 69 | 62 | ||
| @@ -75,16 +68,13 @@ struct skl { · 5 unmodified lines | |||
| 75 | struct snd_soc_dai_driver *dais; | 68 | struct snd_soc_dai_driver *dais; |
| 76 | 69 | ||
| 77 | struct nhlt_acpi_table *nhlt; /* nhlt ptr */ | 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 | struct list_head ppl_list; | 72 | struct list_head ppl_list; |
| 82 | struct list_head bind_list; | 73 | struct list_head bind_list; |
| 83 | 74 | ||
| 84 | const char *fw_name; | 75 | const char *fw_name; |
| 85 | char tplg_name[64]; | 76 | char tplg_name[64]; |
| 86 | unsigned short pci_id; | 77 | unsigned short pci_id; |
| 87 | const struct firmware *tplg; | ||
| 88 | 78 | ||
| 89 | int supend_active; | 79 | int supend_active; |
| 90 | 80 | ||
| @@ -96,13 +86,59 @@ struct skl { · 5 unmodified lines | |||
| 96 | bool use_tplg_pcm; | 86 | bool use_tplg_pcm; |
| 97 | struct skl_fw_config cfg; | 87 | struct skl_fw_config cfg; |
| 98 | struct snd_soc_acpi_mach *mach; | 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 | #define skl_to_bus(s) (&(s)->hbus.core) | 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 | #define skl_to_hbus(s) (&(s)->hbus) | 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 | /* to pass dai dma data */ | 143 | /* to pass dai dma data */ |
| 108 | struct skl_dma_params { | 144 | struct skl_dma_params { |
| @@ -121,52 +157,49 @@ struct skl_dsp_ops { · 12 unmodified lines | |||
| 121 | int (*init)(struct device *dev, void __iomem *mmio_base, | 157 | int (*init)(struct device *dev, void __iomem *mmio_base, |
| 122 | int irq, const char *fw_name, | 158 | int irq, const char *fw_name, |
| 123 | struct skl_dsp_loader_ops loader_ops, | 159 | struct skl_dsp_loader_ops loader_ops, |
| 124 | struct skl_sst **skl_sst); | 160 | struct skl_dev **skl_sst); |
| 125 | int (*init_fw)(struct device *dev, struct skl_sst *ctx); | 161 | int (*init_fw)(struct device *dev, struct skl_dev *skl); |
| 126 | void (*cleanup)(struct device *dev, struct skl_sst *ctx); | 162 | void (*cleanup)(struct device *dev, struct skl_dev *skl); |
| 127 | }; | 163 | }; |
| 128 | 164 | ||
| 129 | int skl_platform_unregister(struct device *dev); | 165 | int skl_platform_unregister(struct device *dev); |
| 130 | int skl_platform_register(struct device *dev); | 166 | int skl_platform_register(struct device *dev); |
| 131 | 167 | ||
| 132 | struct nhlt_acpi_table *skl_nhlt_init(struct device *dev); | 168 | struct nhlt_specific_cfg *skl_get_ep_blob(struct skl_dev *skl, u32 instance, |
| 133 | void skl_nhlt_free(struct nhlt_acpi_table *addr); | ||
| 134 | struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, | ||
| 135 | u8 link_type, u8 s_fmt, u8 no_ch, | 169 | u8 link_type, u8 s_fmt, u8 no_ch, |
| 136 | u32 s_rate, u8 dirn, u8 dev_type); | 170 | u32 s_rate, u8 dirn, u8 dev_type); |
| 137 | 171 | ||
| 138 | int skl_get_dmic_geo(struct skl *skl); | 172 | int skl_nhlt_update_topology_bin(struct skl_dev *skl); |
| 139 | int skl_nhlt_update_topology_bin(struct skl *skl); | 173 | int skl_init_dsp(struct skl_dev *skl); |
| 140 | int skl_init_dsp(struct skl *skl); | 174 | int skl_free_dsp(struct skl_dev *skl); |
| 141 | int skl_free_dsp(struct skl *skl); | 175 | int skl_suspend_late_dsp(struct skl_dev *skl); |
| 142 | int skl_suspend_late_dsp(struct skl *skl); | 176 | int skl_suspend_dsp(struct skl_dev *skl); |
| 143 | int skl_suspend_dsp(struct skl *skl); | 177 | int skl_resume_dsp(struct skl_dev *skl); |
| 144 | int skl_resume_dsp(struct skl *skl); | 178 | void skl_cleanup_resources(struct skl_dev *skl); |
| 145 | void skl_cleanup_resources(struct skl *skl); | ||
| 146 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); | 179 | const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); |
| 147 | void skl_update_d0i3c(struct device *dev, bool enable); | 180 | void skl_update_d0i3c(struct device *dev, bool enable); |
| 148 | int skl_nhlt_create_sysfs(struct skl *skl); | 181 | int skl_nhlt_create_sysfs(struct skl_dev *skl); |
| 149 | void skl_nhlt_remove_sysfs(struct skl *skl); | 182 | void skl_nhlt_remove_sysfs(struct skl_dev *skl); |
| 150 | void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks); | 183 | void skl_get_clks(struct skl_dev *skl, struct skl_ssp_clk *ssp_clks); |
| 151 | struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id); | 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 | u32 caps_size, u32 node_id); | 186 | u32 caps_size, u32 node_id); |
| 154 | 187 | ||
| 155 | struct skl_module_cfg; | 188 | struct skl_module_cfg; |
| 156 | 189 | ||
| 157 | #ifdef CONFIG_DEBUG_FS | 190 | #ifdef CONFIG_DEBUG_FS |
| 158 | struct skl_debug *skl_debugfs_init(struct skl *skl); | 191 | struct skl_debug *skl_debugfs_init(struct skl_dev *skl); |
| 159 | void skl_debugfs_exit(struct skl *skl); | 192 | void skl_debugfs_exit(struct skl_dev *skl); |
| 160 | void skl_debug_init_module(struct skl_debug *d, | 193 | void skl_debug_init_module(struct skl_debug *d, |
| 161 | struct snd_soc_dapm_widget *w, | 194 | struct snd_soc_dapm_widget *w, |
| 162 | struct skl_module_cfg *mconfig); | 195 | struct skl_module_cfg *mconfig); |
| 163 | #else | 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 | return NULL; | 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 | static inline void skl_debug_init_module(struct skl_debug *d, | 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 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; | 523 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
| 524 | struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; | 524 | struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; |
| 525 | struct kirkwood_dma_data *priv; | 525 | struct kirkwood_dma_data *priv; |
| 526 | struct resource *mem; | ||
| 527 | struct device_node *np = pdev->dev.of_node; | 526 | struct device_node *np = pdev->dev.of_node; |
| 528 | int err; | 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 | dev_set_drvdata(&pdev->dev, priv); | 533 | dev_set_drvdata(&pdev->dev, priv); |
| 535 | 534 | ||
| 536 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 535 | priv->io = devm_platform_ioremap_resource(pdev, 0); |
| 537 | priv->io = devm_ioremap_resource(&pdev->dev, mem); | ||
| 538 | if (IS_ERR(priv->io)) | 536 | if (IS_ERR(priv->io)) |
| 539 | return PTR_ERR(priv->io); | 537 | return PTR_ERR(priv->io); |
| 540 | 538 | ||
| 541 | priv->irq = platform_get_irq(pdev, 0); | 539 | priv->irq = platform_get_irq(pdev, 0); |
| 542 | if (priv->irq < 0) { | 540 | if (priv->irq < 0) |
| 543 | dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); | ||
| 544 | return priv->irq; | 541 | return priv->irq; |
| 545 | } | ||
| 546 | 542 | ||
| 547 | if (np) { | 543 | if (np) { |
| 548 | priv->burst = 128; /* might be 32 or 128 */ | 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 | /* irq */ | 1336 | /* irq */ |
| 1337 | irq_id = platform_get_irq(pdev, 0); | 1337 | irq_id = platform_get_irq(pdev, 0); |
| 1338 | if (irq_id <= 0) { | 1338 | if (irq_id <= 0) |
| 1339 | dev_err(dev, "%pOFn no irq found\n", dev->of_node); | ||
| 1340 | return irq_id < 0 ? irq_id : -ENXIO; | 1339 | return irq_id < 0 ? irq_id : -ENXIO; |
| 1341 | } | ||
| 1342 | 1340 | ||
| 1343 | ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler, | 1341 | ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler, |
| 1344 | IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle", | 1342 | IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle", |
| @@ -63,27 +63,6 @@ enum audio_base_clock { · 62 unmodified lines | |||
| 63 | MT2701_BASE_CLK_NUM, | 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 | struct mt2701_i2s_data { | 66 | struct mt2701_i2s_data { |
| 88 | int i2s_ctrl_reg; | 67 | int i2s_ctrl_reg; |
| 89 | int i2s_asrc_fs_shift; | 68 | int i2s_asrc_fs_shift; |
| @@ -60,6 +60,27 @@ static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = { · 59 unmodified lines | |||
| 60 | { .rate = 352800, .regvalue = 24 }, | 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 | static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) | 84 | static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) |
| 64 | { | 85 | { |
| 65 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 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 | SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), | 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 | static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { | 820 | static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { |
| 808 | SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0), | 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 | PWR2_TOP_CON, 18, 1, 0), | 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 | static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { | 848 | static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { |
| 841 | /* inter-connections */ | 849 | /* inter-connections */ |
| 842 | SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), | 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 | return -ENOMEM; | 1350 | return -ENOMEM; |
| 1343 | 1351 | ||
| 1344 | irq_id = platform_get_irq_byname(pdev, "asys"); | 1352 | irq_id = platform_get_irq_byname(pdev, "asys"); |
| 1345 | if (irq_id < 0) { | 1353 | if (irq_id < 0) |
| 1346 | dev_err(dev, "unable to get ASYS IRQ\n"); | ||
| 1347 | return irq_id; | 1354 | return irq_id; |
| 1348 | } | ||
| 1349 | 1355 | ||
| 1350 | ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, | 1356 | ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, |
| 1351 | IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); | 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 | struct mtk_base_afe *afe; | 750 | struct mtk_base_afe *afe; |
| 751 | struct mt6797_afe_private *afe_priv; | 751 | struct mt6797_afe_private *afe_priv; |
| 752 | struct resource *res; | ||
| 753 | struct device *dev; | 752 | struct device *dev; |
| 754 | int i, irq_id, ret; | 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 | /* regmap init */ | 775 | /* regmap init */ |
| 777 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 776 | afe->base_addr = devm_platform_ioremap_resource(pdev, 0); |
| 778 | |||
| 779 | afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | ||
| 780 | if (IS_ERR(afe->base_addr)) | 777 | if (IS_ERR(afe->base_addr)) |
| 781 | return PTR_ERR(afe->base_addr); | 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 | int irq_id; | 1056 | int irq_id; |
| 1057 | struct mtk_base_afe *afe; | 1057 | struct mtk_base_afe *afe; |
| 1058 | struct mt8173_afe_private *afe_priv; | 1058 | struct mt8173_afe_private *afe_priv; |
| 1059 | struct resource *res; | ||
| 1060 | 1059 | ||
| 1061 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); | 1060 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); |
| 1062 | if (ret) | 1061 | if (ret) |
| @@ -1075,10 +1074,8 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) · 12 unmodified lines | |||
| 1075 | afe->dev = &pdev->dev; | 1074 | afe->dev = &pdev->dev; |
| 1076 | 1075 | ||
| 1077 | irq_id = platform_get_irq(pdev, 0); | 1076 | irq_id = platform_get_irq(pdev, 0); |
| 1078 | if (irq_id <= 0) { | 1077 | if (irq_id <= 0) |
| 1079 | dev_err(afe->dev, "np %pOFn no irq\n", afe->dev->of_node); | ||
| 1080 | return irq_id < 0 ? irq_id : -ENXIO; | 1078 | return irq_id < 0 ? irq_id : -ENXIO; |
| 1081 | } | ||
| 1082 | ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, | 1079 | ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, |
| 1083 | 0, "Afe_ISR_Handle", (void *)afe); | 1080 | 0, "Afe_ISR_Handle", (void *)afe); |
| 1084 | if (ret) { | 1081 | if (ret) { |
| @@ -1086,8 +1083,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 1086 | return ret; | 1083 | return ret; |
| 1087 | } | 1084 | } |
| 1088 | 1085 | ||
| 1089 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1086 | afe->base_addr = devm_platform_ioremap_resource(pdev, 0); |
| 1090 | afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | ||
| 1091 | if (IS_ERR(afe->base_addr)) | 1087 | if (IS_ERR(afe->base_addr)) |
| 1092 | return PTR_ERR(afe->base_addr); | 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 | return 0; | 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 | /* FE */ | 119 | /* FE */ |
| 129 | SND_SOC_DAILINK_DEFS(playback1, | 120 | SND_SOC_DAILINK_DEFS(playback1, |
| 130 | DAILINK_COMP_ARRAY(COMP_CPU("DL1")), | 121 | DAILINK_COMP_ARRAY(COMP_CPU("DL1")), |
| @@ -370,7 +361,7 @@ static int · 239 unmodified lines | |||
| 370 | mt8183_da7219_max98357_headset_init(struct snd_soc_component *component); | 361 | mt8183_da7219_max98357_headset_init(struct snd_soc_component *component); |
| 371 | 362 | ||
| 372 | static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { | 363 | static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { |
| 373 | .name = "Headset Chip", | 364 | .dlc = COMP_EMPTY(), |
| 374 | .init = mt8183_da7219_max98357_headset_init, | 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 | dai_link->platforms->of_node = platform_node; | 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 | of_parse_phandle(pdev->dev.of_node, | 431 | of_parse_phandle(pdev->dev.of_node, |
| 441 | "mediatek,headset-codec", 0); | 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 | dev_err(&pdev->dev, | 434 | dev_err(&pdev->dev, |
| 444 | "Property 'mediatek,headset-codec' missing/invalid\n"); | 435 | "Property 'mediatek,headset-codec' missing/invalid\n"); |
| 445 | return -EINVAL; | 436 | return -EINVAL; |
| @@ -15,13 +15,30 @@ · 14 unmodified lines | |||
| 15 | struct mtk_afe_tdm_priv { | 15 | struct mtk_afe_tdm_priv { |
| 16 | int bck_id; | 16 | int bck_id; |
| 17 | int bck_rate; | 17 | int bck_rate; |
| 18 | 18 | int tdm_out_mode; | |
| 19 | int bck_invert; | ||
| 20 | int lck_invert; | ||
| 19 | int mclk_id; | 21 | int mclk_id; |
| 20 | int mclk_multiple; /* according to sample rate */ | 22 | int mclk_multiple; /* according to sample rate */ |
| 21 | int mclk_rate; | 23 | int mclk_rate; |
| 22 | int mclk_apll; | 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 | enum { | 42 | enum { |
| 26 | TDM_WLEN_16_BIT = 1, | 43 | TDM_WLEN_16_BIT = 1, |
| 27 | TDM_WLEN_32_BIT = 2, | 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 | /* interconnection */ | 132 | /* interconnection */ |
| 97 | enum { | 133 | enum { |
| 98 | HDMI_CONN_CH0 = 0, | 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 | struct mt8183_afe_private *afe_priv = afe->platform_priv; | 469 | struct mt8183_afe_private *afe_priv = afe->platform_priv; |
| 434 | int tdm_id = dai->id; | 470 | int tdm_id = dai->id; |
| 435 | struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; | 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 | unsigned int rate = params_rate(params); | 473 | unsigned int rate = params_rate(params); |
| 437 | unsigned int channels = params_channels(params); | 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 | snd_pcm_format_t format = params_format(params); | 477 | snd_pcm_format_t format = params_format(params); |
| 439 | unsigned int tdm_con = 0; | 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 | /* calculate bck */ | 488 | /* calculate bck */ |
| 450 | tdm_priv->bck_rate = rate * | 489 | tdm_priv->bck_rate = rate * |
| 451 | channels * | 490 | out_channels_per_sdata * |
| 452 | snd_pcm_format_physical_width(format); | 491 | snd_pcm_format_physical_width(format); |
| 453 | 492 | ||
| 454 | if (tdm_priv->bck_rate > tdm_priv->mclk_rate) | 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 | __func__, | 500 | __func__, |
| 462 | tdm_id, rate, channels, format, | 501 | tdm_id, rate, channels, format, |
| 463 | tdm_priv->mclk_rate, tdm_priv->bck_rate); | 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 | /* set tdm */ | 506 | /* set tdm */ |
| 466 | tdm_con = 1 << BCK_INVERSE_SFT; | 507 | if (tdm_priv->bck_invert) |
| 467 | tdm_con |= 1 << LRCK_INVERSE_SFT; | 508 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON3, |
| 468 | tdm_con |= 1 << DELAY_DATA_SFT; | 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 | tdm_con |= 1 << LEFT_ALIGN_SFT; | 523 | tdm_con |= 1 << LEFT_ALIGN_SFT; |
| 470 | tdm_con |= get_tdm_wlen(format) << WLEN_SFT; | 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 | tdm_con |= get_tdm_channel_bck(format) << CHANNEL_BCK_CYCLES_SFT; | 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 | regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); | 527 | regmap_write(afe->regmap, AFE_TDM_CON1, tdm_con); |
| 475 | 528 | ||
| 476 | switch (channels) { | 529 | if (out_channels_per_sdata == 2) { |
| 477 | case 1: | 530 | switch (channels) { |
| 478 | case 2: | 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 | tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; | 563 | tdm_con = TDM_CH_START_O30_O31 << ST_CH_PAIR_SOUT0_SFT; |
| 480 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; | 564 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT1_SFT; |
| 481 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; | 565 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT2_SFT; |
| 482 | tdm_con |= TDM_CH_ZERO << ST_CH_PAIR_SOUT3_SFT; | 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 | regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); | 569 | regmap_write(afe->regmap, AFE_TDM_CON2, tdm_con); |
| 509 | 570 | ||
| 510 | regmap_update_bits(afe->regmap, AFE_HDMI_OUT_CON0, | 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 | return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); | 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 | static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { | 684 | static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { |
| 577 | .hw_params = mtk_dai_tdm_hw_params, | 685 | .hw_params = mtk_dai_tdm_hw_params, |
| 578 | .trigger = mtk_dai_tdm_trigger, | 686 | .trigger = mtk_dai_tdm_trigger, |
| 579 | .set_sysclk = mtk_dai_tdm_set_sysclk, | 687 | .set_sysclk = mtk_dai_tdm_set_sysclk, |
| 688 | .set_fmt = mtk_dai_tdm_set_fmt, | ||
| 580 | }; | 689 | }; |
| 581 | 690 | ||
| 582 | /* dai driver */ | 691 | /* dai driver */ |
| @@ -15,7 +15,22 @@ · 14 unmodified lines | |||
| 15 | #include "mt8183-afe-common.h" | 15 | #include "mt8183-afe-common.h" |
| 16 | #include "../../codecs/ts3a227e.h" | 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 | static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, | 35 | static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, |
| 21 | struct snd_pcm_hw_params *params) | 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 | return 0; | 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 | static int | 64 | static int |
| 60 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( | 65 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( |
| 61 | struct snd_pcm_substream *substream) | 66 | struct snd_pcm_substream *substream) |
| @@ -183,6 +188,47 @@ SND_SOC_DAILINK_DEFS(tdm, · 121 unmodified lines | |||
| 183 | DAILINK_COMP_ARRAY(COMP_DUMMY()), | 188 | DAILINK_COMP_ARRAY(COMP_DUMMY()), |
| 184 | DAILINK_COMP_ARRAY(COMP_EMPTY())); | 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 | static struct snd_soc_dai_link | 232 | static struct snd_soc_dai_link |
| 187 | mt8183_mt6358_ts3a227_max98357_dai_links[] = { | 233 | mt8183_mt6358_ts3a227_max98357_dai_links[] = { |
| 188 | /* FE */ | 234 | /* FE */ |
| @@ -333,33 +379,30 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = { · 144 unmodified lines | |||
| 333 | { | 379 | { |
| 334 | .name = "TDM", | 380 | .name = "TDM", |
| 335 | .no_pcm = 1, | 381 | .no_pcm = 1, |
| 382 | .dai_fmt = SND_SOC_DAIFMT_I2S | | ||
| 383 | SND_SOC_DAIFMT_IB_IF | | ||
| 384 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 336 | .dpcm_playback = 1, | 385 | .dpcm_playback = 1, |
| 337 | .ignore_suspend = 1, | 386 | .ignore_suspend = 1, |
| 387 | .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, | ||
| 388 | .ops = &mt8183_mt6358_tdm_ops, | ||
| 338 | SND_SOC_DAILINK_REG(tdm), | 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 | static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { | 393 | static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { |
| 351 | .name = "mt8183_mt6358_ts3a227_max98357", | 394 | .name = "mt8183_mt6358_ts3a227_max98357", |
| 352 | .owner = THIS_MODULE, | 395 | .owner = THIS_MODULE, |
| 353 | .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, | 396 | .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, |
| 354 | .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), | 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 | static int | 400 | static int |
| 360 | mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) | 401 | mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) |
| 361 | { | 402 | { |
| 362 | int ret; | 403 | int ret; |
| 404 | struct mt8183_mt6358_ts3a227_max98357_priv *priv = | ||
| 405 | snd_soc_card_get_drvdata(component->card); | ||
| 363 | 406 | ||
| 364 | /* Enable Headset and 4 Buttons Jack detection */ | 407 | /* Enable Headset and 4 Buttons Jack detection */ |
| 365 | ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, | 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 | SND_JACK_HEADSET | | 410 | SND_JACK_HEADSET | |
| 368 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | | 411 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | |
| 369 | SND_JACK_BTN_2 | SND_JACK_BTN_3, | 412 | SND_JACK_BTN_2 | SND_JACK_BTN_3, |
| 370 | &headset_jack, | 413 | &priv->headset_jack, |
| 371 | NULL, 0); | 414 | NULL, 0); |
| 372 | if (ret) | 415 | if (ret) |
| 373 | return ret; | 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 | return ret; | 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 | static int | 428 | static int |
| 381 | mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) | 429 | mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) |
| 382 | { | 430 | { |
| 383 | struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; | 431 | struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; |
| 384 | struct device_node *platform_node; | 432 | struct device_node *platform_node; |
| 385 | struct snd_soc_dai_link *dai_link; | 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 | int i; | 436 | int i; |
| 388 | 437 | ||
| 389 | card->dev = &pdev->dev; | 438 | card->dev = &pdev->dev; |
| @@ -401,21 +450,53 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 401 | dai_link->platforms->of_node = platform_node; | 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 | of_parse_phandle(pdev->dev.of_node, | 454 | of_parse_phandle(pdev->dev.of_node, |
| 406 | "mediatek,headset-codec", 0); | 455 | "mediatek,headset-codec", 0); |
| 407 | if (!mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node) { | 456 | if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) { |
| 408 | dev_err(&pdev->dev, | 457 | card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev; |
| 409 | "Property 'mediatek,headset-codec' missing/invalid\n"); | 458 | card->num_aux_devs = 1; |
| 410 | return -EINVAL; | ||
| 411 | } | 459 | } |
| 412 | 460 | ||
| 413 | default_pins = | 461 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 414 | devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); | 462 | if (!priv) |
| 415 | if (IS_ERR(default_pins)) { | 463 | return -ENOMEM; |
| 416 | dev_err(&pdev->dev, "%s set pins failed\n", | 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 | __func__); | 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 | return devm_snd_soc_register_card(&pdev->dev, card); | 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 | MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); | 526 | MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); |
| 446 | MODULE_LICENSE("GPL v2"); | 527 | MODULE_LICENSE("GPL v2"); |
| 447 | MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); | 528 | MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card"); |
| 448 | |||
| @@ -413,6 +413,11 @@ · 412 unmodified lines | |||
| 413 | #define AFE_MAX_REGISTER AFE_GENERAL2_ASRC_2CH_CON13 | 413 | #define AFE_MAX_REGISTER AFE_GENERAL2_ASRC_2CH_CON13 |
| 414 | #define AFE_IRQ_STATUS_BITS 0x1fff | 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 | /* AFE_DAC_CON0 */ | 421 | /* AFE_DAC_CON0 */ |
| 417 | #define AWB2_ON_SFT 29 | 422 | #define AWB2_ON_SFT 29 |
| 418 | #define AWB2_ON_MASK 0x1 | 423 | #define AWB2_ON_MASK 0x1 |
| @@ -1596,9 +1601,6 @@ · 1177 unmodified lines | |||
| 1596 | #define TDM_EN_SFT 0 | 1601 | #define TDM_EN_SFT 0 |
| 1597 | #define TDM_EN_MASK 0x1 | 1602 | #define TDM_EN_MASK 0x1 |
| 1598 | #define TDM_EN_MASK_SFT (0x1 << 0) | 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 | #define LRCK_INVERSE_SFT 2 | 1604 | #define LRCK_INVERSE_SFT 2 |
| 1603 | #define LRCK_INVERSE_MASK 0x1 | 1605 | #define LRCK_INVERSE_MASK 0x1 |
| 1604 | #define LRCK_INVERSE_MASK_SFT (0x1 << 2) | 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 | struct snd_soc_card *card = &priv->card; | 111 | struct snd_soc_card *card = &priv->card; |
| 112 | struct snd_soc_dai_link *link; | 112 | struct snd_soc_dai_link *link; |
| 113 | struct snd_soc_dai_link_component *codec; | 113 | struct snd_soc_dai_link_component *codec; |
| 114 | struct snd_soc_aux_dev *aux; | ||
| 114 | int i, j; | 115 | int i, j; |
| 115 | 116 | ||
| 116 | if (card->dai_link) { | 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 | if (card->aux_dev) { | 126 | if (card->aux_dev) { |
| 126 | for (i = 0; i < card->num_aux_devs; i++) | 127 | for_each_card_pre_auxs(card, i, aux) |
| 127 | of_node_put(card->aux_dev[i].codec_of_node); | 128 | of_node_put(aux->dlc.of_node); |
| 128 | } | 129 | } |
| 129 | 130 | ||
| 130 | kfree(card->dai_link); | 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 | card->aux_dev = aux; | 158 | card->aux_dev = aux; |
| 158 | card->num_aux_devs = num; | 159 | card->num_aux_devs = num; |
| 159 | 160 | ||
| 160 | for (i = 0; i < card->num_aux_devs; i++, aux++) { | 161 | for_each_card_pre_auxs(card, i, aux) { |
| 161 | aux->codec_of_node = | 162 | aux->dlc.of_node = |
| 162 | of_parse_phandle(node, "audio-aux-devs", i); | 163 | of_parse_phandle(node, "audio-aux-devs", i); |
| 163 | if (!aux->codec_of_node) | 164 | if (!aux->dlc.of_node) |
| 164 | return -EINVAL; | 165 | return -EINVAL; |
| 165 | } | 166 | } |
| 166 | 167 | ||
| @@ -306,7 +306,7 @@ static const struct regmap_config axg_fifo_regmap_cfg = { · 305 unmodified lines | |||
| 306 | .reg_bits = 32, | 306 | .reg_bits = 32, |
| 307 | .val_bits = 32, | 307 | .val_bits = 32, |
| 308 | .reg_stride = 4, | 308 | .reg_stride = 4, |
| 309 | .max_register = FIFO_INIT_ADDR, | 309 | .max_register = FIFO_CTRL2, |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | int axg_fifo_probe(struct platform_device *pdev) | 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 | struct device *dev = &pdev->dev; | 314 | struct device *dev = &pdev->dev; |
| 315 | const struct axg_fifo_match_data *data; | 315 | const struct axg_fifo_match_data *data; |
| 316 | struct axg_fifo *fifo; | 316 | struct axg_fifo *fifo; |
| 317 | struct resource *res; | ||
| 318 | void __iomem *regs; | 317 | void __iomem *regs; |
| 319 | 318 | ||
| 320 | data = of_device_get_match_data(dev); | 319 | data = of_device_get_match_data(dev); |
| @@ -328,8 +327,7 @@ int axg_fifo_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 328 | return -ENOMEM; | 327 | return -ENOMEM; |
| 329 | platform_set_drvdata(pdev, fifo); | 328 | platform_set_drvdata(pdev, fifo); |
| 330 | 329 | ||
| 331 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 330 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 332 | regs = devm_ioremap_resource(dev, res); | ||
| 333 | if (IS_ERR(regs)) | 331 | if (IS_ERR(regs)) |
| 334 | return PTR_ERR(regs); | 332 | return PTR_ERR(regs); |
| 335 | 333 | ||
| @@ -61,6 +61,7 @@ struct snd_soc_pcm_runtime; · 60 unmodified lines | |||
| 61 | #define STATUS1_INT_STS(x) ((x) << 0) | 61 | #define STATUS1_INT_STS(x) ((x) << 0) |
| 62 | #define FIFO_STATUS2 0x18 | 62 | #define FIFO_STATUS2 0x18 |
| 63 | #define FIFO_INIT_ADDR 0x24 | 63 | #define FIFO_INIT_ADDR 0x24 |
| 64 | #define FIFO_CTRL2 0x28 | ||
| 64 | 65 | ||
| 65 | struct axg_fifo { | 66 | struct axg_fifo { |
| 66 | struct regmap *map; | 67 | struct regmap *map; |
| @@ -23,6 +23,12 @@ · 22 unmodified lines | |||
| 23 | #define CTRL0_SEL3_SHIFT 8 | 23 | #define CTRL0_SEL3_SHIFT 8 |
| 24 | #define CTRL0_SEL3_EN_SHIFT 11 | 24 | #define CTRL0_SEL3_EN_SHIFT 11 |
| 25 | #define CTRL1_FRDDR_FORCE_FINISH BIT(12) | 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 | static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream, | 33 | static int g12a_frddr_dai_prepare(struct snd_pcm_substream *substream, |
| 28 | struct snd_soc_dai *dai) | 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 | static const char * const axg_frddr_sel_texts[] = { | 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 | static SOC_ENUM_SINGLE_DECL(axg_frddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, | 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 | SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0), | 126 | SND_SOC_DAPM_AIF_OUT("OUT 1", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 121 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), | 127 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 122 | SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), | 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 | static const struct snd_soc_dapm_route axg_frddr_dapm_routes[] = { | 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 | { "OUT 1", "OUT 1", "SINK SEL" }, | 138 | { "OUT 1", "OUT 1", "SINK SEL" }, |
| 129 | { "OUT 2", "OUT 2", "SINK SEL" }, | 139 | { "OUT 2", "OUT 2", "SINK SEL" }, |
| 130 | { "OUT 3", "OUT 3", "SINK SEL" }, | 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 | static const struct snd_soc_component_driver axg_frddr_component_drv = { | 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 | .pcm_new = axg_frddr_pcm_new, | 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 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel1_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, | 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 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel2_enum, FIFO_CTRL0, CTRL0_SEL2_SHIFT, | 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 | static SOC_ENUM_SINGLE_DECL(g12a_frddr_sel3_enum, FIFO_CTRL0, CTRL0_SEL3_SHIFT, | 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 | static const struct snd_kcontrol_new g12a_frddr_out1_demux = | 186 | static const struct snd_kcontrol_new g12a_frddr_out1_demux = |
| 177 | SOC_DAPM_ENUM("Output Src 1", g12a_frddr_sel1_enum); | 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 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), | 221 | SND_SOC_DAPM_AIF_OUT("OUT 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 212 | SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), | 222 | SND_SOC_DAPM_AIF_OUT("OUT 3", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 213 | SND_SOC_DAPM_AIF_OUT("OUT 4", NULL, 0, SND_SOC_NOPM, 0, 0), | 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 | static const struct snd_soc_dapm_route g12a_frddr_dapm_routes[] = { | 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 | { "OUT 2", "OUT 2", "SINK 1 SEL" }, | 241 | { "OUT 2", "OUT 2", "SINK 1 SEL" }, |
| 229 | { "OUT 3", "OUT 3", "SINK 1 SEL" }, | 242 | { "OUT 3", "OUT 3", "SINK 1 SEL" }, |
| 230 | { "OUT 4", "OUT 4", "SINK 1 SEL" }, | 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 | { "OUT 0", "OUT 0", "SINK 2 SEL" }, | 247 | { "OUT 0", "OUT 0", "SINK 2 SEL" }, |
| 232 | { "OUT 1", "OUT 1", "SINK 2 SEL" }, | 248 | { "OUT 1", "OUT 1", "SINK 2 SEL" }, |
| 233 | { "OUT 2", "OUT 2", "SINK 2 SEL" }, | 249 | { "OUT 2", "OUT 2", "SINK 2 SEL" }, |
| 234 | { "OUT 3", "OUT 3", "SINK 2 SEL" }, | 250 | { "OUT 3", "OUT 3", "SINK 2 SEL" }, |
| 235 | { "OUT 4", "OUT 4", "SINK 2 SEL" }, | 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 | { "OUT 0", "OUT 0", "SINK 3 SEL" }, | 255 | { "OUT 0", "OUT 0", "SINK 3 SEL" }, |
| 237 | { "OUT 1", "OUT 1", "SINK 3 SEL" }, | 256 | { "OUT 1", "OUT 1", "SINK 3 SEL" }, |
| 238 | { "OUT 2", "OUT 2", "SINK 3 SEL" }, | 257 | { "OUT 2", "OUT 2", "SINK 3 SEL" }, |
| 239 | { "OUT 3", "OUT 3", "SINK 3 SEL" }, | 258 | { "OUT 3", "OUT 3", "SINK 3 SEL" }, |
| 240 | { "OUT 4", "OUT 4", "SINK 3 SEL" }, | 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 | static const struct snd_soc_component_driver g12a_frddr_component_drv = { | 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 | .dai_drv = &g12a_frddr_dai_drv | 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 | static const struct of_device_id axg_frddr_of_match[] = { | 342 | static const struct of_device_id axg_frddr_of_match[] = { |
| 257 | { | 343 | { |
| 258 | .compatible = "amlogic,axg-frddr", | 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 | .compatible = "amlogic,g12a-frddr", | 347 | .compatible = "amlogic,g12a-frddr", |
| 262 | .data = &g12a_frddr_match_data, | 348 | .data = &g12a_frddr_match_data, |
| 349 | }, { | ||
| 350 | .compatible = "amlogic,sm1-frddr", | ||
| 351 | .data = &sm1_frddr_match_data, | ||
| 263 | }, {} | 352 | }, {} |
| 264 | }; | 353 | }; |
| 265 | MODULE_DEVICE_TABLE(of, axg_frddr_of_match); | 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 | struct device *dev = &pdev->dev; | 586 | struct device *dev = &pdev->dev; |
| 587 | struct axg_pdm *priv; | 587 | struct axg_pdm *priv; |
| 588 | struct resource *res; | ||
| 589 | void __iomem *regs; | 588 | void __iomem *regs; |
| 590 | int ret; | 589 | int ret; |
| 591 | 590 | ||
| @@ -600,8 +599,7 @@ static int axg_pdm_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 600 | return -ENODEV; | 599 | return -ENODEV; |
| 601 | } | 600 | } |
| 602 | 601 | ||
| 603 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 602 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 604 | regs = devm_ioremap_resource(dev, res); | ||
| 605 | if (IS_ERR(regs)) | 603 | if (IS_ERR(regs)) |
| 606 | return PTR_ERR(regs); | 604 | return PTR_ERR(regs); |
| 607 | 605 | ||
| @@ -453,7 +453,6 @@ static int axg_spdifin_probe(struct platform_device *pdev) · 452 unmodified lines | |||
| 453 | struct device *dev = &pdev->dev; | 453 | struct device *dev = &pdev->dev; |
| 454 | struct axg_spdifin *priv; | 454 | struct axg_spdifin *priv; |
| 455 | struct snd_soc_dai_driver *dai_drv; | 455 | struct snd_soc_dai_driver *dai_drv; |
| 456 | struct resource *res; | ||
| 457 | void __iomem *regs; | 456 | void __iomem *regs; |
| 458 | int ret; | 457 | int ret; |
| 459 | 458 | ||
| @@ -468,8 +467,7 @@ static int axg_spdifin_probe(struct platform_device *pdev) · 8 unmodified lines | |||
| 468 | return -ENODEV; | 467 | return -ENODEV; |
| 469 | } | 468 | } |
| 470 | 469 | ||
| 471 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 470 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 472 | regs = devm_ioremap_resource(dev, res); | ||
| 473 | if (IS_ERR(regs)) | 471 | if (IS_ERR(regs)) |
| 474 | return PTR_ERR(regs); | 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 | struct device *dev = &pdev->dev; | 402 | struct device *dev = &pdev->dev; |
| 403 | struct axg_spdifout *priv; | 403 | struct axg_spdifout *priv; |
| 404 | struct resource *res; | ||
| 405 | void __iomem *regs; | 404 | void __iomem *regs; |
| 406 | int ret; | 405 | int ret; |
| 407 | 406 | ||
| @@ -410,8 +409,7 @@ static int axg_spdifout_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 410 | return -ENOMEM; | 409 | return -ENOMEM; |
| 411 | platform_set_drvdata(pdev, priv); | 410 | platform_set_drvdata(pdev, priv); |
| 412 | 411 | ||
| 413 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 412 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 414 | regs = devm_ioremap_resource(dev, res); | ||
| 415 | if (IS_ERR(regs)) | 413 | if (IS_ERR(regs)) |
| 416 | return PTR_ERR(regs); | 414 | return PTR_ERR(regs); |
| 417 | 415 | ||
| @@ -253,7 +253,6 @@ int axg_tdm_formatter_probe(struct platform_device *pdev) · 252 unmodified lines | |||
| 253 | struct device *dev = &pdev->dev; | 253 | struct device *dev = &pdev->dev; |
| 254 | const struct axg_tdm_formatter_driver *drv; | 254 | const struct axg_tdm_formatter_driver *drv; |
| 255 | struct axg_tdm_formatter *formatter; | 255 | struct axg_tdm_formatter *formatter; |
| 256 | struct resource *res; | ||
| 257 | void __iomem *regs; | 256 | void __iomem *regs; |
| 258 | int ret; | 257 | int ret; |
| 259 | 258 | ||
| @@ -269,8 +268,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 269 | platform_set_drvdata(pdev, formatter); | 268 | platform_set_drvdata(pdev, formatter); |
| 270 | formatter->drv = drv; | 269 | formatter->drv = drv; |
| 271 | 270 | ||
| 272 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 271 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 273 | regs = devm_ioremap_resource(dev, res); | ||
| 274 | if (IS_ERR(regs)) | 272 | if (IS_ERR(regs)) |
| 275 | return PTR_ERR(regs); | 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 | static const char * const axg_tdmin_sel_texts[] = { | 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 | /* Change to special mux control to reset dapm */ | 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 | static const struct snd_soc_dapm_widget axg_tdmin_dapm_widgets[] = { | 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 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 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 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 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 4", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 172 | SND_SOC_DAPM_AIF_IN("IN 5", 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 | SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_tdmin_in_mux), | 184 | SND_SOC_DAPM_MUX("SRC SEL", SND_SOC_NOPM, 0, 0, &axg_tdmin_in_mux), |
| 174 | SND_SOC_DAPM_PGA_E("DEC", SND_SOC_NOPM, 0, 0, NULL, 0, | 185 | SND_SOC_DAPM_PGA_E("DEC", SND_SOC_NOPM, 0, 0, NULL, 0, |
| 175 | axg_tdm_formatter_event, | 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 | static const struct snd_soc_dapm_route axg_tdmin_dapm_routes[] = { | 191 | static const struct snd_soc_dapm_route axg_tdmin_dapm_routes[] = { |
| 181 | { "SRC SEL", "IN 0", "IN 0" }, | 192 | { "SRC SEL", "IN 0", "IN 0" }, |
| 182 | { "SRC SEL", "IN 1", "IN 1" }, | 193 | { "SRC SEL", "IN 1", "IN 1" }, |
| 183 | { "SRC SEL", "IN 2", "IN 2" }, | 194 | { "SRC SEL", "IN 2", "IN 2" }, |
| 184 | { "SRC SEL", "IN 3", "IN 3" }, | 195 | { "SRC SEL", "IN 3", "IN 3" }, |
| 185 | { "SRC SEL", "IN 4", "IN 4" }, | 196 | { "SRC SEL", "IN 4", "IN 4" }, |
| 186 | { "SRC SEL", "IN 5", "IN 5" }, | 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 | { "DEC", NULL, "SRC SEL" }, | 208 | { "DEC", NULL, "SRC SEL" }, |
| 188 | { "OUT", NULL, "DEC" }, | 209 | { "OUT", NULL, "DEC" }, |
| 189 | }; | 210 | }; |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #define TDMOUT_CTRL1 0x04 | 24 | #define TDMOUT_CTRL1 0x04 |
| 25 | #define TDMOUT_CTRL1_TYPE_MASK GENMASK(6, 4) | 25 | #define TDMOUT_CTRL1_TYPE_MASK GENMASK(6, 4) |
| 26 | #define TDMOUT_CTRL1_TYPE(x) ((x) << 4) | 26 | #define TDMOUT_CTRL1_TYPE(x) ((x) << 4) |
| 27 | #define SM1_TDMOUT_CTRL1_GAIN_EN 7 | ||
| 27 | #define TDMOUT_CTRL1_MSB_POS_MASK GENMASK(12, 8) | 28 | #define TDMOUT_CTRL1_MSB_POS_MASK GENMASK(12, 8) |
| 28 | #define TDMOUT_CTRL1_MSB_POS(x) ((x) << 8) | 29 | #define TDMOUT_CTRL1_MSB_POS(x) ((x) << 8) |
| 29 | #define TDMOUT_CTRL1_SEL_SHIFT 24 | 30 | #define TDMOUT_CTRL1_SEL_SHIFT 24 |
| @@ -51,25 +52,6 @@ static const struct regmap_config axg_tdmout_regmap_cfg = { · 21 unmodified lines | |||
| 51 | .max_register = TDMOUT_MASK_VAL, | 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 | static struct snd_soc_dai * | 55 | static struct snd_soc_dai * |
| 74 | axg_tdmout_get_be(struct snd_soc_dapm_widget *w) | 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 | return axg_tdm_formatter_set_channel_masks(map, ts, TDMOUT_MASK0); | 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 | static const struct snd_soc_dapm_widget axg_tdmout_dapm_widgets[] = { | 201 | static const struct snd_soc_dapm_widget axg_tdmout_dapm_widgets[] = { |
| 201 | SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), | 202 | SND_SOC_DAPM_AIF_IN("IN 0", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 202 | SND_SOC_DAPM_AIF_IN("IN 1", NULL, 0, SND_SOC_NOPM, 0, 0), | 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 | static const struct of_device_id axg_tdmout_of_match[] = { | 317 | static const struct of_device_id axg_tdmout_of_match[] = { |
| 256 | { | 318 | { |
| 257 | .compatible = "amlogic,axg-tdmout", | 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 | .compatible = "amlogic,g12a-tdmout", | 322 | .compatible = "amlogic,g12a-tdmout", |
| 261 | .data = &g12a_tdmout_drv, | 323 | .data = &g12a_tdmout_drv, |
| 324 | }, { | ||
| 325 | .compatible = "amlogic,sm1-tdmout", | ||
| 326 | .data = &sm1_tdmout_drv, | ||
| 262 | }, {} | 327 | }, {} |
| 263 | }; | 328 | }; |
| 264 | MODULE_DEVICE_TABLE(of, axg_tdmout_of_match); | 329 | MODULE_DEVICE_TABLE(of, axg_tdmout_of_match); |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | #define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) | 25 | #define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) |
| 26 | #define CTRL0_TODDR_LSB_POS(x) ((x) << 3) | 26 | #define CTRL0_TODDR_LSB_POS(x) ((x) << 3) |
| 27 | #define CTRL1_TODDR_FORCE_FINISH BIT(25) | 27 | #define CTRL1_TODDR_FORCE_FINISH BIT(25) |
| 28 | #define CTRL1_SEL_SHIFT 28 | ||
| 28 | 29 | ||
| 29 | #define TODDR_MSB_POS 31 | 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 | static const char * const axg_toddr_sel_texts[] = { | 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 | static SOC_ENUM_SINGLE_DECL(axg_toddr_sel_enum, FIFO_CTRL0, CTRL0_SEL_SHIFT, |
| 149 | 0, 1, 2, 3, 4, 6 | 150 | axg_toddr_sel_texts); |
| 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); | ||
| 155 | 151 | ||
| 156 | static const struct snd_kcontrol_new axg_toddr_in_mux = | 152 | static const struct snd_kcontrol_new axg_toddr_in_mux = |
| 157 | SOC_DAPM_ENUM("Input Source", axg_toddr_sel_enum); | 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 | SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), | 159 | SND_SOC_DAPM_AIF_IN("IN 2", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 164 | SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), | 160 | SND_SOC_DAPM_AIF_IN("IN 3", NULL, 0, SND_SOC_NOPM, 0, 0), |
| 165 | SND_SOC_DAPM_AIF_IN("IN 4", NULL, 0, SND_SOC_NOPM, 0, 0), | 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 | SND_SOC_DAPM_AIF_IN("IN 6", NULL, 0, SND_SOC_NOPM, 0, 0), | 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 | static const struct snd_soc_dapm_route axg_toddr_dapm_routes[] = { | 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 | { "SRC SEL", "IN 2", "IN 2" }, | 171 | { "SRC SEL", "IN 2", "IN 2" }, |
| 174 | { "SRC SEL", "IN 3", "IN 3" }, | 172 | { "SRC SEL", "IN 3", "IN 3" }, |
| 175 | { "SRC SEL", "IN 4", "IN 4" }, | 173 | { "SRC SEL", "IN 4", "IN 4" }, |
| 174 | { "SRC SEL", "IN 5", "IN 5" }, | ||
| 176 | { "SRC SEL", "IN 6", "IN 6" }, | 175 | { "SRC SEL", "IN 6", "IN 6" }, |
| 176 | { "SRC SEL", "IN 7", "IN 7" }, | ||
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | static const struct snd_soc_component_driver axg_toddr_component_drv = { | 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 | .dai_drv = &g12a_toddr_dai_drv | 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 | static const struct of_device_id axg_toddr_of_match[] = { | 289 | static const struct of_device_id axg_toddr_of_match[] = { |
| 226 | { | 290 | { |
| 227 | .compatible = "amlogic,axg-toddr", | 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 | .compatible = "amlogic,g12a-toddr", | 294 | .compatible = "amlogic,g12a-toddr", |
| 231 | .data = &g12a_toddr_match_data, | 295 | .data = &g12a_toddr_match_data, |
| 296 | }, { | ||
| 297 | .compatible = "amlogic,sm1-toddr", | ||
| 298 | .data = &sm1_toddr_match_data, | ||
| 232 | }, {} | 299 | }, {} |
| 233 | }; | 300 | }; |
| 234 | MODULE_DEVICE_TABLE(of, axg_toddr_of_match); | 301 | MODULE_DEVICE_TABLE(of, axg_toddr_of_match); |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | |||
| 28 | #define CTRL0_SPDIF_CLK_SEL BIT(0) | 28 | #define CTRL0_SPDIF_CLK_SEL BIT(0) |
| 29 | 29 | ||
| 30 | struct g12a_tohdmitx_input { | 30 | struct g12a_tohdmitx_input { |
| 31 | struct snd_pcm_hw_params params; | 31 | struct snd_soc_pcm_stream params; |
| 32 | unsigned int fmt; | 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 | struct g12a_tohdmitx_input *data = dai->playback_dma_data; | 226 | struct g12a_tohdmitx_input *data = dai->playback_dma_data; |
| 227 | 227 | ||
| 228 | /* Save the stream params for the downstream link */ | 228 | data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params)); |
| 229 | memcpy(&data->params, params, sizeof(*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 | return 0; | 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 | static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai, | 240 | static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai, |
| 250 | unsigned int fmt) | 241 | unsigned int fmt) |
| @@ -266,6 +257,14 @@ static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream, · 15 unmodified lines | |||
| 266 | if (!in_data) | 257 | if (!in_data) |
| 267 | return -ENODEV; | 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 | if (!in_data->fmt) | 268 | if (!in_data->fmt) |
| 270 | return 0; | 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 | static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = { | 279 | static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = { |
| 281 | .hw_params = g12a_tohdmitx_output_hw_params, | ||
| 282 | .startup = g12a_tohdmitx_output_startup, | 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 | static int g12a_tohdmitx_probe(struct platform_device *pdev) | 376 | static int g12a_tohdmitx_probe(struct platform_device *pdev) |
| 379 | { | 377 | { |
| 380 | struct device *dev = &pdev->dev; | 378 | struct device *dev = &pdev->dev; |
| 381 | struct resource *res; | ||
| 382 | void __iomem *regs; | 379 | void __iomem *regs; |
| 383 | struct regmap *map; | 380 | struct regmap *map; |
| 384 | 381 | ||
| 385 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 382 | regs = devm_platform_ioremap_resource(pdev, 0); |
| 386 | regs = devm_ioremap_resource(dev, res); | ||
| 387 | if (IS_ERR(regs)) | 383 | if (IS_ERR(regs)) |
| 388 | return PTR_ERR(regs); | 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 | static int mxs_saif_probe(struct platform_device *pdev) | 732 | static int mxs_saif_probe(struct platform_device *pdev) |
| 733 | { | 733 | { |
| 734 | struct device_node *np = pdev->dev.of_node; | 734 | struct device_node *np = pdev->dev.of_node; |
| 735 | struct resource *iores; | ||
| 736 | struct mxs_saif *saif; | 735 | struct mxs_saif *saif; |
| 737 | int irq, ret = 0; | 736 | int irq, ret = 0; |
| 738 | struct device_node *master; | 737 | struct device_node *master; |
| @@ -786,19 +785,13 @@ static int mxs_saif_probe(struct platform_device *pdev) · 47 unmodified lines | |||
| 786 | return ret; | 785 | return ret; |
| 787 | } | 786 | } |
| 788 | 787 | ||
| 789 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 788 | saif->base = devm_platform_ioremap_resource(pdev, 0); |
| 790 | |||
| 791 | saif->base = devm_ioremap_resource(&pdev->dev, iores); | ||
| 792 | if (IS_ERR(saif->base)) | 789 | if (IS_ERR(saif->base)) |
| 793 | return PTR_ERR(saif->base); | 790 | return PTR_ERR(saif->base); |
| 794 | 791 | ||
| 795 | irq = platform_get_irq(pdev, 0); | 792 | irq = platform_get_irq(pdev, 0); |
| 796 | if (irq < 0) { | 793 | if (irq < 0) |
| 797 | ret = irq; | 794 | return irq; |
| 798 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | ||
| 799 | ret); | ||
| 800 | return ret; | ||
| 801 | } | ||
| 802 | 795 | ||
| 803 | saif->dev = &pdev->dev; | 796 | saif->dev = &pdev->dev; |
| 804 | ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0, | 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 | static int asoc_mmp_sspa_probe(struct platform_device *pdev) | 399 | static int asoc_mmp_sspa_probe(struct platform_device *pdev) |
| 400 | { | 400 | { |
| 401 | struct sspa_priv *priv; | 401 | struct sspa_priv *priv; |
| 402 | struct resource *res; | ||
| 403 | 402 | ||
| 404 | priv = devm_kzalloc(&pdev->dev, | 403 | priv = devm_kzalloc(&pdev->dev, |
| 405 | sizeof(struct sspa_priv), GFP_KERNEL); | 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 | if (priv->dma_params == NULL) | 416 | if (priv->dma_params == NULL) |
| 418 | return -ENOMEM; | 417 | return -ENOMEM; |
| 419 | 418 | ||
| 420 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 419 | priv->sspa->mmio_base = devm_platform_ioremap_resource(pdev, 0); |
| 421 | priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res); | ||
| 422 | if (IS_ERR(priv->sspa->mmio_base)) | 420 | if (IS_ERR(priv->sspa->mmio_base)) |
| 423 | return PTR_ERR(priv->sspa->mmio_base); | 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 | link->num_cpus = 1; | 53 | link->num_cpus = 1; |
| 54 | link->num_platforms = 1; | 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 | cpu = of_get_child_by_name(np, "cpu"); | 62 | cpu = of_get_child_by_name(np, "cpu"); |
| 57 | platform = of_get_child_by_name(np, "platform"); | 63 | platform = of_get_child_by_name(np, "platform"); |
| 58 | codec = of_get_child_by_name(np, "codec"); | 64 | codec = of_get_child_by_name(np, "codec"); |
| 59 | 65 | ||
| 60 | if (!cpu) { | 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 | ret = -EINVAL; | 68 | ret = -EINVAL; |
| 63 | goto err; | 69 | goto err; |
| 64 | } | 70 | } |
| @@ -66,7 +72,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 1 unmodified line | |||
| 66 | ret = of_parse_phandle_with_args(cpu, "sound-dai", | 72 | ret = of_parse_phandle_with_args(cpu, "sound-dai", |
| 67 | "#sound-dai-cells", 0, &args); | 73 | "#sound-dai-cells", 0, &args); |
| 68 | if (ret) { | 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 | goto err; | 76 | goto err; |
| 71 | } | 77 | } |
| 72 | link->cpus->of_node = args.np; | 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 | ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name); | 81 | ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name); |
| 76 | if (ret) { | 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 | goto err; | 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 | "sound-dai", | 89 | "sound-dai", |
| 84 | 0); | 90 | 0); |
| 85 | if (!link->platforms->of_node) { | 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 | ret = -EINVAL; | 93 | ret = -EINVAL; |
| 88 | goto err; | 94 | goto err; |
| 89 | } | 95 | } |
| 90 | 96 | ||
| 91 | ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); | 97 | ret = snd_soc_of_get_dai_link_codecs(dev, codec, link); |
| 92 | if (ret < 0) { | 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 | goto err; | 100 | goto err; |
| 95 | } | 101 | } |
| 96 | link->no_pcm = 1; | 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 | link->ignore_suspend = 1; | 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 | link->nonatomic = 1; | 119 | link->nonatomic = 1; |
| 120 | link->dpcm_playback = 1; | 120 | link->dpcm_playback = 1; |
| 121 | link->dpcm_capture = 1; | 121 | link->dpcm_capture = 1; |
| @@ -564,11 +564,8 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev) · 563 unmodified lines | |||
| 564 | int ret; | 564 | int ret; |
| 565 | 565 | ||
| 566 | drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); | 566 | drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); |
| 567 | if (drvdata->lpaif_irq < 0) { | 567 | if (drvdata->lpaif_irq < 0) |
| 568 | dev_err(&pdev->dev, "error getting irq handle: %d\n", | ||
| 569 | drvdata->lpaif_irq); | ||
| 570 | return -ENODEV; | 568 | return -ENODEV; |
| 571 | } | ||
| 572 | 569 | ||
| 573 | /* ensure audio hardware is disabled */ | 570 | /* ensure audio hardware is disabled */ |
| 574 | ret = regmap_write(drvdata->lpaif_map, | 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 | struct rk_i2s_dev *i2s = to_info(cpu_dai); | 419 | struct rk_i2s_dev *i2s = to_info(cpu_dai); |
| 420 | int ret; | 420 | int ret; |
| 421 | 421 | ||
| 422 | if (freq == 0) | ||
| 423 | return 0; | ||
| 424 | |||
| 422 | ret = clk_set_rate(i2s->mclk, freq); | 425 | ret = clk_set_rate(i2s->mclk, freq); |
| 423 | if (ret) | 426 | if (ret) |
| 424 | dev_err(i2s->dev, "Fail to set mclk %d\n", ret); | 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 | static const struct snd_soc_dapm_route rk_audio_map[] = { | 46 | static const struct snd_soc_dapm_route rk_audio_map[] = { |
| 47 | {"IN34", NULL, "Headset Mic"}, | 47 | {"IN34", NULL, "Headset Mic"}, |
| 48 | {"IN34", NULL, "MICBIAS"}, | ||
| 49 | {"Headset Mic", NULL, "MICBIAS"}, | 48 | {"Headset Mic", NULL, "MICBIAS"}, |
| 50 | {"DMICL", NULL, "Int Mic"}, | 49 | {"DMICL", NULL, "Int Mic"}, |
| 51 | {"Headphone", NULL, "HPL"}, | 50 | {"Headphone", NULL, "HPL"}, |
| @@ -172,7 +171,7 @@ static struct snd_soc_dai_link rk_dailink = { · 120 unmodified lines | |||
| 172 | static int rk_98090_headset_init(struct snd_soc_component *component); | 171 | static int rk_98090_headset_init(struct snd_soc_component *component); |
| 173 | 172 | ||
| 174 | static struct snd_soc_aux_dev rk_98090_headset_dev = { | 173 | static struct snd_soc_aux_dev rk_98090_headset_dev = { |
| 175 | .name = "Headset Chip", | 174 | .dlc = COMP_EMPTY(), |
| 176 | .init = rk_98090_headset_init, | 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 | rk_dailink.platforms->of_node = rk_dailink.cpus->of_node; | 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 | "rockchip,headset-codec", 0); | 241 | "rockchip,headset-codec", 0); |
| 243 | if (!rk_98090_headset_dev.codec_of_node) { | 242 | if (!rk_98090_headset_dev.dlc.of_node) { |
| 244 | dev_err(&pdev->dev, | 243 | dev_err(&pdev->dev, |
| 245 | "Property 'rockchip,headset-codec' missing/invalid\n"); | 244 | "Property 'rockchip,headset-codec' missing/invalid\n"); |
| 246 | return -EINVAL; | 245 | return -EINVAL; |
| @@ -297,8 +297,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { · 296 unmodified lines | |||
| 297 | 297 | ||
| 298 | static struct snd_soc_aux_dev neo1973_aux_devs[] = { | 298 | static struct snd_soc_aux_dev neo1973_aux_devs[] = { |
| 299 | { | 299 | { |
| 300 | .name = "dfbmcs320", | 300 | .dlc = COMP_AUX("dfbmcs320.0"), |
| 301 | .codec_name = "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 | static struct snd_soc_aux_dev speyside_aux_dev[] = { | 241 | static struct snd_soc_aux_dev speyside_aux_dev[] = { |
| 242 | { | 242 | { |
| 243 | .name = "wm9081", | 243 | .dlc = COMP_AUX("wm9081.1-006c"), |
| 244 | .codec_name = "wm9081.1-006c", | ||
| 245 | .init = speyside_wm9081_init, | 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 | static int tm2_late_probe(struct snd_soc_card *card) | 307 | static int tm2_late_probe(struct snd_soc_card *card) |
| 308 | { | 308 | { |
| 309 | struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); | 309 | struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card); |
| 310 | struct snd_soc_dai_link_component dlc = { 0 }; | ||
| 311 | unsigned int ch_map[] = { 0, 1 }; | 310 | unsigned int ch_map[] = { 0, 1 }; |
| 312 | struct snd_soc_dai *amp_pdm_dai; | 311 | struct snd_soc_dai *amp_pdm_dai; |
| 313 | struct snd_soc_pcm_runtime *rtd; | 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 | return ret; | 333 | return ret; |
| 335 | } | 334 | } |
| 336 | 335 | ||
| 337 | dlc.of_node = tm2_speaker_amp_dev.codec_of_node; | 336 | amp_pdm_dai = snd_soc_find_dai(&tm2_speaker_amp_dev.dlc); |
| 338 | amp_pdm_dai = snd_soc_find_dai(&dlc); | ||
| 339 | if (!amp_pdm_dai) | 337 | if (!amp_pdm_dai) |
| 340 | return -ENODEV; | 338 | return -ENODEV; |
| 341 | 339 | ||
| @@ -532,9 +530,9 @@ static int tm2_probe(struct platform_device *pdev) · 190 unmodified lines | |||
| 532 | return ret; | 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 | "audio-amplifier", 0); | 534 | "audio-amplifier", 0); |
| 537 | if (!card->aux_dev[0].codec_of_node) { | 535 | if (!card->aux_dev[0].dlc.of_node) { |
| 538 | dev_err(dev, "audio-amplifier property invalid or missing\n"); | 536 | dev_err(dev, "audio-amplifier property invalid or missing\n"); |
| 539 | return -EINVAL; | 537 | return -EINVAL; |
| 540 | } | 538 | } |
| @@ -623,7 +621,7 @@ dai_node_put: · 82 unmodified lines | |||
| 623 | of_node_put(cpu_dai_node[i]); | 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 | return ret; | 626 | return ret; |
| 629 | } | 627 | } |
| @@ -1421,6 +1421,20 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream, · 1420 unmodified lines | |||
| 1421 | params_buffer_bytes(hw_params)); | 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 | static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) | 1438 | static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) |
| 1425 | { | 1439 | { |
| 1426 | struct snd_soc_dai *dai = rsnd_substream_to_dai(substream); | 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 | static const struct snd_pcm_ops rsnd_pcm_ops = { | 1450 | static const struct snd_pcm_ops rsnd_pcm_ops = { |
| 1437 | .ioctl = snd_pcm_lib_ioctl, | 1451 | .ioctl = snd_pcm_lib_ioctl, |
| 1438 | .hw_params = rsnd_hw_params, | 1452 | .hw_params = rsnd_hw_params, |
| 1439 | .hw_free = snd_pcm_lib_free_pages, | 1453 | .hw_free = rsnd_hw_free, |
| 1440 | .pointer = rsnd_pointer, | 1454 | .pointer = rsnd_pointer, |
| 1441 | }; | 1455 | }; |
| 1442 | 1456 | ||
| @@ -327,6 +327,9 @@ struct rsnd_mod_ops { · 326 unmodified lines | |||
| 327 | int (*cleanup)(struct rsnd_mod *mod, | 327 | int (*cleanup)(struct rsnd_mod *mod, |
| 328 | struct rsnd_dai_stream *io, | 328 | struct rsnd_dai_stream *io, |
| 329 | struct rsnd_priv *priv); | 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 | u32 *(*get_status)(struct rsnd_mod *mod, | 333 | u32 *(*get_status)(struct rsnd_mod *mod, |
| 331 | struct rsnd_dai_stream *io, | 334 | struct rsnd_dai_stream *io, |
| 332 | enum rsnd_mod_type type); | 335 | enum rsnd_mod_type type); |
| @@ -351,12 +354,12 @@ struct rsnd_mod { · 18 unmodified lines | |||
| 351 | * | 354 | * |
| 352 | * B 0: init 1: quit | 355 | * B 0: init 1: quit |
| 353 | * C 0: start 1: stop | 356 | * C 0: start 1: stop |
| 357 | * D 0: hw_params 1: hw_free | ||
| 354 | * | 358 | * |
| 355 | * H is always called (see __rsnd_mod_call) | 359 | * H is always called (see __rsnd_mod_call) |
| 356 | * H 0: probe 1: remove | 360 | * H 0: probe 1: remove |
| 357 | * H 0: pcm_new | 361 | * H 0: pcm_new |
| 358 | * H 0: fallback | 362 | * H 0: fallback |
| 359 | * H 0: hw_params | ||
| 360 | * H 0: pointer | 363 | * H 0: pointer |
| 361 | * H 0: prepare | 364 | * H 0: prepare |
| 362 | * H 0: cleanup | 365 | * H 0: cleanup |
| @@ -365,12 +368,13 @@ struct rsnd_mod { · 2 unmodified lines | |||
| 365 | #define __rsnd_mod_shift_quit 4 | 368 | #define __rsnd_mod_shift_quit 4 |
| 366 | #define __rsnd_mod_shift_start 8 | 369 | #define __rsnd_mod_shift_start 8 |
| 367 | #define __rsnd_mod_shift_stop 8 | 370 | #define __rsnd_mod_shift_stop 8 |
| 371 | #define __rsnd_mod_shift_hw_params 12 | ||
| 372 | #define __rsnd_mod_shift_hw_free 12 | ||
| 368 | #define __rsnd_mod_shift_probe 28 /* always called */ | 373 | #define __rsnd_mod_shift_probe 28 /* always called */ |
| 369 | #define __rsnd_mod_shift_remove 28 /* always called */ | 374 | #define __rsnd_mod_shift_remove 28 /* always called */ |
| 370 | #define __rsnd_mod_shift_irq 28 /* always called */ | 375 | #define __rsnd_mod_shift_irq 28 /* always called */ |
| 371 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ | 376 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ |
| 372 | #define __rsnd_mod_shift_fallback 28 /* always called */ | 377 | #define __rsnd_mod_shift_fallback 28 /* always called */ |
| 373 | #define __rsnd_mod_shift_hw_params 28 /* always called */ | ||
| 374 | #define __rsnd_mod_shift_pointer 28 /* always called */ | 378 | #define __rsnd_mod_shift_pointer 28 /* always called */ |
| 375 | #define __rsnd_mod_shift_prepare 28 /* always called */ | 379 | #define __rsnd_mod_shift_prepare 28 /* always called */ |
| 376 | #define __rsnd_mod_shift_cleanup 28 /* always called */ | 380 | #define __rsnd_mod_shift_cleanup 28 /* always called */ |
| @@ -383,10 +387,11 @@ struct rsnd_mod { · 6 unmodified lines | |||
| 383 | #define __rsnd_mod_add_quit -1 | 387 | #define __rsnd_mod_add_quit -1 |
| 384 | #define __rsnd_mod_add_start 1 | 388 | #define __rsnd_mod_add_start 1 |
| 385 | #define __rsnd_mod_add_stop -1 | 389 | #define __rsnd_mod_add_stop -1 |
| 390 | #define __rsnd_mod_add_hw_params 1 | ||
| 391 | #define __rsnd_mod_add_hw_free -1 | ||
| 386 | #define __rsnd_mod_add_irq 0 | 392 | #define __rsnd_mod_add_irq 0 |
| 387 | #define __rsnd_mod_add_pcm_new 0 | 393 | #define __rsnd_mod_add_pcm_new 0 |
| 388 | #define __rsnd_mod_add_fallback 0 | 394 | #define __rsnd_mod_add_fallback 0 |
| 389 | #define __rsnd_mod_add_hw_params 0 | ||
| 390 | #define __rsnd_mod_add_pointer 0 | 395 | #define __rsnd_mod_add_pointer 0 |
| 391 | 396 | ||
| 392 | #define __rsnd_mod_call_probe 0 | 397 | #define __rsnd_mod_call_probe 0 |
| @@ -402,6 +407,7 @@ struct rsnd_mod { · 9 unmodified lines | |||
| 402 | #define __rsnd_mod_call_fallback 0 | 407 | #define __rsnd_mod_call_fallback 0 |
| 403 | #define __rsnd_mod_call_hw_params 0 | 408 | #define __rsnd_mod_call_hw_params 0 |
| 404 | #define __rsnd_mod_call_pointer 0 | 409 | #define __rsnd_mod_call_pointer 0 |
| 410 | #define __rsnd_mod_call_hw_free 1 | ||
| 405 | 411 | ||
| 406 | #define rsnd_mod_to_priv(mod) ((mod)->priv) | 412 | #define rsnd_mod_to_priv(mod) ((mod)->priv) |
| 407 | #define rsnd_mod_power_on(mod) clk_enable((mod)->clk) | 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 | int ret; | 359 | int ret; |
| 360 | struct sirf_usp *usp; | 360 | struct sirf_usp *usp; |
| 361 | void __iomem *base; | 361 | void __iomem *base; |
| 362 | struct resource *mem_res; | ||
| 363 | 362 | ||
| 364 | usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), | 363 | usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), |
| 365 | GFP_KERNEL); | 364 | GFP_KERNEL); |
| @@ -368,8 +367,7 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 368 | 367 | ||
| 369 | platform_set_drvdata(pdev, usp); | 368 | platform_set_drvdata(pdev, usp); |
| 370 | 369 | ||
| 371 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 370 | base = devm_platform_ioremap_resource(pdev, 0); |
| 372 | base = devm_ioremap_resource(&pdev->dev, mem_res); | ||
| 373 | if (IS_ERR(base)) | 371 | if (IS_ERR(base)) |
| 374 | return PTR_ERR(base); | 372 | return PTR_ERR(base); |
| 375 | usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, | 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 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 80 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 81 | int ret; | 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 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { | 85 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { |
| 86 | ret = cpu_dai->driver->cops->startup(cstream, cpu_dai); | 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 | snd_soc_runtime_activate(rtd, cstream->direction); | 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 | return 0; | 113 | return 0; |
| 114 | 114 | ||
| @@ -118,7 +118,7 @@ machine_err: · 3 unmodified lines | |||
| 118 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) | 118 | if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) |
| 119 | cpu_dai->driver->cops->shutdown(cstream, cpu_dai); | 119 | cpu_dai->driver->cops->shutdown(cstream, cpu_dai); |
| 120 | out: | 120 | out: |
| 121 | mutex_unlock(&rtd->pcm_mutex); | 121 | mutex_unlock(&rtd->card->pcm_mutex); |
| 122 | return ret; | 122 | return ret; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| @@ -224,7 +224,7 @@ static void close_delayed_work(struct work_struct *work) · 99 unmodified lines | |||
| 224 | container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); | 224 | container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); |
| 225 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 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 | dev_dbg(rtd->dev, | 229 | dev_dbg(rtd->dev, |
| 230 | "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n", | 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 | SND_SOC_DAPM_STREAM_STOP); | 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 | static int soc_compr_free(struct snd_compr_stream *cstream) | 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 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 249 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 250 | int stream; | 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 | if (cstream->direction == SND_COMPRESS_PLAYBACK) | 254 | if (cstream->direction == SND_COMPRESS_PLAYBACK) |
| 255 | stream = SNDRV_PCM_STREAM_PLAYBACK; | 255 | stream = SNDRV_PCM_STREAM_PLAYBACK; |
| @@ -292,7 +292,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream) · 36 unmodified lines | |||
| 292 | SND_SOC_DAPM_STREAM_STOP); | 292 | SND_SOC_DAPM_STREAM_STOP); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | mutex_unlock(&rtd->pcm_mutex); | 295 | mutex_unlock(&rtd->card->pcm_mutex); |
| 296 | return 0; | 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 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 375 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 376 | int ret; | 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 | ret = soc_compr_components_trigger(cstream, cmd); | 380 | ret = soc_compr_components_trigger(cstream, cmd); |
| 381 | if (ret < 0) | 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.