Pull sound updates from Takashi Iwai: "A relatively calm release at this time, and no massive code changes are found in the stats, while a wide range of code refactoring and cleanup have been done. Note that this update includes the tree-wide trivial changes for dropping the return value from ISA remove callbacks, too. Below lists up some highlight: ALSA Core: - Support for the software jack injection via debugfs - Fixes for sync_stop PCM operations HD-audio and USB-audio: - A few usual HD-audio device quirks - Updates for Tegra HD-audio - More quirks for Pioneer and other USB-audio devices - Stricter state checks at USB-audio disconnection ASoC: - Continued code refactoring, cleanup and fixes in ASoC core API - A KUnit testsuite for the topology code - Lots of ASoC Intel driver Realtek codec updates, quirk additions and fixes - Support for Ingenic JZ4760(B), Intel AlderLake-P, DT configured nVidia cards, Qualcomm lpass-rx-macro and lpass-tx-macro - Removal of obsolete SIRF prima/atlas, Txx9 and ZTE zx drivers Others: - Drop return value from ISA driver remove callback - Cleanup with DIV_ROUND_UP() macro - FireWire updates, HDSP output loopback support" * tag 'sound-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (322 commits) ALSA: hda: intel-dsp-config: add Alder Lake support ASoC: soc-pcm: fix hw param limits calculation for multi-DAI ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R tablet ASoC: soc-pcm: fix hwparams min/max init for dpcm ALSA: hda/realtek: Quirk for HP Spectre x360 14 amp setup ALSA: usb-audio: Add implicit fb quirk for BOSS GP-10 ALSA: hda: Add another CometLake-H PCI ID ASoC: soc-pcm: add soc_pcm_hw_update_format() ASoC: soc-pcm: add soc_pcm_hw_update_chan() ASoC: soc-pcm: add soc_pcm_hw_update_rate() ASoC: wm_adsp: Remove unused control callback structure ASoC: SOF: relax ABI checks and avoid unnecessary warnings ASoC: codecs: lpass-tx-macro: add dapm widgets and route ASoC: codecs: lpass-tx-macro: add support for lpass tx macro ASoC: qcom: dt-bindings: add bindings for lpass tx macro codec ASoC: codecs: lpass-rx-macro: add iir widgets ASoC: codecs: lpass-rx-macro: add dapm widgets and route ...
Unified · Split
| @@ -71,9 +71,6 @@ properties: · 70 unmodified lines | |||
| 71 | description: CPU to Codec rate channels. | 71 | description: CPU to Codec rate channels. |
| 72 | $ref: /schemas/types.yaml#/definitions/uint32 | 72 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 73 | 73 | ||
| 74 | required: | ||
| 75 | - remote-endpoint | ||
| 76 | |||
| 77 | ports: | 74 | ports: |
| 78 | description: multi OF-Graph subnode | 75 | description: multi OF-Graph subnode |
| 79 | type: object | 76 | type: object |
| @@ -15,9 +15,14 @@ properties: · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | compatible: | 16 | compatible: |
| 17 | oneOf: | 17 | oneOf: |
| 18 | - const: ingenic,jz4770-codec | 18 | - enum: |
| 19 | - const: ingenic,jz4725b-codec | 19 | - ingenic,jz4770-codec |
| 20 | - const: ingenic,jz4740-codec | 20 | - ingenic,jz4760-codec |
| 21 | - ingenic,jz4725b-codec | ||
| 22 | - ingenic,jz4740-codec | ||
| 23 | - items: | ||
| 24 | - const: ingenic,jz4760b-codec | ||
| 25 | - const: ingenic,jz4760-codec | ||
| 21 | 26 | ||
| 22 | reg: | 27 | reg: |
| 23 | maxItems: 1 | 28 | maxItems: 1 |
| @@ -18,6 +18,7 @@ properties: · 17 unmodified lines | |||
| 18 | enum: | 18 | enum: |
| 19 | - intel,keembay-i2s | 19 | - intel,keembay-i2s |
| 20 | - intel,keembay-tdm | 20 | - intel,keembay-tdm |
| 21 | - intel,keembay-hdmi-i2s | ||
| 21 | 22 | ||
| 22 | "#sound-dai-cells": | 23 | "#sound-dai-cells": |
| 23 | const: 0 | 24 | const: 0 |
| @@ -45,6 +46,16 @@ properties: · 21 unmodified lines | |||
| 45 | - const: osc | 46 | - const: osc |
| 46 | - const: apb_clk | 47 | - const: apb_clk |
| 47 | 48 | ||
| 49 | dmas: | ||
| 50 | items: | ||
| 51 | - description: DMA TX channel | ||
| 52 | - description: DMA RX channel | ||
| 53 | |||
| 54 | dma-names: | ||
| 55 | items: | ||
| 56 | - const: tx | ||
| 57 | - const: rx | ||
| 58 | |||
| 48 | required: | 59 | required: |
| 49 | - compatible | 60 | - compatible |
| 50 | - "#sound-dai-cells" | 61 | - "#sound-dai-cells" |
| @@ -70,4 +81,6 @@ examples: · 19 unmodified lines | |||
| 70 | interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; | 81 | interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; |
| 71 | clock-names = "osc", "apb_clk"; | 82 | clock-names = "osc", "apb_clk"; |
| 72 | clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>; | 83 | clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>; |
| 84 | dmas = <&axi_dma0 29 &axi_dma0 33>; | ||
| 85 | dma-names = "tx", "rx"; | ||
| 73 | }; | 86 | }; |
| @@ -23,6 +23,10 @@ properties: · 22 unmodified lines | |||
| 23 | $ref: "/schemas/types.yaml#/definitions/phandle" | 23 | $ref: "/schemas/types.yaml#/definitions/phandle" |
| 24 | description: The phandle of MT8192 ASoC platform. | 24 | description: The phandle of MT8192 ASoC platform. |
| 25 | 25 | ||
| 26 | mediatek,hdmi-codec: | ||
| 27 | $ref: "/schemas/types.yaml#/definitions/phandle" | ||
| 28 | description: The phandle of HDMI codec. | ||
| 29 | |||
| 26 | additionalProperties: false | 30 | additionalProperties: false |
| 27 | 31 | ||
| 28 | required: | 32 | required: |
| @@ -35,6 +39,7 @@ examples: · 6 unmodified lines | |||
| 35 | sound: mt8192-sound { | 39 | sound: mt8192-sound { |
| 36 | compatible = "mediatek,mt8192_mt6359_rt1015_rt5682"; | 40 | compatible = "mediatek,mt8192_mt6359_rt1015_rt5682"; |
| 37 | mediatek,platform = <&afe>; | 41 | mediatek,platform = <&afe>; |
| 42 | mediatek,hdmi-codec = <&anx_bridge_dp>; | ||
| 38 | pinctrl-names = "aud_clk_mosi_off", | 43 | pinctrl-names = "aud_clk_mosi_off", |
| 39 | "aud_clk_mosi_on"; | 44 | "aud_clk_mosi_on"; |
| 40 | pinctrl-0 = <&aud_clk_mosi_off>; | 45 | pinctrl-0 = <&aud_clk_mosi_off>; |
| @@ -0,0 +1,190 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-graph-card.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Audio Graph based Tegra sound card driver | ||
| 8 | |||
| 9 | description: | | ||
| 10 | This is based on generic audio graph card driver along with additional | ||
| 11 | customizations for Tegra platforms. It uses the same bindings with | ||
| 12 | additional standard clock DT bindings required for Tegra. | ||
| 13 | |||
| 14 | maintainers: | ||
| 15 | - Jon Hunter <jonathanh@nvidia.com> | ||
| 16 | - Sameer Pujar <spujar@nvidia.com> | ||
| 17 | |||
| 18 | allOf: | ||
| 19 | - $ref: audio-graph.yaml# | ||
| 20 | |||
| 21 | properties: | ||
| 22 | compatible: | ||
| 23 | enum: | ||
| 24 | - nvidia,tegra210-audio-graph-card | ||
| 25 | - nvidia,tegra186-audio-graph-card | ||
| 26 | |||
| 27 | clocks: | ||
| 28 | minItems: 2 | ||
| 29 | |||
| 30 | clock-names: | ||
| 31 | minItems: 2 | ||
| 32 | items: | ||
| 33 | - const: pll_a | ||
| 34 | - const: plla_out0 | ||
| 35 | |||
| 36 | assigned-clocks: | ||
| 37 | minItems: 1 | ||
| 38 | maxItems: 3 | ||
| 39 | |||
| 40 | assigned-clock-parents: | ||
| 41 | minItems: 1 | ||
| 42 | maxItems: 3 | ||
| 43 | |||
| 44 | assigned-clock-rates: | ||
| 45 | minItems: 1 | ||
| 46 | maxItems: 3 | ||
| 47 | |||
| 48 | iommus: | ||
| 49 | maxItems: 1 | ||
| 50 | |||
| 51 | required: | ||
| 52 | - clocks | ||
| 53 | - clock-names | ||
| 54 | - assigned-clocks | ||
| 55 | - assigned-clock-parents | ||
| 56 | |||
| 57 | unevaluatedProperties: false | ||
| 58 | |||
| 59 | examples: | ||
| 60 | - | | ||
| 61 | #include<dt-bindings/clock/tegra210-car.h> | ||
| 62 | |||
| 63 | tegra_sound { | ||
| 64 | compatible = "nvidia,tegra210-audio-graph-card"; | ||
| 65 | |||
| 66 | clocks = <&tegra_car TEGRA210_CLK_PLL_A>, | ||
| 67 | <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; | ||
| 68 | clock-names = "pll_a", "plla_out0"; | ||
| 69 | |||
| 70 | assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>, | ||
| 71 | <&tegra_car TEGRA210_CLK_PLL_A_OUT0>, | ||
| 72 | <&tegra_car TEGRA210_CLK_EXTERN1>; | ||
| 73 | assigned-clock-parents = <0>, <0>, <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; | ||
| 74 | assigned-clock-rates = <368640000>, <49152000>, <12288000>; | ||
| 75 | |||
| 76 | dais = /* FE */ | ||
| 77 | <&admaif1_port>, | ||
| 78 | /* Router */ | ||
| 79 | <&xbar_i2s1_port>, | ||
| 80 | /* I/O DAP Ports */ | ||
| 81 | <&i2s1_port>; | ||
| 82 | |||
| 83 | label = "jetson-tx1-ape"; | ||
| 84 | }; | ||
| 85 | |||
| 86 | // The ports are defined for AHUB and its child devices. | ||
| 87 | ahub@702d0800 { | ||
| 88 | compatible = "nvidia,tegra210-ahub"; | ||
| 89 | reg = <0x702d0800 0x800>; | ||
| 90 | clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; | ||
| 91 | clock-names = "ahub"; | ||
| 92 | assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; | ||
| 93 | assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; | ||
| 94 | #address-cells = <1>; | ||
| 95 | #size-cells = <1>; | ||
| 96 | ranges = <0x702d0000 0x702d0000 0x0000e400>; | ||
| 97 | |||
| 98 | ports { | ||
| 99 | #address-cells = <1>; | ||
| 100 | #size-cells = <0>; | ||
| 101 | |||
| 102 | port@0 { | ||
| 103 | reg = <0x0>; | ||
| 104 | xbar_admaif1_ep: endpoint { | ||
| 105 | remote-endpoint = <&admaif1_ep>; | ||
| 106 | }; | ||
| 107 | }; | ||
| 108 | |||
| 109 | // ... | ||
| 110 | |||
| 111 | xbar_i2s1_port: port@a { | ||
| 112 | reg = <0xa>; | ||
| 113 | xbar_i2s1_ep: endpoint { | ||
| 114 | remote-endpoint = <&i2s1_cif_ep>; | ||
| 115 | }; | ||
| 116 | }; | ||
| 117 | }; | ||
| 118 | |||
| 119 | admaif@702d0000 { | ||
| 120 | compatible = "nvidia,tegra210-admaif"; | ||
| 121 | reg = <0x702d0000 0x800>; | ||
| 122 | dmas = <&adma 1>, <&adma 1>, | ||
| 123 | <&adma 2>, <&adma 2>, | ||
| 124 | <&adma 3>, <&adma 3>, | ||
| 125 | <&adma 4>, <&adma 4>, | ||
| 126 | <&adma 5>, <&adma 5>, | ||
| 127 | <&adma 6>, <&adma 6>, | ||
| 128 | <&adma 7>, <&adma 7>, | ||
| 129 | <&adma 8>, <&adma 8>, | ||
| 130 | <&adma 9>, <&adma 9>, | ||
| 131 | <&adma 10>, <&adma 10>; | ||
| 132 | dma-names = "rx1", "tx1", | ||
| 133 | "rx2", "tx2", | ||
| 134 | "rx3", "tx3", | ||
| 135 | "rx4", "tx4", | ||
| 136 | "rx5", "tx5", | ||
| 137 | "rx6", "tx6", | ||
| 138 | "rx7", "tx7", | ||
| 139 | "rx8", "tx8", | ||
| 140 | "rx9", "tx9", | ||
| 141 | "rx10", "tx10"; | ||
| 142 | |||
| 143 | ports { | ||
| 144 | #address-cells = <1>; | ||
| 145 | #size-cells = <0>; | ||
| 146 | |||
| 147 | admaif1_port: port@0 { | ||
| 148 | reg = <0x0>; | ||
| 149 | admaif1_ep: endpoint { | ||
| 150 | remote-endpoint = <&xbar_admaif1_ep>; | ||
| 151 | }; | ||
| 152 | }; | ||
| 153 | |||
| 154 | // More ADMAIF ports to follow | ||
| 155 | }; | ||
| 156 | }; | ||
| 157 | |||
| 158 | i2s@702d1000 { | ||
| 159 | compatible = "nvidia,tegra210-i2s"; | ||
| 160 | clocks = <&tegra_car TEGRA210_CLK_I2S0>; | ||
| 161 | clock-names = "i2s"; | ||
| 162 | assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>; | ||
| 163 | assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; | ||
| 164 | assigned-clock-rates = <1536000>; | ||
| 165 | reg = <0x702d1000 0x100>; | ||
| 166 | |||
| 167 | ports { | ||
| 168 | #address-cells = <1>; | ||
| 169 | #size-cells = <0>; | ||
| 170 | |||
| 171 | port@0 { | ||
| 172 | reg = <0x0>; | ||
| 173 | |||
| 174 | i2s1_cif_ep: endpoint { | ||
| 175 | remote-endpoint = <&xbar_i2s1_ep>; | ||
| 176 | }; | ||
| 177 | }; | ||
| 178 | |||
| 179 | i2s1_port: port@1 { | ||
| 180 | reg = <0x1>; | ||
| 181 | |||
| 182 | i2s1_dap: endpoint { | ||
| 183 | dai-format = "i2s"; | ||
| 184 | }; | ||
| 185 | }; | ||
| 186 | }; | ||
| 187 | }; | ||
| 188 | }; | ||
| 189 | |||
| 190 | ... | ||
| @@ -17,6 +17,9 @@ maintainers: · 16 unmodified lines | |||
| 17 | - Jon Hunter <jonathanh@nvidia.com> | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | - Sameer Pujar <spujar@nvidia.com> | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | ||
| 20 | allOf: | ||
| 21 | - $ref: audio-graph-port.yaml# | ||
| 22 | |||
| 20 | properties: | 23 | properties: |
| 21 | $nodename: | 24 | $nodename: |
| 22 | pattern: "^dspk@[0-9a-f]*$" | 25 | pattern: "^dspk@[0-9a-f]*$" |
| @@ -55,6 +58,19 @@ properties: · 32 unmodified lines | |||
| 55 | The name can be "DSPK1" or "DSPKx", where x depends on the maximum | 58 | The name can be "DSPK1" or "DSPKx", where x depends on the maximum |
| 56 | available instances on a Tegra SoC. | 59 | available instances on a Tegra SoC. |
| 57 | 60 | ||
| 61 | ports: | ||
| 62 | type: object | ||
| 63 | properties: | ||
| 64 | port@0: | ||
| 65 | description: | | ||
| 66 | DSPK ACIF (Audio Client Interface) port connected to the | ||
| 67 | corresponding AHUB (Audio Hub) ACIF port. | ||
| 68 | |||
| 69 | port@1: | ||
| 70 | description: | | ||
| 71 | DSPK DAP (Digital Audio Port) interface which can be connected | ||
| 72 | to external audio codec for playback. | ||
| 73 | |||
| 58 | required: | 74 | required: |
| 59 | - compatible | 75 | - compatible |
| 60 | - reg | 76 | - reg |
| @@ -64,7 +80,7 @@ required: · 3 unmodified lines | |||
| 64 | - assigned-clock-parents | 80 | - assigned-clock-parents |
| 65 | - sound-name-prefix | 81 | - sound-name-prefix |
| 66 | 82 | ||
| 67 | additionalProperties: false | 83 | unevaluatedProperties: false |
| 68 | 84 | ||
| 69 | examples: | 85 | examples: |
| 70 | - | | 86 | - | |
| @@ -17,6 +17,9 @@ maintainers: · 16 unmodified lines | |||
| 17 | - Jon Hunter <jonathanh@nvidia.com> | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | - Sameer Pujar <spujar@nvidia.com> | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | ||
| 20 | allOf: | ||
| 21 | - $ref: audio-graph-port.yaml# | ||
| 22 | |||
| 20 | properties: | 23 | properties: |
| 21 | $nodename: | 24 | $nodename: |
| 22 | pattern: "^admaif@[0-9a-f]*$" | 25 | pattern: "^admaif@[0-9a-f]*$" |
| @@ -37,6 +40,14 @@ properties: · 14 unmodified lines | |||
| 37 | 40 | ||
| 38 | dma-names: true | 41 | dma-names: true |
| 39 | 42 | ||
| 43 | ports: | ||
| 44 | description: | | ||
| 45 | Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels. | ||
| 46 | The number of port nodes depends on the number of ADMAIF channels | ||
| 47 | that SoC may have. These are interfaced with respective ACIF ports | ||
| 48 | in AHUB (Audio Hub). Each port is capable of data transfers in | ||
| 49 | both directions. | ||
| 50 | |||
| 40 | if: | 51 | if: |
| 41 | properties: | 52 | properties: |
| 42 | compatible: | 53 | compatible: |
| @@ -81,7 +92,7 @@ required: · 38 unmodified lines | |||
| 81 | - dmas | 92 | - dmas |
| 82 | - dma-names | 93 | - dma-names |
| 83 | 94 | ||
| 84 | additionalProperties: false | 95 | unevaluatedProperties: false |
| 85 | 96 | ||
| 86 | examples: | 97 | examples: |
| 87 | - | | 98 | - | |
| @@ -17,6 +17,9 @@ maintainers: · 16 unmodified lines | |||
| 17 | - Jon Hunter <jonathanh@nvidia.com> | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | - Sameer Pujar <spujar@nvidia.com> | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | ||
| 20 | allOf: | ||
| 21 | - $ref: audio-graph-port.yaml# | ||
| 22 | |||
| 20 | properties: | 23 | properties: |
| 21 | $nodename: | 24 | $nodename: |
| 22 | pattern: "^ahub@[0-9a-f]*$" | 25 | pattern: "^ahub@[0-9a-f]*$" |
| @@ -56,6 +59,13 @@ properties: · 33 unmodified lines | |||
| 56 | 59 | ||
| 57 | ranges: true | 60 | ranges: true |
| 58 | 61 | ||
| 62 | ports: | ||
| 63 | description: | | ||
| 64 | Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub). | ||
| 65 | These are connected to ACIF interfaces of AHUB clients. Thus the | ||
| 66 | number of port nodes depend on the number of clients that AHUB may | ||
| 67 | have depending on the SoC revision. | ||
| 68 | |||
| 59 | required: | 69 | required: |
| 60 | - compatible | 70 | - compatible |
| 61 | - reg | 71 | - reg |
| @@ -67,8 +77,7 @@ required: · 5 unmodified lines | |||
| 67 | - "#size-cells" | 77 | - "#size-cells" |
| 68 | - ranges | 78 | - ranges |
| 69 | 79 | ||
| 70 | additionalProperties: | 80 | unevaluatedProperties: false |
| 71 | type: object | ||
| 72 | 81 | ||
| 73 | examples: | 82 | examples: |
| 74 | - | | 83 | - | |
| @@ -16,6 +16,9 @@ maintainers: · 15 unmodified lines | |||
| 16 | - Jon Hunter <jonathanh@nvidia.com> | 16 | - Jon Hunter <jonathanh@nvidia.com> |
| 17 | - Sameer Pujar <spujar@nvidia.com> | 17 | - Sameer Pujar <spujar@nvidia.com> |
| 18 | 18 | ||
| 19 | allOf: | ||
| 20 | - $ref: audio-graph-port.yaml# | ||
| 21 | |||
| 19 | properties: | 22 | properties: |
| 20 | $nodename: | 23 | $nodename: |
| 21 | pattern: "^dmic@[0-9a-f]*$" | 24 | pattern: "^dmic@[0-9a-f]*$" |
| @@ -56,6 +59,19 @@ properties: · 34 unmodified lines | |||
| 56 | The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends | 59 | The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends |
| 57 | on the maximum available instances on a Tegra SoC. | 60 | on the maximum available instances on a Tegra SoC. |
| 58 | 61 | ||
| 62 | ports: | ||
| 63 | type: object | ||
| 64 | properties: | ||
| 65 | port@0: | ||
| 66 | description: | | ||
| 67 | DMIC ACIF (Audio Client Interface) port connected to the | ||
| 68 | corresponding AHUB (Audio Hub) ACIF port. | ||
| 69 | |||
| 70 | port@1: | ||
| 71 | description: | | ||
| 72 | DMIC DAP (Digital Audio Port) interface which can be connected | ||
| 73 | to external audio codec for capture. | ||
| 74 | |||
| 59 | required: | 75 | required: |
| 60 | - compatible | 76 | - compatible |
| 61 | - reg | 77 | - reg |
| @@ -64,7 +80,7 @@ required: · 2 unmodified lines | |||
| 64 | - assigned-clocks | 80 | - assigned-clocks |
| 65 | - assigned-clock-parents | 81 | - assigned-clock-parents |
| 66 | 82 | ||
| 67 | additionalProperties: false | 83 | unevaluatedProperties: false |
| 68 | 84 | ||
| 69 | examples: | 85 | examples: |
| 70 | - | | 86 | - | |
| @@ -16,6 +16,9 @@ maintainers: · 15 unmodified lines | |||
| 16 | - Jon Hunter <jonathanh@nvidia.com> | 16 | - Jon Hunter <jonathanh@nvidia.com> |
| 17 | - Sameer Pujar <spujar@nvidia.com> | 17 | - Sameer Pujar <spujar@nvidia.com> |
| 18 | 18 | ||
| 19 | allOf: | ||
| 20 | - $ref: audio-graph-port.yaml# | ||
| 21 | |||
| 19 | properties: | 22 | properties: |
| 20 | $nodename: | 23 | $nodename: |
| 21 | pattern: "^i2s@[0-9a-f]*$" | 24 | pattern: "^i2s@[0-9a-f]*$" |
| @@ -74,6 +77,19 @@ properties: · 52 unmodified lines | |||
| 74 | The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends | 77 | The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends |
| 75 | on the maximum available instances on a Tegra SoC. | 78 | on the maximum available instances on a Tegra SoC. |
| 76 | 79 | ||
| 80 | ports: | ||
| 81 | type: object | ||
| 82 | properties: | ||
| 83 | port@0: | ||
| 84 | description: | | ||
| 85 | I2S ACIF (Audio Client Interface) port connected to the | ||
| 86 | corresponding AHUB (Audio Hub) ACIF port. | ||
| 87 | |||
| 88 | port@1: | ||
| 89 | description: | | ||
| 90 | I2S DAP (Digital Audio Port) interface which can be connected | ||
| 91 | to external audio codec for playback or capture. | ||
| 92 | |||
| 77 | required: | 93 | required: |
| 78 | - compatible | 94 | - compatible |
| 79 | - reg | 95 | - reg |
| @@ -82,7 +98,7 @@ required: · 2 unmodified lines | |||
| 82 | - assigned-clocks | 98 | - assigned-clocks |
| 83 | - assigned-clock-parents | 99 | - assigned-clock-parents |
| 84 | 100 | ||
| 85 | additionalProperties: false | 101 | unevaluatedProperties: false |
| 86 | 102 | ||
| 87 | examples: | 103 | examples: |
| 88 | - | | 104 | - | |
| @@ -0,0 +1,62 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/sound/qcom,lpass-rx-macro.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: LPASS(Low Power Audio Subsystem) RX Macro audio codec DT bindings | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | const: qcom,sm8250-lpass-rx-macro | ||
| 15 | |||
| 16 | reg: | ||
| 17 | maxItems: 1 | ||
| 18 | |||
| 19 | "#sound-dai-cells": | ||
| 20 | const: 1 | ||
| 21 | |||
| 22 | '#clock-cells': | ||
| 23 | const: 0 | ||
| 24 | |||
| 25 | clocks: | ||
| 26 | maxItems: 5 | ||
| 27 | |||
| 28 | clock-names: | ||
| 29 | items: | ||
| 30 | - const: mclk | ||
| 31 | - const: npl | ||
| 32 | - const: macro | ||
| 33 | - const: dcodec | ||
| 34 | - const: fsgen | ||
| 35 | |||
| 36 | clock-output-names: | ||
| 37 | items: | ||
| 38 | - const: mclk | ||
| 39 | |||
| 40 | required: | ||
| 41 | - compatible | ||
| 42 | - reg | ||
| 43 | - "#sound-dai-cells" | ||
| 44 | |||
| 45 | additionalProperties: false | ||
| 46 | |||
| 47 | examples: | ||
| 48 | - | | ||
| 49 | #include <dt-bindings/sound/qcom,q6afe.h> | ||
| 50 | codec@3200000 { | ||
| 51 | compatible = "qcom,sm8250-lpass-rx-macro"; | ||
| 52 | reg = <0x3200000 0x1000>; | ||
| 53 | #sound-dai-cells = <1>; | ||
| 54 | #clock-cells = <0>; | ||
| 55 | clocks = <&audiocc 0>, | ||
| 56 | <&audiocc 1>, | ||
| 57 | <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, | ||
| 58 | <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, | ||
| 59 | <&vamacro>; | ||
| 60 | clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; | ||
| 61 | clock-output-names = "mclk"; | ||
| 62 | }; | ||
| @@ -0,0 +1,67 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/sound/qcom,lpass-tx-macro.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: LPASS(Low Power Audio Subsystem) TX Macro audio codec DT bindings | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | const: qcom,sm8250-lpass-tx-macro | ||
| 15 | |||
| 16 | reg: | ||
| 17 | maxItems: 1 | ||
| 18 | |||
| 19 | "#sound-dai-cells": | ||
| 20 | const: 1 | ||
| 21 | |||
| 22 | '#clock-cells': | ||
| 23 | const: 0 | ||
| 24 | |||
| 25 | clocks: | ||
| 26 | maxItems: 5 | ||
| 27 | |||
| 28 | clock-names: | ||
| 29 | items: | ||
| 30 | - const: mclk | ||
| 31 | - const: npl | ||
| 32 | - const: macro | ||
| 33 | - const: dcodec | ||
| 34 | - const: fsgen | ||
| 35 | |||
| 36 | clock-output-names: | ||
| 37 | items: | ||
| 38 | - const: mclk | ||
| 39 | |||
| 40 | qcom,dmic-sample-rate: | ||
| 41 | description: dmic sample rate | ||
| 42 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 43 | |||
| 44 | required: | ||
| 45 | - compatible | ||
| 46 | - reg | ||
| 47 | - "#sound-dai-cells" | ||
| 48 | |||
| 49 | additionalProperties: false | ||
| 50 | |||
| 51 | examples: | ||
| 52 | - | | ||
| 53 | #include <dt-bindings/sound/qcom,q6afe.h> | ||
| 54 | codec@3220000 { | ||
| 55 | compatible = "qcom,sm8250-lpass-tx-macro"; | ||
| 56 | reg = <0x3220000 0x1000>; | ||
| 57 | #sound-dai-cells = <1>; | ||
| 58 | #clock-cells = <0>; | ||
| 59 | clocks = <&aoncc 0>, | ||
| 60 | <&aoncc 1>, | ||
| 61 | <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, | ||
| 62 | <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, | ||
| 63 | <&vamacro>; | ||
| 64 | clock-names = "mclk", "npl", "macro", "dcodec", "fsgen"; | ||
| 65 | clock-output-names = "mclk"; | ||
| 66 | qcom,dmic-sample-rate = <600000>; | ||
| 67 | }; | ||
| @@ -404,7 +404,7 @@ examples: · 403 unmodified lines | |||
| 404 | /* DAI base */ | 404 | /* DAI base */ |
| 405 | rcar_sound,dai { | 405 | rcar_sound,dai { |
| 406 | dai0 { | 406 | dai0 { |
| 407 | playback = <&ssi5 &src5>; | 407 | playback = <&ssi5>, <&src5>; |
| 408 | capture = <&ssi6>; | 408 | capture = <&ssi6>; |
| 409 | }; | 409 | }; |
| 410 | dai1 { | 410 | dai1 { |
| @@ -430,8 +430,8 @@ examples: · 19 unmodified lines | |||
| 430 | bitclock-master = <&rsnd_endpoint0>; | 430 | bitclock-master = <&rsnd_endpoint0>; |
| 431 | frame-master = <&rsnd_endpoint0>; | 431 | frame-master = <&rsnd_endpoint0>; |
| 432 | 432 | ||
| 433 | playback = <&ssi0 &src0 &dvc0>; | 433 | playback = <&ssi0>, <&src0>, <&dvc0>; |
| 434 | capture = <&ssi1 &src1 &dvc1>; | 434 | capture = <&ssi1>, <&src1>, <&dvc1>; |
| 435 | }; | 435 | }; |
| 436 | }; | 436 | }; |
| 437 | }; | 437 | }; |
| @@ -37,10 +37,21 @@ Optional properties: · 36 unmodified lines | |||
| 37 | - realtek,jd-src | 37 | - realtek,jd-src |
| 38 | 0: No JD is used | 38 | 0: No JD is used |
| 39 | 1: using JD3 as JD source | 39 | 1: using JD3 as JD source |
| 40 | 2: JD source for Intel HDA header | ||
| 40 | 41 | ||
| 41 | - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. | 42 | - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. |
| 42 | - realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin. | 43 | - realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin. |
| 43 | 44 | ||
| 45 | - sound-name-prefix: Please refer to name-prefix.txt | ||
| 46 | |||
| 47 | - ports: A Codec may have a single or multiple I2S interfaces. These | ||
| 48 | interfaces on Codec side can be described under 'ports' or 'port'. | ||
| 49 | When the SoC or host device is connected to multiple interfaces of | ||
| 50 | the Codec, the connectivity can be described using 'ports' property. | ||
| 51 | If a single interface is used, then 'port' can be used. The usage | ||
| 52 | depends on the platform or board design. | ||
| 53 | Please refer to Documentation/devicetree/bindings/graph.txt | ||
| 54 | |||
| 44 | Pins on the device (for linking into audio routes) for RT5659/RT5658: | 55 | Pins on the device (for linking into audio routes) for RT5659/RT5658: |
| 45 | 56 | ||
| 46 | * DMIC L1 | 57 | * DMIC L1 |
| @@ -1,17 +0,0 @@ | |||
| 1 | SiRF internal audio CODEC | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec" | ||
| 6 | |||
| 7 | - reg : the register address of the device. | ||
| 8 | |||
| 9 | - clocks: the clock of SiRF internal audio codec | ||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | audiocodec: audiocodec@b0040000 { | ||
| 14 | compatible = "sirf,atlas6-audio-codec"; | ||
| 15 | reg = <0xb0040000 0x10000>; | ||
| 16 | clocks = <&clks 27>; | ||
| 17 | }; | ||
| @@ -1,27 +0,0 @@ | |||
| 1 | * SiRF SoC USP module | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "sirf,prima2-usp-pcm" | ||
| 5 | - reg: Base address and size entries: | ||
| 6 | - dmas: List of DMA controller phandle and DMA request line ordered pairs. | ||
| 7 | - dma-names: Identifier string for each DMA request line in the dmas property. | ||
| 8 | These strings correspond 1:1 with the ordered pairs in dmas. | ||
| 9 | |||
| 10 | One of the DMA channels will be responsible for transmission (should be | ||
| 11 | named "tx") and one for reception (should be named "rx"). | ||
| 12 | |||
| 13 | - clocks: USP controller clock source | ||
| 14 | - pinctrl-names: Must contain a "default" entry. | ||
| 15 | - pinctrl-NNN: One property must exist for each entry in pinctrl-names. | ||
| 16 | |||
| 17 | Example: | ||
| 18 | usp0: usp@b0080000 { | ||
| 19 | compatible = "sirf,prima2-usp-pcm"; | ||
| 20 | reg = <0xb0080000 0x10000>; | ||
| 21 | clocks = <&clks 28>; | ||
| 22 | dmas = <&dmac1 1>, <&dmac1 2>; | ||
| 23 | dma-names = "rx", "tx"; | ||
| 24 | pinctrl-names = "default"; | ||
| 25 | pinctrl-0 = <&usp0_only_utfs_pins_a>; | ||
| 26 | }; | ||
| 27 | |||
| @@ -54,6 +54,10 @@ properties: · 53 unmodified lines | |||
| 54 | resets: | 54 | resets: |
| 55 | maxItems: 1 | 55 | maxItems: 1 |
| 56 | 56 | ||
| 57 | "#clock-cells": | ||
| 58 | description: Configure the I2S device as MCLK clock provider. | ||
| 59 | const: 0 | ||
| 60 | |||
| 57 | required: | 61 | required: |
| 58 | - compatible | 62 | - compatible |
| 59 | - "#sound-dai-cells" | 63 | - "#sound-dai-cells" |
| @@ -9,6 +9,9 @@ Required properties: · 8 unmodified lines | |||
| 9 | - reg : the I2C address of the device. | 9 | - reg : the I2C address of the device. |
| 10 | 10 | ||
| 11 | Optional properties: | 11 | Optional properties: |
| 12 | |||
| 13 | - clocks : The clock source of the mclk | ||
| 14 | |||
| 12 | - spk-mono: This is a boolean property. If present, the SPK_MONO bit | 15 | - spk-mono: This is a boolean property. If present, the SPK_MONO bit |
| 13 | of R51 (Class D Control 2) gets set, indicating that the speaker is | 16 | of R51 (Class D Control 2) gets set, indicating that the speaker is |
| 14 | in mono mode. | 17 | in mono mode. |
| @@ -27,6 +30,7 @@ Example: · 12 unmodified lines | |||
| 27 | wm8962: codec@1a { | 30 | wm8962: codec@1a { |
| 28 | compatible = "wlf,wm8962"; | 31 | compatible = "wlf,wm8962"; |
| 29 | reg = <0x1a>; | 32 | reg = <0x1a>; |
| 33 | clocks = <&clks IMX6QDL_CLK_CKO>; | ||
| 30 | 34 | ||
| 31 | gpio-cfg = < | 35 | gpio-cfg = < |
| 32 | 0x0000 /* 0:Default */ | 36 | 0x0000 /* 0:Default */ |
| @@ -1,30 +0,0 @@ | |||
| 1 | ZTE TDM DAI driver | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : should be one of the following. | ||
| 6 | * zte,zx296718-tdm | ||
| 7 | - reg : physical base address of the controller and length of memory mapped | ||
| 8 | region. | ||
| 9 | - clocks : Pairs of phandle and specifier referencing the controller's clocks. | ||
| 10 | - clock-names: "wclk" for the wclk. | ||
| 11 | "pclk" for the pclk. | ||
| 12 | -#clock-cells: should be 1. | ||
| 13 | - zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling | ||
| 14 | the dma. includes: | ||
| 15 | phandle of sysctrl. | ||
| 16 | register offset in sysctrl for control dma. | ||
| 17 | mask of the register that be written to sysctrl. | ||
| 18 | |||
| 19 | Example: | ||
| 20 | |||
| 21 | tdm: tdm@1487000 { | ||
| 22 | compatible = "zte,zx296718-tdm"; | ||
| 23 | reg = <0x01487000 0x1000>; | ||
| 24 | clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>; | ||
| 25 | clock-names = "wclk", "pclk"; | ||
| 26 | #clock-cells = <1>; | ||
| 27 | pinctrl-names = "default"; | ||
| 28 | pinctrl-0 = <&tdm_global_pin>; | ||
| 29 | zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>; | ||
| 30 | }; | ||
| @@ -1,24 +0,0 @@ | |||
| 1 | ZTE ZX AUD96P22 Audio Codec | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Must be "zte,zx-aud96p22" | ||
| 5 | - #sound-dai-cells: Should be 0 | ||
| 6 | - reg: I2C bus slave address of AUD96P22 | ||
| 7 | |||
| 8 | Example: | ||
| 9 | |||
| 10 | i2c0: i2c@1486000 { | ||
| 11 | compatible = "zte,zx296718-i2c"; | ||
| 12 | reg = <0x01486000 0x1000>; | ||
| 13 | interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; | ||
| 14 | #address-cells = <1>; | ||
| 15 | #size-cells = <0>; | ||
| 16 | clocks = <&audiocrm AUDIO_I2C0_WCLK>; | ||
| 17 | clock-frequency = <1600000>; | ||
| 18 | |||
| 19 | aud96p22: codec@22 { | ||
| 20 | compatible = "zte,zx-aud96p22"; | ||
| 21 | #sound-dai-cells = <0>; | ||
| 22 | reg = <0x22>; | ||
| 23 | }; | ||
| 24 | }; | ||
| @@ -1,45 +0,0 @@ | |||
| 1 | ZTE ZX296702 I2S controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Must be one of: | ||
| 5 | "zte,zx296718-i2s", "zte,zx296702-i2s" | ||
| 6 | "zte,zx296702-i2s" | ||
| 7 | - reg : Must contain I2S core's registers location and length | ||
| 8 | - clocks : Pairs of phandle and specifier referencing the controller's clocks. | ||
| 9 | - clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface. | ||
| 10 | - dmas: Pairs of phandle and specifier for the DMA channel that is used by | ||
| 11 | the core. The core expects two dma channels for transmit. | ||
| 12 | - dma-names : Must be "tx" and "rx" | ||
| 13 | |||
| 14 | For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties | ||
| 15 | please check: | ||
| 16 | * resource-names.txt | ||
| 17 | * clock/clock-bindings.txt | ||
| 18 | * dma/dma.txt | ||
| 19 | |||
| 20 | Example: | ||
| 21 | i2s0: i2s@b005000 { | ||
| 22 | #sound-dai-cells = <0>; | ||
| 23 | compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; | ||
| 24 | reg = <0x0b005000 0x1000>; | ||
| 25 | clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>; | ||
| 26 | clock-names = "wclk", "pclk"; | ||
| 27 | interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; | ||
| 28 | dmas = <&dma 5>, <&dma 6>; | ||
| 29 | dma-names = "tx", "rx"; | ||
| 30 | }; | ||
| 31 | |||
| 32 | sound { | ||
| 33 | compatible = "simple-audio-card"; | ||
| 34 | simple-audio-card,name = "zx296702_snd"; | ||
| 35 | simple-audio-card,format = "left_j"; | ||
| 36 | simple-audio-card,bitclock-master = <&sndcodec>; | ||
| 37 | simple-audio-card,frame-master = <&sndcodec>; | ||
| 38 | sndcpu: simple-audio-card,cpu { | ||
| 39 | sound-dai = <&i2s0>; | ||
| 40 | }; | ||
| 41 | |||
| 42 | sndcodec: simple-audio-card,codec { | ||
| 43 | sound-dai = <&acodec>; | ||
| 44 | }; | ||
| 45 | }; | ||
| @@ -1,27 +0,0 @@ | |||
| 1 | ZTE ZX296702 SPDIF controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Must be "zte,zx296702-spdif" | ||
| 5 | - reg : Must contain SPDIF core's registers location and length | ||
| 6 | - clocks : Pairs of phandle and specifier referencing the controller's clocks. | ||
| 7 | - clock-names: "tx" for the clock to the SPDIF interface. | ||
| 8 | - dmas: Pairs of phandle and specifier for the DMA channel that is used by | ||
| 9 | the core. The core expects one dma channel for transmit. | ||
| 10 | - dma-names : Must be "tx" | ||
| 11 | |||
| 12 | For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties | ||
| 13 | please check: | ||
| 14 | * resource-names.txt | ||
| 15 | * clock/clock-bindings.txt | ||
| 16 | * dma/dma.txt | ||
| 17 | |||
| 18 | Example: | ||
| 19 | spdif0: spdif0@b004000 { | ||
| 20 | compatible = "zte,zx296702-spdif"; | ||
| 21 | reg = <0x0b004000 0x1000>; | ||
| 22 | clocks = <&lsp0clk ZX296702_SPDIF0_DIV>; | ||
| 23 | clock-names = "tx"; | ||
| 24 | interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; | ||
| 25 | dmas = <&dma 4>; | ||
| 26 | dma-names = "tx"; | ||
| 27 | }; | ||
| @@ -14,3 +14,4 @@ Designs and Implementations · 13 unmodified lines | |||
| 14 | powersave | 14 | powersave |
| 15 | oss-emulation | 15 | oss-emulation |
| 16 | seq-oss | 16 | seq-oss |
| 17 | jack-injection | ||
| @@ -0,0 +1,166 @@ | |||
| 1 | ============================ | ||
| 2 | ALSA Jack Software Injection | ||
| 3 | ============================ | ||
| 4 | |||
| 5 | Simple Introduction On Jack Injection | ||
| 6 | ===================================== | ||
| 7 | |||
| 8 | Here jack injection means users could inject plugin or plugout events | ||
| 9 | to the audio jacks through debugfs interface, it is helpful to | ||
| 10 | validate ALSA userspace changes. For example, we change the audio | ||
| 11 | profile switching code in the pulseaudio, and we want to verify if the | ||
| 12 | change works as expected and if the change introduce the regression, | ||
| 13 | in this case, we could inject plugin or plugout events to an audio | ||
| 14 | jack or to some audio jacks, we don't need to physically access the | ||
| 15 | machine and plug/unplug physical devices to the audio jack. | ||
| 16 | |||
| 17 | In this design, an audio jack doesn't equal to a physical audio jack. | ||
| 18 | Sometimes a physical audio jack contains multi functions, and the | ||
| 19 | ALSA driver creates multi ``jack_kctl`` for a ``snd_jack``, here the | ||
| 20 | ``snd_jack`` represents a physical audio jack and the ``jack_kctl`` | ||
| 21 | represents a function, for example a physical jack has two functions: | ||
| 22 | headphone and mic_in, the ALSA ASoC driver will build 2 ``jack_kctl`` | ||
| 23 | for this jack. The jack injection is implemented based on the | ||
| 24 | ``jack_kctl`` instead of ``snd_jack``. | ||
| 25 | |||
| 26 | To inject events to audio jacks, we need to enable the jack injection | ||
| 27 | via ``sw_inject_enable`` first, once it is enabled, this jack will not | ||
| 28 | change the state by hardware events anymore, we could inject plugin or | ||
| 29 | plugout events via ``jackin_inject`` and check the jack state via | ||
| 30 | ``status``, after we finish our test, we need to disable the jack | ||
| 31 | injection via ``sw_inject_enable`` too, once it is disabled, the jack | ||
| 32 | state will be restored according to the last reported hardware events | ||
| 33 | and will change by future hardware events. | ||
| 34 | |||
| 35 | The Layout of Jack Injection Interface | ||
| 36 | ====================================== | ||
| 37 | |||
| 38 | If users enable the SND_JACK_INJECTION_DEBUG in the kernel, the audio | ||
| 39 | jack injection interface will be created as below: | ||
| 40 | :: | ||
| 41 | |||
| 42 | $debugfs_mount_dir/sound | ||
| 43 | |-- card0 | ||
| 44 | |-- |-- HDMI_DP_pcm_10_Jack | ||
| 45 | |-- |-- |-- jackin_inject | ||
| 46 | |-- |-- |-- kctl_id | ||
| 47 | |-- |-- |-- mask_bits | ||
| 48 | |-- |-- |-- status | ||
| 49 | |-- |-- |-- sw_inject_enable | ||
| 50 | |-- |-- |-- type | ||
| 51 | ... | ||
| 52 | |-- |-- HDMI_DP_pcm_9_Jack | ||
| 53 | |-- |-- jackin_inject | ||
| 54 | |-- |-- kctl_id | ||
| 55 | |-- |-- mask_bits | ||
| 56 | |-- |-- status | ||
| 57 | |-- |-- sw_inject_enable | ||
| 58 | |-- |-- type | ||
| 59 | |-- card1 | ||
| 60 | |-- HDMI_DP_pcm_5_Jack | ||
| 61 | |-- |-- jackin_inject | ||
| 62 | |-- |-- kctl_id | ||
| 63 | |-- |-- mask_bits | ||
| 64 | |-- |-- status | ||
| 65 | |-- |-- sw_inject_enable | ||
| 66 | |-- |-- type | ||
| 67 | ... | ||
| 68 | |-- Headphone_Jack | ||
| 69 | |-- |-- jackin_inject | ||
| 70 | |-- |-- kctl_id | ||
| 71 | |-- |-- mask_bits | ||
| 72 | |-- |-- status | ||
| 73 | |-- |-- sw_inject_enable | ||
| 74 | |-- |-- type | ||
| 75 | |-- Headset_Mic_Jack | ||
| 76 | |-- jackin_inject | ||
| 77 | |-- kctl_id | ||
| 78 | |-- mask_bits | ||
| 79 | |-- status | ||
| 80 | |-- sw_inject_enable | ||
| 81 | |-- type | ||
| 82 | |||
| 83 | The Explanation Of The Nodes | ||
| 84 | ====================================== | ||
| 85 | |||
| 86 | kctl_id | ||
| 87 | read-only, get jack_kctl->kctl's id | ||
| 88 | :: | ||
| 89 | |||
| 90 | sound/card1/Headphone_Jack# cat kctl_id | ||
| 91 | Headphone Jack | ||
| 92 | |||
| 93 | mask_bits | ||
| 94 | read-only, get jack_kctl's supported events mask_bits | ||
| 95 | :: | ||
| 96 | |||
| 97 | sound/card1/Headphone_Jack# cat mask_bits | ||
| 98 | 0x0001 HEADPHONE(0x0001) | ||
| 99 | |||
| 100 | status | ||
| 101 | read-only, get jack_kctl's current status | ||
| 102 | |||
| 103 | - headphone unplugged: | ||
| 104 | |||
| 105 | :: | ||
| 106 | |||
| 107 | sound/card1/Headphone_Jack# cat status | ||
| 108 | Unplugged | ||
| 109 | |||
| 110 | - headphone plugged: | ||
| 111 | |||
| 112 | :: | ||
| 113 | |||
| 114 | sound/card1/Headphone_Jack# cat status | ||
| 115 | Plugged | ||
| 116 | |||
| 117 | type | ||
| 118 | read-only, get snd_jack's supported events from type (all supported events on the physical audio jack) | ||
| 119 | :: | ||
| 120 | |||
| 121 | sound/card1/Headphone_Jack# cat type | ||
| 122 | 0x7803 HEADPHONE(0x0001) MICROPHONE(0x0002) BTN_3(0x0800) BTN_2(0x1000) BTN_1(0x2000) BTN_0(0x4000) | ||
| 123 | |||
| 124 | sw_inject_enable | ||
| 125 | read-write, enable or disable injection | ||
| 126 | |||
| 127 | - injection disabled: | ||
| 128 | |||
| 129 | :: | ||
| 130 | |||
| 131 | sound/card1/Headphone_Jack# cat sw_inject_enable | ||
| 132 | Jack: Headphone Jack Inject Enabled: 0 | ||
| 133 | |||
| 134 | - injection enabled: | ||
| 135 | |||
| 136 | :: | ||
| 137 | |||
| 138 | sound/card1/Headphone_Jack# cat sw_inject_enable | ||
| 139 | Jack: Headphone Jack Inject Enabled: 1 | ||
| 140 | |||
| 141 | - to enable jack injection: | ||
| 142 | |||
| 143 | :: | ||
| 144 | |||
| 145 | sound/card1/Headphone_Jack# echo 1 > sw_inject_enable | ||
| 146 | |||
| 147 | - to disable jack injection: | ||
| 148 | |||
| 149 | :: | ||
| 150 | |||
| 151 | sound/card1/Headphone_Jack# echo 0 > sw_inject_enable | ||
| 152 | |||
| 153 | jackin_inject | ||
| 154 | write-only, inject plugin or plugout | ||
| 155 | |||
| 156 | - to inject plugin: | ||
| 157 | |||
| 158 | :: | ||
| 159 | |||
| 160 | sound/card1/Headphone_Jack# echo 1 > jackin_inject | ||
| 161 | |||
| 162 | - to inject plugout: | ||
| 163 | |||
| 164 | :: | ||
| 165 | |||
| 166 | sound/card1/Headphone_Jack# echo 0 > jackin_inject | ||
| @@ -51,7 +51,7 @@ static int isa_bus_remove(struct device *dev) · 50 unmodified lines | |||
| 51 | struct isa_driver *isa_driver = dev->platform_data; | 51 | struct isa_driver *isa_driver = dev->platform_data; |
| 52 | 52 | ||
| 53 | if (isa_driver && isa_driver->remove) | 53 | if (isa_driver && isa_driver->remove) |
| 54 | return isa_driver->remove(dev, to_isa_dev(dev)->id); | 54 | isa_driver->remove(dev, to_isa_dev(dev)->id); |
| 55 | 55 | ||
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| @@ -282,7 +282,7 @@ static int elektor_probe(struct device *dev, unsigned int id) · 281 unmodified lines | |||
| 282 | return -ENODEV; | 282 | return -ENODEV; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static int elektor_remove(struct device *dev, unsigned int id) | 285 | static void elektor_remove(struct device *dev, unsigned int id) |
| 286 | { | 286 | { |
| 287 | i2c_del_adapter(&pcf_isa_ops); | 287 | i2c_del_adapter(&pcf_isa_ops); |
| 288 | 288 | ||
| @@ -298,8 +298,6 @@ static int elektor_remove(struct device *dev, unsigned int id) · 9 unmodified lines | |||
| 298 | iounmap(base_iomem); | 298 | iounmap(base_iomem); |
| 299 | release_mem_region(base, 2); | 299 | release_mem_region(base, 2); |
| 300 | } | 300 | } |
| 301 | |||
| 302 | return 0; | ||
| 303 | } | 301 | } |
| 304 | 302 | ||
| 305 | static struct isa_driver i2c_elektor_driver = { | 303 | static struct isa_driver i2c_elektor_driver = { |
| @@ -161,7 +161,7 @@ static int pca_isa_probe(struct device *dev, unsigned int id) · 160 unmodified lines | |||
| 161 | return -ENODEV; | 161 | return -ENODEV; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static int pca_isa_remove(struct device *dev, unsigned int id) | 164 | static void pca_isa_remove(struct device *dev, unsigned int id) |
| 165 | { | 165 | { |
| 166 | i2c_del_adapter(&pca_isa_ops); | 166 | i2c_del_adapter(&pca_isa_ops); |
| 167 | 167 | ||
| @@ -170,8 +170,6 @@ static int pca_isa_remove(struct device *dev, unsigned int id) · 2 unmodified lines | |||
| 170 | free_irq(irq, &pca_isa_ops); | 170 | free_irq(irq, &pca_isa_ops); |
| 171 | } | 171 | } |
| 172 | release_region(base, IO_SIZE); | 172 | release_region(base, IO_SIZE); |
| 173 | |||
| 174 | return 0; | ||
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | static struct isa_driver pca_isa_driver = { | 175 | static struct isa_driver pca_isa_driver = { |
| @@ -171,7 +171,7 @@ static int htcpen_isa_probe(struct device *dev, unsigned int id) · 170 unmodified lines | |||
| 171 | return err; | 171 | return err; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | static int htcpen_isa_remove(struct device *dev, unsigned int id) | 174 | static void htcpen_isa_remove(struct device *dev, unsigned int id) |
| 175 | { | 175 | { |
| 176 | struct input_dev *htcpen_dev = dev_get_drvdata(dev); | 176 | struct input_dev *htcpen_dev = dev_get_drvdata(dev); |
| 177 | 177 | ||
| @@ -182,8 +182,6 @@ static int htcpen_isa_remove(struct device *dev, unsigned int id) · 4 unmodified lines | |||
| 182 | release_region(HTCPEN_PORT_INDEX, 2); | 182 | release_region(HTCPEN_PORT_INDEX, 2); |
| 183 | release_region(HTCPEN_PORT_INIT, 1); | 183 | release_region(HTCPEN_PORT_INIT, 1); |
| 184 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); | 184 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); |
| 185 | |||
| 186 | return 0; | ||
| 187 | } | 185 | } |
| 188 | 186 | ||
| 189 | #ifdef CONFIG_PM | 187 | #ifdef CONFIG_PM |
| @@ -273,8 +273,8 @@ err_dev_reg: · 272 unmodified lines | |||
| 273 | return res; | 273 | return res; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static int radio_isa_common_remove(struct radio_isa_card *isa, | 276 | static void radio_isa_common_remove(struct radio_isa_card *isa, |
| 277 | unsigned region_size) | 277 | unsigned region_size) |
| 278 | { | 278 | { |
| 279 | const struct radio_isa_ops *ops = isa->drv->ops; | 279 | const struct radio_isa_ops *ops = isa->drv->ops; |
| 280 | 280 | ||
| @@ -285,7 +285,6 @@ static int radio_isa_common_remove(struct radio_isa_card *isa, · 4 unmodified lines | |||
| 285 | release_region(isa->io, region_size); | 285 | release_region(isa->io, region_size); |
| 286 | v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card); | 286 | v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card); |
| 287 | kfree(isa); | 287 | kfree(isa); |
| 288 | return 0; | ||
| 289 | } | 288 | } |
| 290 | 289 | ||
| 291 | int radio_isa_probe(struct device *pdev, unsigned int dev) | 290 | int radio_isa_probe(struct device *pdev, unsigned int dev) |
| @@ -338,11 +337,11 @@ int radio_isa_probe(struct device *pdev, unsigned int dev) · 46 unmodified lines | |||
| 338 | } | 337 | } |
| 339 | EXPORT_SYMBOL_GPL(radio_isa_probe); | 338 | EXPORT_SYMBOL_GPL(radio_isa_probe); |
| 340 | 339 | ||
| 341 | int radio_isa_remove(struct device *pdev, unsigned int dev) | 340 | void radio_isa_remove(struct device *pdev, unsigned int dev) |
| 342 | { | 341 | { |
| 343 | struct radio_isa_card *isa = dev_get_drvdata(pdev); | 342 | struct radio_isa_card *isa = dev_get_drvdata(pdev); |
| 344 | 343 | ||
| 345 | return radio_isa_common_remove(isa, isa->drv->region_size); | 344 | radio_isa_common_remove(isa, isa->drv->region_size); |
| 346 | } | 345 | } |
| 347 | EXPORT_SYMBOL_GPL(radio_isa_remove); | 346 | EXPORT_SYMBOL_GPL(radio_isa_remove); |
| 348 | 347 | ||
| @@ -91,7 +91,7 @@ struct radio_isa_driver { · 90 unmodified lines | |||
| 91 | 91 | ||
| 92 | int radio_isa_match(struct device *pdev, unsigned int dev); | 92 | int radio_isa_match(struct device *pdev, unsigned int dev); |
| 93 | int radio_isa_probe(struct device *pdev, unsigned int dev); | 93 | int radio_isa_probe(struct device *pdev, unsigned int dev); |
| 94 | int radio_isa_remove(struct device *pdev, unsigned int dev); | 94 | void radio_isa_remove(struct device *pdev, unsigned int dev); |
| 95 | #ifdef CONFIG_PNP | 95 | #ifdef CONFIG_PNP |
| 96 | int radio_isa_pnp_probe(struct pnp_dev *dev, | 96 | int radio_isa_pnp_probe(struct pnp_dev *dev, |
| 97 | const struct pnp_device_id *dev_id); | 97 | const struct pnp_device_id *dev_id); |
| @@ -293,11 +293,9 @@ static void fmr2_remove(struct fmr2 *fmr2) · 292 unmodified lines | |||
| 293 | kfree(fmr2); | 293 | kfree(fmr2); |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | static int fmr2_isa_remove(struct device *pdev, unsigned int ndev) | 296 | static void fmr2_isa_remove(struct device *pdev, unsigned int ndev) |
| 297 | { | 297 | { |
| 298 | fmr2_remove(dev_get_drvdata(pdev)); | 298 | fmr2_remove(dev_get_drvdata(pdev)); |
| 299 | |||
| 300 | return 0; | ||
| 301 | } | 299 | } |
| 302 | 300 | ||
| 303 | static void fmr2_pnp_remove(struct pnp_dev *pdev) | 301 | static void fmr2_pnp_remove(struct pnp_dev *pdev) |
| @@ -797,17 +797,6 @@ const struct dev_pm_ops arizona_pm_ops = { · 796 unmodified lines | |||
| 797 | EXPORT_SYMBOL_GPL(arizona_pm_ops); | 797 | EXPORT_SYMBOL_GPL(arizona_pm_ops); |
| 798 | 798 | ||
| 799 | #ifdef CONFIG_OF | 799 | #ifdef CONFIG_OF |
| 800 | unsigned long arizona_of_get_type(struct device *dev) | ||
| 801 | { | ||
| 802 | const struct of_device_id *id = of_match_device(arizona_of_match, dev); | ||
| 803 | |||
| 804 | if (id) | ||
| 805 | return (unsigned long)id->data; | ||
| 806 | else | ||
| 807 | return 0; | ||
| 808 | } | ||
| 809 | EXPORT_SYMBOL_GPL(arizona_of_get_type); | ||
| 810 | |||
| 811 | static int arizona_of_get_core_pdata(struct arizona *arizona) | 800 | static int arizona_of_get_core_pdata(struct arizona *arizona) |
| 812 | { | 801 | { |
| 813 | struct arizona_pdata *pdata = &arizona->pdata; | 802 | struct arizona_pdata *pdata = &arizona->pdata; |
| @@ -23,14 +23,16 @@ · 22 unmodified lines | |||
| 23 | static int arizona_i2c_probe(struct i2c_client *i2c, | 23 | static int arizona_i2c_probe(struct i2c_client *i2c, |
| 24 | const struct i2c_device_id *id) | 24 | const struct i2c_device_id *id) |
| 25 | { | 25 | { |
| 26 | const void *match_data; | ||
| 26 | struct arizona *arizona; | 27 | struct arizona *arizona; |
| 27 | const struct regmap_config *regmap_config = NULL; | 28 | const struct regmap_config *regmap_config = NULL; |
| 28 | unsigned long type; | 29 | unsigned long type = 0; |
| 29 | int ret; | 30 | int ret; |
| 30 | 31 | ||
| 31 | if (i2c->dev.of_node) | 32 | match_data = device_get_match_data(&i2c->dev); |
| 32 | type = arizona_of_get_type(&i2c->dev); | 33 | if (match_data) |
| 33 | else | 34 | type = (unsigned long)match_data; |
| 35 | else if (id) | ||
| 34 | type = id->driver_data; | 36 | type = id->driver_data; |
| 35 | 37 | ||
| 36 | switch (type) { | 38 | switch (type) { |
| @@ -115,6 +117,7 @@ static struct i2c_driver arizona_i2c_driver = { · 78 unmodified lines | |||
| 115 | 117 | ||
| 116 | module_i2c_driver(arizona_i2c_driver); | 118 | module_i2c_driver(arizona_i2c_driver); |
| 117 | 119 | ||
| 120 | MODULE_SOFTDEP("pre: arizona_ldo1"); | ||
| 118 | MODULE_DESCRIPTION("Arizona I2C bus interface"); | 121 | MODULE_DESCRIPTION("Arizona I2C bus interface"); |
| 119 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 122 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 120 | MODULE_LICENSE("GPL"); | 123 | MODULE_LICENSE("GPL"); |
| @@ -7,7 +7,10 @@ · 6 unmodified lines | |||
| 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/acpi.h> | ||
| 10 | #include <linux/err.h> | 11 | #include <linux/err.h> |
| 12 | #include <linux/gpio/consumer.h> | ||
| 13 | #include <linux/gpio/machine.h> | ||
| 11 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 12 | #include <linux/pm_runtime.h> | 15 | #include <linux/pm_runtime.h> |
| 13 | #include <linux/regmap.h> | 16 | #include <linux/regmap.h> |
| @@ -15,22 +18,141 @@ · 1 unmodified line | |||
| 15 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 16 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
| 17 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <uapi/linux/input-event-codes.h> | ||
| 18 | 22 | ||
| 19 | #include <linux/mfd/arizona/core.h> | 23 | #include <linux/mfd/arizona/core.h> |
| 20 | 24 | ||
| 21 | #include "arizona.h" | 25 | #include "arizona.h" |
| 22 | 26 | ||
| 27 | #ifdef CONFIG_ACPI | ||
| 28 | const struct acpi_gpio_params reset_gpios = { 1, 0, false }; | ||
| 29 | const struct acpi_gpio_params ldoena_gpios = { 2, 0, false }; | ||
| 30 | |||
| 31 | static const struct acpi_gpio_mapping arizona_acpi_gpios[] = { | ||
| 32 | { "reset-gpios", &reset_gpios, 1, }, | ||
| 33 | { "wlf,ldoena-gpios", &ldoena_gpios, 1 }, | ||
| 34 | { } | ||
| 35 | }; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * The ACPI resources for the device only describe external GPIO-s. They do | ||
| 39 | * not provide mappings for the GPIO-s coming from the Arizona codec itself. | ||
| 40 | */ | ||
| 41 | static const struct gpiod_lookup arizona_soc_gpios[] = { | ||
| 42 | { "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH }, | ||
| 43 | { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW }, | ||
| 44 | }; | ||
| 45 | |||
| 46 | /* | ||
| 47 | * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: | ||
| 48 | * Function A Play/Pause: 0 ohm | ||
| 49 | * Function D Voice assistant: 135 ohm | ||
| 50 | * Function B Volume Up 240 ohm | ||
| 51 | * Function C Volume Down 470 ohm | ||
| 52 | * Minimum Mic DC resistance 1000 ohm | ||
| 53 | * Minimum Ear speaker impedance 16 ohm | ||
| 54 | * Note the first max value below must be less then the min. speaker impedance, | ||
| 55 | * to allow CTIA/OMTP detection to work. The other max values are the closest | ||
| 56 | * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. | ||
| 57 | */ | ||
| 58 | static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { | ||
| 59 | { .max = 11, .key = KEY_PLAYPAUSE }, | ||
| 60 | { .max = 186, .key = KEY_VOICECOMMAND }, | ||
| 61 | { .max = 348, .key = KEY_VOLUMEUP }, | ||
| 62 | { .max = 752, .key = KEY_VOLUMEDOWN }, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static void arizona_spi_acpi_remove_lookup(void *lookup) | ||
| 66 | { | ||
| 67 | gpiod_remove_lookup_table(lookup); | ||
| 68 | } | ||
| 69 | |||
| 70 | static int arizona_spi_acpi_probe(struct arizona *arizona) | ||
| 71 | { | ||
| 72 | struct gpiod_lookup_table *lookup; | ||
| 73 | acpi_status status; | ||
| 74 | int ret; | ||
| 75 | |||
| 76 | /* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */ | ||
| 77 | devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios); | ||
| 78 | |||
| 79 | /* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */ | ||
| 80 | lookup = devm_kzalloc(arizona->dev, | ||
| 81 | struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1), | ||
| 82 | GFP_KERNEL); | ||
| 83 | if (!lookup) | ||
| 84 | return -ENOMEM; | ||
| 85 | |||
| 86 | lookup->dev_id = dev_name(arizona->dev); | ||
| 87 | memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios)); | ||
| 88 | |||
| 89 | gpiod_add_lookup_table(lookup); | ||
| 90 | ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup); | ||
| 91 | if (ret) | ||
| 92 | return ret; | ||
| 93 | |||
| 94 | /* Enable 32KHz clock from SoC to codec for jack-detect */ | ||
| 95 | status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL); | ||
| 96 | if (ACPI_FAILURE(status)) | ||
| 97 | dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING | ||
| 101 | * The IRQ line will stay low when a new IRQ event happens between reading | ||
| 102 | * the IRQ status flags and acknowledging them. When the IRQ line stays | ||
| 103 | * low like this the IRQ will never trigger again when its type is set | ||
| 104 | * to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this. | ||
| 105 | * | ||
| 106 | * Note theoretically it is possible that some boards are not capable | ||
| 107 | * of handling active low level interrupts. In that case setting the | ||
| 108 | * flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need | ||
| 109 | * to work around this) but so far all known usages of IRQF_TRIGGER_FALLING | ||
| 110 | * are a bug in the board's DSDT. | ||
| 111 | */ | ||
| 112 | arizona->pdata.irq_flags = IRQF_TRIGGER_LOW; | ||
| 113 | |||
| 114 | /* Wait 200 ms after jack insertion */ | ||
| 115 | arizona->pdata.micd_detect_debounce = 200; | ||
| 116 | |||
| 117 | /* Use standard AOSP values for headset-button mappings */ | ||
| 118 | arizona->pdata.micd_ranges = arizona_micd_aosp_ranges; | ||
| 119 | arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges); | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static const struct acpi_device_id arizona_acpi_match[] = { | ||
| 125 | { | ||
| 126 | .id = "WM510204", | ||
| 127 | .driver_data = WM5102, | ||
| 128 | }, | ||
| 129 | { | ||
| 130 | .id = "WM510205", | ||
| 131 | .driver_data = WM5102, | ||
| 132 | }, | ||
| 133 | { } | ||
| 134 | }; | ||
| 135 | MODULE_DEVICE_TABLE(acpi, arizona_acpi_match); | ||
| 136 | #else | ||
| 137 | static int arizona_spi_acpi_probe(struct arizona *arizona) | ||
| 138 | { | ||
| 139 | return -ENODEV; | ||
| 140 | } | ||
| 141 | #endif | ||
| 142 | |||
| 23 | static int arizona_spi_probe(struct spi_device *spi) | 143 | static int arizona_spi_probe(struct spi_device *spi) |
| 24 | { | 144 | { |
| 25 | const struct spi_device_id *id = spi_get_device_id(spi); | 145 | const struct spi_device_id *id = spi_get_device_id(spi); |
| 146 | const void *match_data; | ||
| 26 | struct arizona *arizona; | 147 | struct arizona *arizona; |
| 27 | const struct regmap_config *regmap_config = NULL; | 148 | const struct regmap_config *regmap_config = NULL; |
| 28 | unsigned long type; | 149 | unsigned long type = 0; |
| 29 | int ret; | 150 | int ret; |
| 30 | 151 | ||
| 31 | if (spi->dev.of_node) | 152 | match_data = device_get_match_data(&spi->dev); |
| 32 | type = arizona_of_get_type(&spi->dev); | 153 | if (match_data) |
| 33 | else | 154 | type = (unsigned long)match_data; |
| 155 | else if (id) | ||
| 34 | type = id->driver_data; | 156 | type = id->driver_data; |
| 35 | 157 | ||
| 36 | switch (type) { | 158 | switch (type) { |
| @@ -75,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi) · 38 unmodified lines | |||
| 75 | arizona->dev = &spi->dev; | 197 | arizona->dev = &spi->dev; |
| 76 | arizona->irq = spi->irq; | 198 | arizona->irq = spi->irq; |
| 77 | 199 | ||
| 200 | if (has_acpi_companion(&spi->dev)) { | ||
| 201 | ret = arizona_spi_acpi_probe(arizona); | ||
| 202 | if (ret) | ||
| 203 | return ret; | ||
| 204 | } | ||
| 205 | |||
| 78 | return arizona_dev_init(arizona); | 206 | return arizona_dev_init(arizona); |
| 79 | } | 207 | } |
| 80 | 208 | ||
| @@ -102,6 +230,7 @@ static struct spi_driver arizona_spi_driver = { · 21 unmodified lines | |||
| 102 | .name = "arizona", | 230 | .name = "arizona", |
| 103 | .pm = &arizona_pm_ops, | 231 | .pm = &arizona_pm_ops, |
| 104 | .of_match_table = of_match_ptr(arizona_of_match), | 232 | .of_match_table = of_match_ptr(arizona_of_match), |
| 233 | .acpi_match_table = ACPI_PTR(arizona_acpi_match), | ||
| 105 | }, | 234 | }, |
| 106 | .probe = arizona_spi_probe, | 235 | .probe = arizona_spi_probe, |
| 107 | .remove = arizona_spi_remove, | 236 | .remove = arizona_spi_remove, |
| @@ -110,6 +239,7 @@ static struct spi_driver arizona_spi_driver = { · 2 unmodified lines | |||
| 110 | 239 | ||
| 111 | module_spi_driver(arizona_spi_driver); | 240 | module_spi_driver(arizona_spi_driver); |
| 112 | 241 | ||
| 242 | MODULE_SOFTDEP("pre: arizona_ldo1"); | ||
| 113 | MODULE_DESCRIPTION("Arizona SPI bus interface"); | 243 | MODULE_DESCRIPTION("Arizona SPI bus interface"); |
| 114 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 244 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 115 | MODULE_LICENSE("GPL"); | 245 | MODULE_LICENSE("GPL"); |
| @@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona); · 49 unmodified lines | |||
| 50 | int arizona_irq_init(struct arizona *arizona); | 50 | int arizona_irq_init(struct arizona *arizona); |
| 51 | int arizona_irq_exit(struct arizona *arizona); | 51 | int arizona_irq_exit(struct arizona *arizona); |
| 52 | 52 | ||
| 53 | #ifdef CONFIG_OF | ||
| 54 | unsigned long arizona_of_get_type(struct device *dev); | ||
| 55 | #else | ||
| 56 | static inline unsigned long arizona_of_get_type(struct device *dev) | ||
| 57 | { | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #endif | 53 | #endif |
| @@ -159,7 +159,7 @@ static int tscan1_probe(struct device *dev, unsigned id) · 158 unmodified lines | |||
| 159 | return -ENXIO; | 159 | return -ENXIO; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | static int tscan1_remove(struct device *dev, unsigned id /*unused*/) | 162 | static void tscan1_remove(struct device *dev, unsigned id /*unused*/) |
| 163 | { | 163 | { |
| 164 | struct net_device *netdev; | 164 | struct net_device *netdev; |
| 165 | struct sja1000_priv *priv; | 165 | struct sja1000_priv *priv; |
| @@ -179,8 +179,6 @@ static int tscan1_remove(struct device *dev, unsigned id /*unused*/) · 13 unmodified lines | |||
| 179 | release_region(pld_base, TSCAN1_PLD_SIZE); | 179 | release_region(pld_base, TSCAN1_PLD_SIZE); |
| 180 | 180 | ||
| 181 | free_sja1000dev(netdev); | 181 | free_sja1000dev(netdev); |
| 182 | |||
| 183 | return 0; | ||
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | static struct isa_driver tscan1_isa_driver = { | 184 | static struct isa_driver tscan1_isa_driver = { |
| @@ -335,12 +335,11 @@ static int el3_isa_match(struct device *pdev, unsigned int ndev) · 334 unmodified lines | |||
| 335 | return 1; | 335 | return 1; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | static int el3_isa_remove(struct device *pdev, | 338 | static void el3_isa_remove(struct device *pdev, |
| 339 | unsigned int ndev) | 339 | unsigned int ndev) |
| 340 | { | 340 | { |
| 341 | el3_device_remove(pdev); | 341 | el3_device_remove(pdev); |
| 342 | dev_set_drvdata(pdev, NULL); | 342 | dev_set_drvdata(pdev, NULL); |
| 343 | return 0; | ||
| 344 | } | 343 | } |
| 345 | 344 | ||
| 346 | #ifdef CONFIG_PM | 345 | #ifdef CONFIG_PM |
| @@ -11459,12 +11459,11 @@ static int advansys_isa_probe(struct device *dev, unsigned int id) · 11458 unmodified lines | |||
| 11459 | return err; | 11459 | return err; |
| 11460 | } | 11460 | } |
| 11461 | 11461 | ||
| 11462 | static int advansys_isa_remove(struct device *dev, unsigned int id) | 11462 | static void advansys_isa_remove(struct device *dev, unsigned int id) |
| 11463 | { | 11463 | { |
| 11464 | int ioport = _asc_def_iop_base[id]; | 11464 | int ioport = _asc_def_iop_base[id]; |
| 11465 | advansys_release(dev_get_drvdata(dev)); | 11465 | advansys_release(dev_get_drvdata(dev)); |
| 11466 | release_region(ioport, ASC_IOADR_GAP); | 11466 | release_region(ioport, ASC_IOADR_GAP); |
| 11467 | return 0; | ||
| 11468 | } | 11467 | } |
| 11469 | 11468 | ||
| 11470 | static struct isa_driver advansys_isa_driver = { | 11469 | static struct isa_driver advansys_isa_driver = { |
| @@ -1025,12 +1025,11 @@ static int aha1542_isa_match(struct device *pdev, unsigned int ndev) · 1024 unmodified lines | |||
| 1025 | return 1; | 1025 | return 1; |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| 1028 | static int aha1542_isa_remove(struct device *pdev, | 1028 | static void aha1542_isa_remove(struct device *pdev, |
| 1029 | unsigned int ndev) | 1029 | unsigned int ndev) |
| 1030 | { | 1030 | { |
| 1031 | aha1542_release(dev_get_drvdata(pdev)); | 1031 | aha1542_release(dev_get_drvdata(pdev)); |
| 1032 | dev_set_drvdata(pdev, NULL); | 1032 | dev_set_drvdata(pdev, NULL); |
| 1033 | return 0; | ||
| 1034 | } | 1033 | } |
| 1035 | 1034 | ||
| 1036 | static struct isa_driver aha1542_isa_driver = { | 1035 | static struct isa_driver aha1542_isa_driver = { |
| @@ -175,7 +175,7 @@ static int fdomain_isa_param_match(struct device *dev, unsigned int ndev) · 174 unmodified lines | |||
| 175 | return 1; | 175 | return 1; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static int fdomain_isa_remove(struct device *dev, unsigned int ndev) | 178 | static void fdomain_isa_remove(struct device *dev, unsigned int ndev) |
| 179 | { | 179 | { |
| 180 | struct Scsi_Host *sh = dev_get_drvdata(dev); | 180 | struct Scsi_Host *sh = dev_get_drvdata(dev); |
| 181 | int base = sh->io_port; | 181 | int base = sh->io_port; |
| @@ -183,7 +183,6 @@ static int fdomain_isa_remove(struct device *dev, unsigned int ndev) · 1 unmodified line | |||
| 183 | fdomain_destroy(sh); | 183 | fdomain_destroy(sh); |
| 184 | release_region(base, FDOMAIN_REGION_SIZE); | 184 | release_region(base, FDOMAIN_REGION_SIZE); |
| 185 | dev_set_drvdata(dev, NULL); | 185 | dev_set_drvdata(dev, NULL); |
| 186 | return 0; | ||
| 187 | } | 186 | } |
| 188 | 187 | ||
| 189 | static struct isa_driver fdomain_isa_driver = { | 188 | static struct isa_driver fdomain_isa_driver = { |
| @@ -720,12 +720,11 @@ static int generic_NCR5380_isa_match(struct device *pdev, unsigned int ndev) · 719 unmodified lines | |||
| 720 | return 1; | 720 | return 1; |
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | static int generic_NCR5380_isa_remove(struct device *pdev, | 723 | static void generic_NCR5380_isa_remove(struct device *pdev, |
| 724 | unsigned int ndev) | 724 | unsigned int ndev) |
| 725 | { | 725 | { |
| 726 | generic_NCR5380_release_resources(dev_get_drvdata(pdev)); | 726 | generic_NCR5380_release_resources(dev_get_drvdata(pdev)); |
| 727 | dev_set_drvdata(pdev, NULL); | 727 | dev_set_drvdata(pdev, NULL); |
| 728 | return 0; | ||
| 729 | } | 728 | } |
| 730 | 729 | ||
| 731 | static struct isa_driver generic_NCR5380_isa_driver = { | 730 | static struct isa_driver generic_NCR5380_isa_driver = { |
| @@ -951,14 +951,11 @@ error_request_region: · 950 unmodified lines | |||
| 951 | return ret; | 951 | return ret; |
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | static int pcwd_isa_remove(struct device *dev, unsigned int id) | 954 | static void pcwd_isa_remove(struct device *dev, unsigned int id) |
| 955 | { | 955 | { |
| 956 | if (debug >= DEBUG) | 956 | if (debug >= DEBUG) |
| 957 | pr_debug("pcwd_isa_remove id=%d\n", id); | 957 | pr_debug("pcwd_isa_remove id=%d\n", id); |
| 958 | 958 | ||
| 959 | if (!pcwd_private.io_addr) | ||
| 960 | return 1; | ||
| 961 | |||
| 962 | /* Disable the board */ | 959 | /* Disable the board */ |
| 963 | if (!nowayout) | 960 | if (!nowayout) |
| 964 | pcwd_stop(); | 961 | pcwd_stop(); |
| @@ -971,8 +968,6 @@ static int pcwd_isa_remove(struct device *dev, unsigned int id) · 6 unmodified lines | |||
| 971 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); | 968 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
| 972 | pcwd_private.io_addr = 0x0000; | 969 | pcwd_private.io_addr = 0x0000; |
| 973 | cards_found--; | 970 | cards_found--; |
| 974 | |||
| 975 | return 0; | ||
| 976 | } | 971 | } |
| 977 | 972 | ||
| 978 | static void pcwd_isa_shutdown(struct device *dev, unsigned int id) | 973 | static void pcwd_isa_shutdown(struct device *dev, unsigned int id) |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | struct isa_driver { | 13 | struct isa_driver { |
| 14 | int (*match)(struct device *, unsigned int); | 14 | int (*match)(struct device *, unsigned int); |
| 15 | int (*probe)(struct device *, unsigned int); | 15 | int (*probe)(struct device *, unsigned int); |
| 16 | int (*remove)(struct device *, unsigned int); | 16 | void (*remove)(struct device *, unsigned int); |
| 17 | void (*shutdown)(struct device *, unsigned int); | 17 | void (*shutdown)(struct device *, unsigned int); |
| 18 | int (*suspend)(struct device *, unsigned int, pm_message_t); | 18 | int (*suspend)(struct device *, unsigned int, pm_message_t); |
| 19 | int (*resume)(struct device *, unsigned int); | 19 | int (*resume)(struct device *, unsigned int); |
| @@ -4610,6 +4610,7 @@ enum ec_codec_i2s_rx_subcmd { · 4609 unmodified lines | |||
| 4610 | EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, | 4610 | EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, |
| 4611 | EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, | 4611 | EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, |
| 4612 | EC_CODEC_I2S_RX_SET_BCLK = 0x4, | 4612 | EC_CODEC_I2S_RX_SET_BCLK = 0x4, |
| 4613 | EC_CODEC_I2S_RX_RESET = 0x5, | ||
| 4613 | EC_CODEC_I2S_RX_SUBCMD_COUNT, | 4614 | EC_CODEC_I2S_RX_SUBCMD_COUNT, |
| 4614 | }; | 4615 | }; |
| 4615 | 4616 | ||
| @@ -122,6 +122,9 @@ struct snd_card { · 121 unmodified lines | |||
| 122 | 122 | ||
| 123 | size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */ | 123 | size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */ |
| 124 | struct mutex memory_mutex; /* protection for the above */ | 124 | struct mutex memory_mutex; /* protection for the above */ |
| 125 | #ifdef CONFIG_SND_DEBUG | ||
| 126 | struct dentry *debugfs_root; /* debugfs root for card */ | ||
| 127 | #endif | ||
| 125 | 128 | ||
| 126 | #ifdef CONFIG_PM | 129 | #ifdef CONFIG_PM |
| 127 | unsigned int power_state; /* power state */ | 130 | unsigned int power_state; /* power state */ |
| @@ -180,6 +183,9 @@ static inline struct device *snd_card_get_device_link(struct snd_card *card) · 52 unmodified lines | |||
| 180 | extern int snd_major; | 183 | extern int snd_major; |
| 181 | extern int snd_ecards_limit; | 184 | extern int snd_ecards_limit; |
| 182 | extern struct class *sound_class; | 185 | extern struct class *sound_class; |
| 186 | #ifdef CONFIG_SND_DEBUG | ||
| 187 | extern struct dentry *sound_debugfs_root; | ||
| 188 | #endif | ||
| 183 | 189 | ||
| 184 | void snd_request_card(int card); | 190 | void snd_request_card(int card); |
| 185 | 191 | ||
| @@ -66,6 +66,9 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) · 65 unmodified lines | |||
| 66 | * @chan_name: Custom channel name to use when requesting DMA channel. | 66 | * @chan_name: Custom channel name to use when requesting DMA channel. |
| 67 | * @fifo_size: FIFO size of the DAI controller in bytes | 67 | * @fifo_size: FIFO size of the DAI controller in bytes |
| 68 | * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now | 68 | * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now |
| 69 | * @peripheral_config: peripheral configuration for programming peripheral | ||
| 70 | * for dmaengine transfer | ||
| 71 | * @peripheral_size: peripheral configuration buffer size | ||
| 69 | */ | 72 | */ |
| 70 | struct snd_dmaengine_dai_dma_data { | 73 | struct snd_dmaengine_dai_dma_data { |
| 71 | dma_addr_t addr; | 74 | dma_addr_t addr; |
| @@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data { · 4 unmodified lines | |||
| 76 | const char *chan_name; | 79 | const char *chan_name; |
| 77 | unsigned int fifo_size; | 80 | unsigned int fifo_size; |
| 78 | unsigned int flags; | 81 | unsigned int flags; |
| 82 | void *peripheral_config; | ||
| 83 | size_t peripheral_size; | ||
| 79 | }; | 84 | }; |
| 80 | 85 | ||
| 81 | void snd_dmaengine_pcm_set_config_from_dai_data( | 86 | void snd_dmaengine_pcm_set_config_from_dai_data( |
| @@ -9,8 +9,10 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <sound/simple_card_utils.h> | 10 | #include <sound/simple_card_utils.h> |
| 11 | 11 | ||
| 12 | int graph_card_probe(struct snd_soc_card *card); | 12 | int audio_graph_card_probe(struct snd_soc_card *card); |
| 13 | 13 | ||
| 14 | int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); | 14 | int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev); |
| 15 | |||
| 16 | int audio_graph_remove(struct platform_device *pdev); | ||
| 15 | 17 | ||
| 16 | #endif /* __GRAPH_CARD_H */ | 18 | #endif /* __GRAPH_CARD_H */ |
| @@ -241,6 +241,8 @@ struct hdac_bus_ops { · 240 unmodified lines | |||
| 241 | /* get a response from the last command */ | 241 | /* get a response from the last command */ |
| 242 | int (*get_response)(struct hdac_bus *bus, unsigned int addr, | 242 | int (*get_response)(struct hdac_bus *bus, unsigned int addr, |
| 243 | unsigned int *res); | 243 | unsigned int *res); |
| 244 | /* notify of codec link power-up/down */ | ||
| 245 | void (*link_power)(struct hdac_device *hdev, bool enable); | ||
| 244 | }; | 246 | }; |
| 245 | 247 | ||
| 246 | /* | 248 | /* |
| @@ -378,15 +380,8 @@ void snd_hdac_bus_exit(struct hdac_bus *bus); · 131 unmodified lines | |||
| 378 | int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr, | 380 | int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr, |
| 379 | unsigned int cmd, unsigned int *res); | 381 | unsigned int cmd, unsigned int *res); |
| 380 | 382 | ||
| 381 | static inline void snd_hdac_codec_link_up(struct hdac_device *codec) | 383 | void snd_hdac_codec_link_up(struct hdac_device *codec); |
| 382 | { | 384 | void snd_hdac_codec_link_down(struct hdac_device *codec); |
| 383 | set_bit(codec->addr, &codec->bus->codec_powered); | ||
| 384 | } | ||
| 385 | |||
| 386 | static inline void snd_hdac_codec_link_down(struct hdac_device *codec) | ||
| 387 | { | ||
| 388 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
| 389 | } | ||
| 390 | 385 | ||
| 391 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); | 386 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); |
| 392 | int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, | 387 | int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, |
| @@ -400,6 +395,7 @@ void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus); · 7 unmodified lines | |||
| 400 | void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus); | 395 | void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus); |
| 401 | void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus); | 396 | void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus); |
| 402 | int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset); | 397 | int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset); |
| 398 | void snd_hdac_bus_link_power(struct hdac_device *hdev, bool enable); | ||
| 403 | 399 | ||
| 404 | void snd_hdac_bus_update_rirb(struct hdac_bus *bus); | 400 | void snd_hdac_bus_update_rirb(struct hdac_bus *bus); |
| 405 | int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, | 401 | int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, |
| @@ -131,6 +131,8 @@ void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, · 130 unmodified lines | |||
| 131 | int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link); | 131 | int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link); |
| 132 | int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link); | 132 | int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *link); |
| 133 | 133 | ||
| 134 | void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable); | ||
| 135 | |||
| 134 | /* update register macro */ | 136 | /* update register macro */ |
| 135 | #define snd_hdac_updatel(addr, reg, mask, val) \ | 137 | #define snd_hdac_updatel(addr, reg, mask, val) \ |
| 136 | writel(((readl(addr + reg) & ~(mask)) | (val)), \ | 138 | writel(((readl(addr + reg) & ~(mask)) | (val)), \ |
| @@ -34,6 +34,11 @@ struct hdmi_codec_daifmt { · 33 unmodified lines | |||
| 34 | unsigned int frame_clk_inv:1; | 34 | unsigned int frame_clk_inv:1; |
| 35 | unsigned int bit_clk_master:1; | 35 | unsigned int bit_clk_master:1; |
| 36 | unsigned int frame_clk_master:1; | 36 | unsigned int frame_clk_master:1; |
| 37 | /* bit_fmt could be standard PCM format or | ||
| 38 | * IEC958 encoded format. ALSA IEC958 plugin will pass | ||
| 39 | * IEC958_SUBFRAME format to the underneath driver. | ||
| 40 | */ | ||
| 41 | snd_pcm_format_t bit_fmt; | ||
| 37 | }; | 42 | }; |
| 38 | 43 | ||
| 39 | /* | 44 | /* |
| @@ -67,6 +67,7 @@ struct snd_jack { · 66 unmodified lines | |||
| 67 | char name[100]; | 67 | char name[100]; |
| 68 | unsigned int key[6]; /* Keep in sync with definitions above */ | 68 | unsigned int key[6]; /* Keep in sync with definitions above */ |
| 69 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ | 69 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ |
| 70 | int hw_status_cache; | ||
| 70 | void *private_data; | 71 | void *private_data; |
| 71 | void (*private_free)(struct snd_jack *); | 72 | void (*private_free)(struct snd_jack *); |
| 72 | }; | 73 | }; |
| @@ -22,6 +22,8 @@ struct rt5645_platform_data { · 21 unmodified lines | |||
| 22 | bool level_trigger_irq; | 22 | bool level_trigger_irq; |
| 23 | /* Invert JD1_1 status polarity */ | 23 | /* Invert JD1_1 status polarity */ |
| 24 | bool inv_jd1_1; | 24 | bool inv_jd1_1; |
| 25 | /* Invert HP detect status polarity */ | ||
| 26 | bool inv_hp_pol; | ||
| 25 | 27 | ||
| 26 | /* Value to asign to snd_soc_card.long_name */ | 28 | /* Value to asign to snd_soc_card.long_name */ |
| 27 | const char *long_name; | 29 | const char *long_name; |
| @@ -353,6 +353,12 @@ int snd_soc_component_test_bits(struct snd_soc_component *component, · 352 unmodified lines | |||
| 353 | unsigned int reg, unsigned int mask, | 353 | unsigned int reg, unsigned int mask, |
| 354 | unsigned int value); | 354 | unsigned int value); |
| 355 | 355 | ||
| 356 | unsigned int snd_soc_component_read_field(struct snd_soc_component *component, | ||
| 357 | unsigned int reg, unsigned int mask); | ||
| 358 | int snd_soc_component_write_field(struct snd_soc_component *component, | ||
| 359 | unsigned int reg, unsigned int mask, | ||
| 360 | unsigned int val); | ||
| 361 | |||
| 356 | /* component wide operations */ | 362 | /* component wide operations */ |
| 357 | int snd_soc_component_set_sysclk(struct snd_soc_component *component, | 363 | int snd_soc_component_set_sysclk(struct snd_soc_component *component, |
| 358 | int clk_id, int source, | 364 | int clk_id, int source, |
| @@ -353,9 +353,9 @@ struct snd_soc_dai_driver { · 352 unmodified lines | |||
| 353 | /* DAI capabilities */ | 353 | /* DAI capabilities */ |
| 354 | struct snd_soc_pcm_stream capture; | 354 | struct snd_soc_pcm_stream capture; |
| 355 | struct snd_soc_pcm_stream playback; | 355 | struct snd_soc_pcm_stream playback; |
| 356 | unsigned int symmetric_rates:1; | 356 | unsigned int symmetric_rate:1; |
| 357 | unsigned int symmetric_channels:1; | 357 | unsigned int symmetric_channels:1; |
| 358 | unsigned int symmetric_samplebits:1; | 358 | unsigned int symmetric_sample_bits:1; |
| 359 | 359 | ||
| 360 | /* probe ordering - for components with runtime dependencies */ | 360 | /* probe ordering - for components with runtime dependencies */ |
| 361 | int probe_order; | 361 | int probe_order; |
| @@ -685,9 +685,9 @@ struct snd_soc_dai_link { · 684 unmodified lines | |||
| 685 | unsigned int ignore_suspend:1; | 685 | unsigned int ignore_suspend:1; |
| 686 | 686 | ||
| 687 | /* Symmetry requirements */ | 687 | /* Symmetry requirements */ |
| 688 | unsigned int symmetric_rates:1; | 688 | unsigned int symmetric_rate:1; |
| 689 | unsigned int symmetric_channels:1; | 689 | unsigned int symmetric_channels:1; |
| 690 | unsigned int symmetric_samplebits:1; | 690 | unsigned int symmetric_sample_bits:1; |
| 691 | 691 | ||
| 692 | /* Do not create a PCM for this DAI link (Backend link) */ | 692 | /* Do not create a PCM for this DAI link (Backend link) */ |
| 693 | unsigned int no_pcm:1; | 693 | unsigned int no_pcm:1; |
| @@ -58,9 +58,9 @@ struct sof_ext_man_header { · 57 unmodified lines | |||
| 58 | /* Extended manifest elements types */ | 58 | /* Extended manifest elements types */ |
| 59 | enum sof_ext_man_elem_type { | 59 | enum sof_ext_man_elem_type { |
| 60 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, | 60 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, |
| 61 | SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW, | 61 | SOF_EXT_MAN_ELEM_WINDOW = 1, |
| 62 | SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO, | 62 | SOF_EXT_MAN_ELEM_CC_VERSION = 2, |
| 63 | SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO, | 63 | SOF_EXT_MAN_ELEM_DBG_ABI = 4, |
| 64 | SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */ | 64 | SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */ |
| 65 | SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6, | 65 | SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6, |
| 66 | }; | 66 | }; |
| @@ -273,7 +273,7 @@ static struct attribute *ac97_controller_device_attrs[] = { · 272 unmodified lines | |||
| 273 | NULL | 273 | NULL |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | static struct attribute_group ac97_adapter_attr_group = { | 276 | static const struct attribute_group ac97_adapter_attr_group = { |
| 277 | .name = "ac97_operations", | 277 | .name = "ac97_operations", |
| 278 | .attrs = ac97_controller_device_attrs, | 278 | .attrs = ac97_controller_device_attrs, |
| 279 | }; | 279 | }; |
| @@ -1013,7 +1013,7 @@ static int onyx_i2c_probe(struct i2c_client *client, · 1012 unmodified lines | |||
| 1013 | goto fail; | 1013 | goto fail; |
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); | 1016 | strscpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); |
| 1017 | onyx->codec.owner = THIS_MODULE; | 1017 | onyx->codec.owner = THIS_MODULE; |
| 1018 | onyx->codec.init = onyx_init_codec; | 1018 | onyx->codec.init = onyx_init_codec; |
| 1019 | onyx->codec.exit = onyx_exit_codec; | 1019 | onyx->codec.exit = onyx_exit_codec; |
| @@ -894,7 +894,7 @@ static int tas_i2c_probe(struct i2c_client *client, · 893 unmodified lines | |||
| 894 | /* seems that half is a saner default */ | 894 | /* seems that half is a saner default */ |
| 895 | tas->drc_range = TAS3004_DRC_MAX / 2; | 895 | tas->drc_range = TAS3004_DRC_MAX / 2; |
| 896 | 896 | ||
| 897 | strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); | 897 | strscpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); |
| 898 | tas->codec.owner = THIS_MODULE; | 898 | tas->codec.owner = THIS_MODULE; |
| 899 | tas->codec.init = tas_init_codec; | 899 | tas->codec.init = tas_init_codec; |
| 900 | tas->codec.exit = tas_exit_codec; | 900 | tas->codec.exit = tas_exit_codec; |
| @@ -126,7 +126,7 @@ static int __init toonie_init(void) · 125 unmodified lines | |||
| 126 | if (!toonie) | 126 | if (!toonie) |
| 127 | return -ENOMEM; | 127 | return -ENOMEM; |
| 128 | 128 | ||
| 129 | strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name)); | 129 | strscpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name)); |
| 130 | toonie->codec.owner = THIS_MODULE; | 130 | toonie->codec.owner = THIS_MODULE; |
| 131 | toonie->codec.init = toonie_init_codec; | 131 | toonie->codec.init = toonie_init_codec; |
| 132 | toonie->codec.exit = toonie_exit_codec; | 132 | toonie->codec.exit = toonie_exit_codec; |
| @@ -28,10 +28,10 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev) · 27 unmodified lines | |||
| 28 | return err; | 28 | return err; |
| 29 | aoa_card = alsa_card->private_data; | 29 | aoa_card = alsa_card->private_data; |
| 30 | aoa_card->alsa_card = alsa_card; | 30 | aoa_card->alsa_card = alsa_card; |
| 31 | strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver)); | 31 | strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver)); |
| 32 | strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname)); | 32 | strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname)); |
| 33 | strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname)); | 33 | strscpy(alsa_card->longname, name, sizeof(alsa_card->longname)); |
| 34 | strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername)); | 34 | strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername)); |
| 35 | err = snd_card_register(aoa_card->alsa_card); | 35 | err = snd_card_register(aoa_card->alsa_card); |
| 36 | if (err < 0) { | 36 | if (err < 0) { |
| 37 | printk(KERN_ERR "snd-aoa: couldn't register alsa card\n"); | 37 | printk(KERN_ERR "snd-aoa: couldn't register alsa card\n"); |
| @@ -948,7 +948,7 @@ static void layout_attached_codec(struct aoa_codec *codec) · 947 unmodified lines | |||
| 948 | ldev->gpio.methods->set_lineout(codec->gpio, 1); | 948 | ldev->gpio.methods->set_lineout(codec->gpio, 1); |
| 949 | ctl = snd_ctl_new1(&lineout_ctl, codec->gpio); | 949 | ctl = snd_ctl_new1(&lineout_ctl, codec->gpio); |
| 950 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) | 950 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 951 | strlcpy(ctl->id.name, | 951 | strscpy(ctl->id.name, |
| 952 | "Headphone Switch", sizeof(ctl->id.name)); | 952 | "Headphone Switch", sizeof(ctl->id.name)); |
| 953 | ldev->lineout_ctrl = ctl; | 953 | ldev->lineout_ctrl = ctl; |
| 954 | aoa_snd_ctl_add(ctl); | 954 | aoa_snd_ctl_add(ctl); |
| @@ -962,14 +962,14 @@ static void layout_attached_codec(struct aoa_codec *codec) · 7 unmodified lines | |||
| 962 | ctl = snd_ctl_new1(&lineout_detect_choice, | 962 | ctl = snd_ctl_new1(&lineout_detect_choice, |
| 963 | ldev); | 963 | ldev); |
| 964 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) | 964 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 965 | strlcpy(ctl->id.name, | 965 | strscpy(ctl->id.name, |
| 966 | "Headphone Detect Autoswitch", | 966 | "Headphone Detect Autoswitch", |
| 967 | sizeof(ctl->id.name)); | 967 | sizeof(ctl->id.name)); |
| 968 | aoa_snd_ctl_add(ctl); | 968 | aoa_snd_ctl_add(ctl); |
| 969 | ctl = snd_ctl_new1(&lineout_detected, | 969 | ctl = snd_ctl_new1(&lineout_detected, |
| 970 | ldev); | 970 | ldev); |
| 971 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) | 971 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 972 | strlcpy(ctl->id.name, | 972 | strscpy(ctl->id.name, |
| 973 | "Headphone Detected", | 973 | "Headphone Detected", |
| 974 | sizeof(ctl->id.name)); | 974 | sizeof(ctl->id.name)); |
| 975 | ldev->lineout_detected_ctrl = ctl; | 975 | ldev->lineout_detected_ctrl = ctl; |
| @@ -13,7 +13,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, · 12 unmodified lines | |||
| 13 | int length; | 13 | int length; |
| 14 | 14 | ||
| 15 | if (*sdev->modalias) { | 15 | if (*sdev->modalias) { |
| 16 | strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1); | 16 | strscpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1); |
| 17 | strcat(buf, "\n"); | 17 | strcat(buf, "\n"); |
| 18 | length = strlen(buf); | 18 | length = strlen(buf); |
| 19 | } else { | 19 | } else { |
| @@ -890,8 +890,8 @@ static struct aaci *aaci_init_card(struct amba_device *dev) · 889 unmodified lines | |||
| 890 | 890 | ||
| 891 | card->private_free = aaci_free_card; | 891 | card->private_free = aaci_free_card; |
| 892 | 892 | ||
| 893 | strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); | 893 | strscpy(card->driver, DRIVER_NAME, sizeof(card->driver)); |
| 894 | strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); | 894 | strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); |
| 895 | snprintf(card->longname, sizeof(card->longname), | 895 | snprintf(card->longname, sizeof(card->longname), |
| 896 | "%s PL%03x rev%u at 0x%08llx, irq %d", | 896 | "%s PL%03x rev%u at 0x%08llx, irq %d", |
| 897 | card->shortname, amba_part(dev), amba_rev(dev), | 897 | card->shortname, amba_part(dev), amba_rev(dev), |
| @@ -921,7 +921,7 @@ static int aaci_init_pcm(struct aaci *aaci) · 23 unmodified lines | |||
| 921 | pcm->private_data = aaci; | 921 | pcm->private_data = aaci; |
| 922 | pcm->info_flags = 0; | 922 | pcm->info_flags = 0; |
| 923 | 923 | ||
| 924 | strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); | 924 | strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); |
| 925 | 925 | ||
| 926 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); | 926 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); |
| 927 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); | 927 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); |
| @@ -235,7 +235,7 @@ static int pxa2xx_ac97_probe(struct platform_device *dev) · 234 unmodified lines | |||
| 235 | if (ret < 0) | 235 | if (ret < 0) |
| 236 | goto err; | 236 | goto err; |
| 237 | 237 | ||
| 238 | strlcpy(card->driver, dev->dev.driver->name, sizeof(card->driver)); | 238 | strscpy(card->driver, dev->dev.driver->name, sizeof(card->driver)); |
| 239 | 239 | ||
| 240 | ret = pxa2xx_ac97_pcm_new(card); | 240 | ret = pxa2xx_ac97_pcm_new(card); |
| 241 | if (ret) | 241 | if (ret) |
| @@ -187,6 +187,15 @@ config SND_CTL_VALIDATION · 186 unmodified lines | |||
| 187 | from the driver are in the proper ranges or the check of the invalid | 187 | from the driver are in the proper ranges or the check of the invalid |
| 188 | access at out-of-array areas. | 188 | access at out-of-array areas. |
| 189 | 189 | ||
| 190 | config SND_JACK_INJECTION_DEBUG | ||
| 191 | bool "Sound jack injection interface via debugfs" | ||
| 192 | depends on SND_JACK && SND_DEBUG && DEBUG_FS | ||
| 193 | help | ||
| 194 | This option can be used to enable or disable sound jack | ||
| 195 | software injection. | ||
| 196 | Say Y if you are debugging via jack injection interface. | ||
| 197 | If unsure select "N". | ||
| 198 | |||
| 190 | config SND_VMASTER | 199 | config SND_VMASTER |
| 191 | bool | 200 | bool |
| 192 | 201 | ||
| @@ -1132,7 +1132,7 @@ static void snd_compress_proc_done(struct snd_compr *compr) · 1131 unmodified lines | |||
| 1132 | 1132 | ||
| 1133 | static inline void snd_compress_set_id(struct snd_compr *compr, const char *id) | 1133 | static inline void snd_compress_set_id(struct snd_compr *compr, const char *id) |
| 1134 | { | 1134 | { |
| 1135 | strlcpy(compr->id, id, sizeof(compr->id)); | 1135 | strscpy(compr->id, id, sizeof(compr->id)); |
| 1136 | } | 1136 | } |
| 1137 | #else | 1137 | #else |
| 1138 | static inline int snd_compress_proc_init(struct snd_compr *compr) | 1138 | static inline int snd_compress_proc_init(struct snd_compr *compr) |
| @@ -261,7 +261,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, · 260 unmodified lines | |||
| 261 | kctl->id.device = ncontrol->device; | 261 | kctl->id.device = ncontrol->device; |
| 262 | kctl->id.subdevice = ncontrol->subdevice; | 262 | kctl->id.subdevice = ncontrol->subdevice; |
| 263 | if (ncontrol->name) { | 263 | if (ncontrol->name) { |
| 264 | strlcpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name)); | 264 | strscpy(kctl->id.name, ncontrol->name, sizeof(kctl->id.name)); |
| 265 | if (strcmp(ncontrol->name, kctl->id.name) != 0) | 265 | if (strcmp(ncontrol->name, kctl->id.name) != 0) |
| 266 | pr_warn("ALSA: Control name '%s' truncated to '%s'\n", | 266 | pr_warn("ALSA: Control name '%s' truncated to '%s'\n", |
| 267 | ncontrol->name, kctl->id.name); | 267 | ncontrol->name, kctl->id.name); |
| @@ -701,12 +701,12 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, · 433 unmodified lines | |||
| 701 | return -ENOMEM; | 701 | return -ENOMEM; |
| 702 | down_read(&snd_ioctl_rwsem); | 702 | down_read(&snd_ioctl_rwsem); |
| 703 | info->card = card->number; | 703 | info->card = card->number; |
| 704 | strlcpy(info->id, card->id, sizeof(info->id)); | 704 | strscpy(info->id, card->id, sizeof(info->id)); |
| 705 | strlcpy(info->driver, card->driver, sizeof(info->driver)); | 705 | strscpy(info->driver, card->driver, sizeof(info->driver)); |
| 706 | strlcpy(info->name, card->shortname, sizeof(info->name)); | 706 | strscpy(info->name, card->shortname, sizeof(info->name)); |
| 707 | strlcpy(info->longname, card->longname, sizeof(info->longname)); | 707 | strscpy(info->longname, card->longname, sizeof(info->longname)); |
| 708 | strlcpy(info->mixername, card->mixername, sizeof(info->mixername)); | 708 | strscpy(info->mixername, card->mixername, sizeof(info->mixername)); |
| 709 | strlcpy(info->components, card->components, sizeof(info->components)); | 709 | strscpy(info->components, card->components, sizeof(info->components)); |
| 710 | up_read(&snd_ioctl_rwsem); | 710 | up_read(&snd_ioctl_rwsem); |
| 711 | if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) { | 711 | if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) { |
| 712 | kfree(info); | 712 | kfree(info); |
| @@ -836,7 +836,7 @@ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control, · 123 unmodified lines | |||
| 836 | { | 836 | { |
| 837 | size_t offset = value_sizes[info->type] * info->count; | 837 | size_t offset = value_sizes[info->type] * info->count; |
| 838 | 838 | ||
| 839 | offset = (offset + sizeof(u32) - 1) / sizeof(u32); | 839 | offset = DIV_ROUND_UP(offset, sizeof(u32)); |
| 840 | memset32((u32 *)control->value.bytes.data + offset, pattern, | 840 | memset32((u32 *)control->value.bytes.data + offset, pattern, |
| 841 | sizeof(control->value) / sizeof(u32) - offset); | 841 | sizeof(control->value) / sizeof(u32) - offset); |
| 842 | } | 842 | } |
| @@ -928,7 +928,7 @@ static int sanity_check_elem_value(struct snd_card *card, · 85 unmodified lines | |||
| 928 | 928 | ||
| 929 | /* check whether the remaining area kept untouched */ | 929 | /* check whether the remaining area kept untouched */ |
| 930 | offset = value_sizes[info->type] * info->count; | 930 | offset = value_sizes[info->type] * info->count; |
| 931 | offset = (offset + sizeof(u32) - 1) / sizeof(u32); | 931 | offset = DIV_ROUND_UP(offset, sizeof(u32)); |
| 932 | p = (u32 *)control->value.bytes.data + offset; | 932 | p = (u32 *)control->value.bytes.data + offset; |
| 933 | for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) { | 933 | for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) { |
| 934 | if (*p != pattern) { | 934 | if (*p != pattern) { |
| @@ -2137,7 +2137,7 @@ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, · 1202 unmodified lines | |||
| 2137 | WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), | 2137 | WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), |
| 2138 | "ALSA: too long item name '%s'\n", | 2138 | "ALSA: too long item name '%s'\n", |
| 2139 | names[info->value.enumerated.item]); | 2139 | names[info->value.enumerated.item]); |
| 2140 | strlcpy(info->value.enumerated.name, | 2140 | strscpy(info->value.enumerated.name, |
| 2141 | names[info->value.enumerated.item], | 2141 | names[info->value.enumerated.item], |
| 2142 | sizeof(info->value.enumerated.name)); | 2142 | sizeof(info->value.enumerated.name)); |
| 2143 | return 0; | 2143 | return 0; |
| @@ -35,7 +35,7 @@ static int get_available_index(struct snd_card *card, const char *name) · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | sid.index = 0; | 36 | sid.index = 0; |
| 37 | sid.iface = SNDRV_CTL_ELEM_IFACE_CARD; | 37 | sid.iface = SNDRV_CTL_ELEM_IFACE_CARD; |
| 38 | strlcpy(sid.name, name, sizeof(sid.name)); | 38 | strscpy(sid.name, name, sizeof(sid.name)); |
| 39 | 39 | ||
| 40 | while (snd_ctl_find_id(card, &sid)) { | 40 | while (snd_ctl_find_id(card, &sid)) { |
| 41 | sid.index++; | 41 | sid.index++; |
| @@ -177,8 +177,8 @@ static int snd_hwdep_info(struct snd_hwdep *hw, · 176 unmodified lines | |||
| 177 | 177 | ||
| 178 | memset(&info, 0, sizeof(info)); | 178 | memset(&info, 0, sizeof(info)); |
| 179 | info.card = hw->card->number; | 179 | info.card = hw->card->number; |
| 180 | strlcpy(info.id, hw->id, sizeof(info.id)); | 180 | strscpy(info.id, hw->id, sizeof(info.id)); |
| 181 | strlcpy(info.name, hw->name, sizeof(info.name)); | 181 | strscpy(info.name, hw->name, sizeof(info.name)); |
| 182 | info.iface = hw->iface; | 182 | info.iface = hw->iface; |
| 183 | if (copy_to_user(_info, &info, sizeof(info))) | 183 | if (copy_to_user(_info, &info, sizeof(info))) |
| 184 | return -EFAULT; | 184 | return -EFAULT; |
| @@ -379,7 +379,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, · 194 unmodified lines | |||
| 379 | hwdep->card = card; | 379 | hwdep->card = card; |
| 380 | hwdep->device = device; | 380 | hwdep->device = device; |
| 381 | if (id) | 381 | if (id) |
| 382 | strlcpy(hwdep->id, id, sizeof(hwdep->id)); | 382 | strscpy(hwdep->id, id, sizeof(hwdep->id)); |
| 383 | 383 | ||
| 384 | snd_device_initialize(&hwdep->dev, card); | 384 | snd_device_initialize(&hwdep->dev, card); |
| 385 | hwdep->dev.release = release_hwdep_device; | 385 | hwdep->dev.release = release_hwdep_device; |
| @@ -13,7 +13,9 @@ · 12 unmodified lines | |||
| 13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
| 14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
| 15 | #include <linux/pm.h> | 15 | #include <linux/pm.h> |
| 16 | #include <linux/debugfs.h> | ||
| 16 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
| 18 | #include <linux/interrupt.h> | ||
| 17 | 19 | ||
| 18 | #include <sound/core.h> | 20 | #include <sound/core.h> |
| 19 | #include <sound/control.h> | 21 | #include <sound/control.h> |
| @@ -161,6 +163,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid, · 141 unmodified lines | |||
| 161 | { | 163 | { |
| 162 | struct snd_card *card; | 164 | struct snd_card *card; |
| 163 | int err; | 165 | int err; |
| 166 | #ifdef CONFIG_SND_DEBUG | ||
| 167 | char name[8]; | ||
| 168 | #endif | ||
| 164 | 169 | ||
| 165 | if (snd_BUG_ON(!card_ret)) | 170 | if (snd_BUG_ON(!card_ret)) |
| 166 | return -EINVAL; | 171 | return -EINVAL; |
| @@ -174,7 +179,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid, · 7 unmodified lines | |||
| 174 | if (extra_size > 0) | 179 | if (extra_size > 0) |
| 175 | card->private_data = (char *)card + sizeof(struct snd_card); | 180 | card->private_data = (char *)card + sizeof(struct snd_card); |
| 176 | if (xid) | 181 | if (xid) |
| 177 | strlcpy(card->id, xid, sizeof(card->id)); | 182 | strscpy(card->id, xid, sizeof(card->id)); |
| 178 | err = 0; | 183 | err = 0; |
| 179 | mutex_lock(&snd_card_mutex); | 184 | mutex_lock(&snd_card_mutex); |
| 180 | if (idx < 0) /* first check the matching module-name slot */ | 185 | if (idx < 0) /* first check the matching module-name slot */ |
| @@ -244,6 +249,12 @@ int snd_card_new(struct device *parent, int idx, const char *xid, · 63 unmodified lines | |||
| 244 | dev_err(parent, "unable to create card info\n"); | 249 | dev_err(parent, "unable to create card info\n"); |
| 245 | goto __error_ctl; | 250 | goto __error_ctl; |
| 246 | } | 251 | } |
| 252 | |||
| 253 | #ifdef CONFIG_SND_DEBUG | ||
| 254 | sprintf(name, "card%d", idx); | ||
| 255 | card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root); | ||
| 256 | #endif | ||
| 257 | |||
| 247 | *card_ret = card; | 258 | *card_ret = card; |
| 248 | return 0; | 259 | return 0; |
| 249 | 260 | ||
| @@ -416,6 +427,9 @@ int snd_card_disconnect(struct snd_card *card) · 166 unmodified lines | |||
| 416 | /* notify all devices that we are disconnected */ | 427 | /* notify all devices that we are disconnected */ |
| 417 | snd_device_disconnect_all(card); | 428 | snd_device_disconnect_all(card); |
| 418 | 429 | ||
| 430 | if (card->sync_irq > 0) | ||
| 431 | synchronize_irq(card->sync_irq); | ||
| 432 | |||
| 419 | snd_info_card_disconnect(card); | 433 | snd_info_card_disconnect(card); |
| 420 | if (card->registered) { | 434 | if (card->registered) { |
| 421 | device_del(&card->card_dev); | 435 | device_del(&card->card_dev); |
| @@ -477,6 +491,10 @@ static int snd_card_do_free(struct snd_card *card) · 55 unmodified lines | |||
| 477 | dev_warn(card->dev, "unable to free card info\n"); | 491 | dev_warn(card->dev, "unable to free card info\n"); |
| 478 | /* Not fatal error */ | 492 | /* Not fatal error */ |
| 479 | } | 493 | } |
| 494 | #ifdef CONFIG_SND_DEBUG | ||
| 495 | debugfs_remove(card->debugfs_root); | ||
| 496 | card->debugfs_root = NULL; | ||
| 497 | #endif | ||
| 480 | if (card->release_completion) | 498 | if (card->release_completion) |
| 481 | complete(card->release_completion); | 499 | complete(card->release_completion); |
| 482 | kfree(card); | 500 | kfree(card); |
| @@ -526,6 +544,7 @@ int snd_card_free(struct snd_card *card) · 43 unmodified lines | |||
| 526 | return ret; | 544 | return ret; |
| 527 | /* wait, until all devices are ready for the free operation */ | 545 | /* wait, until all devices are ready for the free operation */ |
| 528 | wait_for_completion(&released); | 546 | wait_for_completion(&released); |
| 547 | |||
| 529 | return 0; | 548 | return 0; |
| 530 | } | 549 | } |
| 531 | EXPORT_SYMBOL(snd_card_free); | 550 | EXPORT_SYMBOL(snd_card_free); |
| @@ -623,7 +642,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src, · 91 unmodified lines | |||
| 623 | /* last resort... */ | 642 | /* last resort... */ |
| 624 | dev_err(card->dev, "unable to set card id (%s)\n", id); | 643 | dev_err(card->dev, "unable to set card id (%s)\n", id); |
| 625 | if (card->proc_root->name) | 644 | if (card->proc_root->name) |
| 626 | strlcpy(card->id, card->proc_root->name, sizeof(card->id)); | 645 | strscpy(card->id, card->proc_root->name, sizeof(card->id)); |
| 627 | } | 646 | } |
| 628 | 647 | ||
| 629 | /** | 648 | /** |
| @@ -8,6 +8,9 @@ · 7 unmodified lines | |||
| 8 | #include <linux/input.h> | 8 | #include <linux/input.h> |
| 9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/ctype.h> | ||
| 12 | #include <linux/mm.h> | ||
| 13 | #include <linux/debugfs.h> | ||
| 11 | #include <sound/jack.h> | 14 | #include <sound/jack.h> |
| 12 | #include <sound/core.h> | 15 | #include <sound/core.h> |
| 13 | #include <sound/control.h> | 16 | #include <sound/control.h> |
| @@ -16,6 +19,11 @@ struct snd_jack_kctl { · 2 unmodified lines | |||
| 16 | struct snd_kcontrol *kctl; | 19 | struct snd_kcontrol *kctl; |
| 17 | struct list_head list; /* list of controls belong to the same jack */ | 20 | struct list_head list; /* list of controls belong to the same jack */ |
| 18 | unsigned int mask_bits; /* only masked status bits are reported via kctl */ | 21 | unsigned int mask_bits; /* only masked status bits are reported via kctl */ |
| 22 | struct snd_jack *jack; /* pointer to struct snd_jack */ | ||
| 23 | bool sw_inject_enable; /* allow to inject plug event via debugfs */ | ||
| 24 | #ifdef CONFIG_SND_JACK_INJECTION_DEBUG | ||
| 25 | struct dentry *jack_debugfs_root; /* jack_kctl debugfs root */ | ||
| 26 | #endif | ||
| 19 | }; | 27 | }; |
| 20 | 28 | ||
| 21 | #ifdef CONFIG_SND_JACK_INPUT_DEV | 29 | #ifdef CONFIG_SND_JACK_INPUT_DEV |
| @@ -109,12 +117,291 @@ static int snd_jack_dev_register(struct snd_device *device) · 87 unmodified lines | |||
| 109 | } | 117 | } |
| 110 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ | 118 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ |
| 111 | 119 | ||
| 120 | #ifdef CONFIG_SND_JACK_INJECTION_DEBUG | ||
| 121 | static void snd_jack_inject_report(struct snd_jack_kctl *jack_kctl, int status) | ||
| 122 | { | ||
| 123 | struct snd_jack *jack; | ||
| 124 | #ifdef CONFIG_SND_JACK_INPUT_DEV | ||
| 125 | int i; | ||
| 126 | #endif | ||
| 127 | if (!jack_kctl) | ||
| 128 | return; | ||
| 129 | |||
| 130 | jack = jack_kctl->jack; | ||
| 131 | |||
| 132 | if (jack_kctl->sw_inject_enable) | ||
| 133 | snd_kctl_jack_report(jack->card, jack_kctl->kctl, | ||
| 134 | status & jack_kctl->mask_bits); | ||
| 135 | |||
| 136 | #ifdef CONFIG_SND_JACK_INPUT_DEV | ||
| 137 | if (!jack->input_dev) | ||
| 138 | return; | ||
| 139 | |||
| 140 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { | ||
| 141 | int testbit = ((SND_JACK_BTN_0 >> i) & jack_kctl->mask_bits); | ||
| 142 | |||
| 143 | if (jack->type & testbit) | ||
| 144 | input_report_key(jack->input_dev, jack->key[i], | ||
| 145 | status & testbit); | ||
| 146 | } | ||
| 147 | |||
| 148 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { | ||
| 149 | int testbit = ((1 << i) & jack_kctl->mask_bits); | ||
| 150 | |||
| 151 | if (jack->type & testbit) | ||
| 152 | input_report_switch(jack->input_dev, | ||
| 153 | jack_switch_types[i], | ||
| 154 | status & testbit); | ||
| 155 | } | ||
| 156 | |||
| 157 | input_sync(jack->input_dev); | ||
| 158 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ | ||
| 159 | } | ||
| 160 | |||
| 161 | static ssize_t sw_inject_enable_read(struct file *file, | ||
| 162 | char __user *to, size_t count, loff_t *ppos) | ||
| 163 | { | ||
| 164 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 165 | int len, ret; | ||
| 166 | char buf[128]; | ||
| 167 | |||
| 168 | len = scnprintf(buf, sizeof(buf), "%s: %s\t\t%s: %i\n", "Jack", jack_kctl->kctl->id.name, | ||
| 169 | "Inject Enabled", jack_kctl->sw_inject_enable); | ||
| 170 | ret = simple_read_from_buffer(to, count, ppos, buf, len); | ||
| 171 | |||
| 172 | return ret; | ||
| 173 | } | ||
| 174 | |||
| 175 | static ssize_t sw_inject_enable_write(struct file *file, | ||
| 176 | const char __user *from, size_t count, loff_t *ppos) | ||
| 177 | { | ||
| 178 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 179 | int ret, err; | ||
| 180 | unsigned long enable; | ||
| 181 | char buf[8] = { 0 }; | ||
| 182 | |||
| 183 | ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); | ||
| 184 | err = kstrtoul(buf, 0, &enable); | ||
| 185 | if (err) | ||
| 186 | return err; | ||
| 187 | |||
| 188 | if (jack_kctl->sw_inject_enable == (!!enable)) | ||
| 189 | return ret; | ||
| 190 | |||
| 191 | jack_kctl->sw_inject_enable = !!enable; | ||
| 192 | |||
| 193 | if (!jack_kctl->sw_inject_enable) | ||
| 194 | snd_jack_report(jack_kctl->jack, jack_kctl->jack->hw_status_cache); | ||
| 195 | |||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | static ssize_t jackin_inject_write(struct file *file, | ||
| 200 | const char __user *from, size_t count, loff_t *ppos) | ||
| 201 | { | ||
| 202 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 203 | int ret, err; | ||
| 204 | unsigned long enable; | ||
| 205 | char buf[8] = { 0 }; | ||
| 206 | |||
| 207 | if (!jack_kctl->sw_inject_enable) | ||
| 208 | return -EINVAL; | ||
| 209 | |||
| 210 | ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count); | ||
| 211 | err = kstrtoul(buf, 0, &enable); | ||
| 212 | if (err) | ||
| 213 | return err; | ||
| 214 | |||
| 215 | snd_jack_inject_report(jack_kctl, !!enable ? jack_kctl->mask_bits : 0); | ||
| 216 | |||
| 217 | return ret; | ||
| 218 | } | ||
| 219 | |||
| 220 | static ssize_t jack_kctl_id_read(struct file *file, | ||
| 221 | char __user *to, size_t count, loff_t *ppos) | ||
| 222 | { | ||
| 223 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 224 | char buf[64]; | ||
| 225 | int len, ret; | ||
| 226 | |||
| 227 | len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->id.name); | ||
| 228 | ret = simple_read_from_buffer(to, count, ppos, buf, len); | ||
| 229 | |||
| 230 | return ret; | ||
| 231 | } | ||
| 232 | |||
| 233 | /* the bit definition is aligned with snd_jack_types in jack.h */ | ||
| 234 | static const char * const jack_events_name[] = { | ||
| 235 | "HEADPHONE(0x0001)", "MICROPHONE(0x0002)", "LINEOUT(0x0004)", | ||
| 236 | "MECHANICAL(0x0008)", "VIDEOOUT(0x0010)", "LINEIN(0x0020)", | ||
| 237 | "", "", "", "BTN_5(0x0200)", "BTN_4(0x0400)", "BTN_3(0x0800)", | ||
| 238 | "BTN_2(0x1000)", "BTN_1(0x2000)", "BTN_0(0x4000)", "", | ||
| 239 | }; | ||
| 240 | |||
| 241 | /* the recommended buffer size is 256 */ | ||
| 242 | static int parse_mask_bits(unsigned int mask_bits, char *buf, size_t buf_size) | ||
| 243 | { | ||
| 244 | int i; | ||
| 245 | |||
| 246 | scnprintf(buf, buf_size, "0x%04x", mask_bits); | ||
| 247 | |||
| 248 | for (i = 0; i < ARRAY_SIZE(jack_events_name); i++) | ||
| 249 | if (mask_bits & (1 << i)) { | ||
| 250 | strlcat(buf, " ", buf_size); | ||
| 251 | strlcat(buf, jack_events_name[i], buf_size); | ||
| 252 | } | ||
| 253 | strlcat(buf, "\n", buf_size); | ||
| 254 | |||
| 255 | return strlen(buf); | ||
| 256 | } | ||
| 257 | |||
| 258 | static ssize_t jack_kctl_mask_bits_read(struct file *file, | ||
| 259 | char __user *to, size_t count, loff_t *ppos) | ||
| 260 | { | ||
| 261 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 262 | char buf[256]; | ||
| 263 | int len, ret; | ||
| 264 | |||
| 265 | len = parse_mask_bits(jack_kctl->mask_bits, buf, sizeof(buf)); | ||
| 266 | ret = simple_read_from_buffer(to, count, ppos, buf, len); | ||
| 267 | |||
| 268 | return ret; | ||
| 269 | } | ||
| 270 | |||
| 271 | static ssize_t jack_kctl_status_read(struct file *file, | ||
| 272 | char __user *to, size_t count, loff_t *ppos) | ||
| 273 | { | ||
| 274 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 275 | char buf[16]; | ||
| 276 | int len, ret; | ||
| 277 | |||
| 278 | len = scnprintf(buf, sizeof(buf), "%s\n", jack_kctl->kctl->private_value ? | ||
| 279 | "Plugged" : "Unplugged"); | ||
| 280 | ret = simple_read_from_buffer(to, count, ppos, buf, len); | ||
| 281 | |||
| 282 | return ret; | ||
| 283 | } | ||
| 284 | |||
| 285 | #ifdef CONFIG_SND_JACK_INPUT_DEV | ||
| 286 | static ssize_t jack_type_read(struct file *file, | ||
| 287 | char __user *to, size_t count, loff_t *ppos) | ||
| 288 | { | ||
| 289 | struct snd_jack_kctl *jack_kctl = file->private_data; | ||
| 290 | char buf[256]; | ||
| 291 | int len, ret; | ||
| 292 | |||
| 293 | len = parse_mask_bits(jack_kctl->jack->type, buf, sizeof(buf)); | ||
| 294 | ret = simple_read_from_buffer(to, count, ppos, buf, len); | ||
| 295 | |||
| 296 | return ret; | ||
| 297 | } | ||
| 298 | |||
| 299 | static const struct file_operations jack_type_fops = { | ||
| 300 | .open = simple_open, | ||
| 301 | .read = jack_type_read, | ||
| 302 | .llseek = default_llseek, | ||
| 303 | }; | ||
| 304 | #endif | ||
| 305 | |||
| 306 | static const struct file_operations sw_inject_enable_fops = { | ||
| 307 | .open = simple_open, | ||
| 308 | .read = sw_inject_enable_read, | ||
| 309 | .write = sw_inject_enable_write, | ||
| 310 | .llseek = default_llseek, | ||
| 311 | }; | ||
| 312 | |||
| 313 | static const struct file_operations jackin_inject_fops = { | ||
| 314 | .open = simple_open, | ||
| 315 | .write = jackin_inject_write, | ||
| 316 | .llseek = default_llseek, | ||
| 317 | }; | ||
| 318 | |||
| 319 | static const struct file_operations jack_kctl_id_fops = { | ||
| 320 | .open = simple_open, | ||
| 321 | .read = jack_kctl_id_read, | ||
| 322 | .llseek = default_llseek, | ||
| 323 | }; | ||
| 324 | |||
| 325 | static const struct file_operations jack_kctl_mask_bits_fops = { | ||
| 326 | .open = simple_open, | ||
| 327 | .read = jack_kctl_mask_bits_read, | ||
| 328 | .llseek = default_llseek, | ||
| 329 | }; | ||
| 330 | |||
| 331 | static const struct file_operations jack_kctl_status_fops = { | ||
| 332 | .open = simple_open, | ||
| 333 | .read = jack_kctl_status_read, | ||
| 334 | .llseek = default_llseek, | ||
| 335 | }; | ||
| 336 | |||
| 337 | static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, | ||
| 338 | struct snd_jack_kctl *jack_kctl) | ||
| 339 | { | ||
| 340 | char *tname; | ||
| 341 | int i; | ||
| 342 | |||
| 343 | /* Don't create injection interface for Phantom jacks */ | ||
| 344 | if (strstr(jack_kctl->kctl->id.name, "Phantom")) | ||
| 345 | return 0; | ||
| 346 | |||
| 347 | tname = kstrdup(jack_kctl->kctl->id.name, GFP_KERNEL); | ||
| 348 | if (!tname) | ||
| 349 | return -ENOMEM; | ||
| 350 | |||
| 351 | /* replace the chars which are not suitable for folder's name with _ */ | ||
| 352 | for (i = 0; tname[i]; i++) | ||
| 353 | if (!isalnum(tname[i])) | ||
| 354 | tname[i] = '_'; | ||
| 355 | |||
| 356 | jack_kctl->jack_debugfs_root = debugfs_create_dir(tname, jack->card->debugfs_root); | ||
| 357 | kfree(tname); | ||
| 358 | |||
| 359 | debugfs_create_file("sw_inject_enable", 0644, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 360 | &sw_inject_enable_fops); | ||
| 361 | |||
| 362 | debugfs_create_file("jackin_inject", 0200, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 363 | &jackin_inject_fops); | ||
| 364 | |||
| 365 | debugfs_create_file("kctl_id", 0444, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 366 | &jack_kctl_id_fops); | ||
| 367 | |||
| 368 | debugfs_create_file("mask_bits", 0444, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 369 | &jack_kctl_mask_bits_fops); | ||
| 370 | |||
| 371 | debugfs_create_file("status", 0444, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 372 | &jack_kctl_status_fops); | ||
| 373 | |||
| 374 | #ifdef CONFIG_SND_JACK_INPUT_DEV | ||
| 375 | debugfs_create_file("type", 0444, jack_kctl->jack_debugfs_root, jack_kctl, | ||
| 376 | &jack_type_fops); | ||
| 377 | #endif | ||
| 378 | return 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) | ||
| 382 | { | ||
| 383 | debugfs_remove(jack_kctl->jack_debugfs_root); | ||
| 384 | jack_kctl->jack_debugfs_root = NULL; | ||
| 385 | } | ||
| 386 | #else /* CONFIG_SND_JACK_INJECTION_DEBUG */ | ||
| 387 | static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack, | ||
| 388 | struct snd_jack_kctl *jack_kctl) | ||
| 389 | { | ||
| 390 | return 0; | ||
| 391 | } | ||
| 392 | |||
| 393 | static void snd_jack_debugfs_clear_inject_node(struct snd_jack_kctl *jack_kctl) | ||
| 394 | { | ||
| 395 | } | ||
| 396 | #endif /* CONFIG_SND_JACK_INJECTION_DEBUG */ | ||
| 397 | |||
| 112 | static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) | 398 | static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) |
| 113 | { | 399 | { |
| 114 | struct snd_jack_kctl *jack_kctl; | 400 | struct snd_jack_kctl *jack_kctl; |
| 115 | 401 | ||
| 116 | jack_kctl = kctl->private_data; | 402 | jack_kctl = kctl->private_data; |
| 117 | if (jack_kctl) { | 403 | if (jack_kctl) { |
| 404 | snd_jack_debugfs_clear_inject_node(jack_kctl); | ||
| 118 | list_del(&jack_kctl->list); | 405 | list_del(&jack_kctl->list); |
| 119 | kfree(jack_kctl); | 406 | kfree(jack_kctl); |
| 120 | } | 407 | } |
| @@ -122,7 +409,9 @@ static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) · 1 unmodified line | |||
| 122 | 409 | ||
| 123 | static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl) | 410 | static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl) |
| 124 | { | 411 | { |
| 412 | jack_kctl->jack = jack; | ||
| 125 | list_add_tail(&jack_kctl->list, &jack->kctl_list); | 413 | list_add_tail(&jack_kctl->list, &jack->kctl_list); |
| 414 | snd_jack_debugfs_add_inject_node(jack, jack_kctl); | ||
| 126 | } | 415 | } |
| 127 | 416 | ||
| 128 | static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask) | 417 | static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask) |
| @@ -340,6 +629,7 @@ EXPORT_SYMBOL(snd_jack_set_key); · 211 unmodified lines | |||
| 340 | void snd_jack_report(struct snd_jack *jack, int status) | 629 | void snd_jack_report(struct snd_jack *jack, int status) |
| 341 | { | 630 | { |
| 342 | struct snd_jack_kctl *jack_kctl; | 631 | struct snd_jack_kctl *jack_kctl; |
| 632 | unsigned int mask_bits = 0; | ||
| 343 | #ifdef CONFIG_SND_JACK_INPUT_DEV | 633 | #ifdef CONFIG_SND_JACK_INPUT_DEV |
| 344 | int i; | 634 | int i; |
| 345 | #endif | 635 | #endif |
| @@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status) · 1 unmodified line | |||
| 347 | if (!jack) | 637 | if (!jack) |
| 348 | return; | 638 | return; |
| 349 | 639 | ||
| 640 | jack->hw_status_cache = status; | ||
| 641 | |||
| 350 | list_for_each_entry(jack_kctl, &jack->kctl_list, list) | 642 | list_for_each_entry(jack_kctl, &jack->kctl_list, list) |
| 351 | snd_kctl_jack_report(jack->card, jack_kctl->kctl, | 643 | if (jack_kctl->sw_inject_enable) |
| 352 | status & jack_kctl->mask_bits); | 644 | mask_bits |= jack_kctl->mask_bits; |
| 645 | else | ||
| 646 | snd_kctl_jack_report(jack->card, jack_kctl->kctl, | ||
| 647 | status & jack_kctl->mask_bits); | ||
| 353 | 648 | ||
| 354 | #ifdef CONFIG_SND_JACK_INPUT_DEV | 649 | #ifdef CONFIG_SND_JACK_INPUT_DEV |
| 355 | if (!jack->input_dev) | 650 | if (!jack->input_dev) |
| 356 | return; | 651 | return; |
| 357 | 652 | ||
| 358 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { | 653 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { |
| 359 | int testbit = SND_JACK_BTN_0 >> i; | 654 | int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits); |
| 360 | 655 | ||
| 361 | if (jack->type & testbit) | 656 | if (jack->type & testbit) |
| 362 | input_report_key(jack->input_dev, jack->key[i], | 657 | input_report_key(jack->input_dev, jack->key[i], |
| @@ -364,7 +659,8 @@ void snd_jack_report(struct snd_jack *jack, int status) · 1 unmodified line | |||
| 364 | } | 659 | } |
| 365 | 660 | ||
| 366 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { | 661 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { |
| 367 | int testbit = 1 << i; | 662 | int testbit = ((1 << i) & ~mask_bits); |
| 663 | |||
| 368 | if (jack->type & testbit) | 664 | if (jack->type & testbit) |
| 369 | input_report_switch(jack->input_dev, | 665 | input_report_switch(jack->input_dev, |
| 370 | jack_switch_types[i], | 666 | jack_switch_types[i], |
| @@ -87,8 +87,8 @@ static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer, · 86 unmodified lines | |||
| 87 | struct mixer_info info; | 87 | struct mixer_info info; |
| 88 | 88 | ||
| 89 | memset(&info, 0, sizeof(info)); | 89 | memset(&info, 0, sizeof(info)); |
| 90 | strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); | 90 | strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); |
| 91 | strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); | 91 | strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); |
| 92 | info.modify_counter = card->mixer_oss_change_count; | 92 | info.modify_counter = card->mixer_oss_change_count; |
| 93 | if (copy_to_user(_info, &info, sizeof(info))) | 93 | if (copy_to_user(_info, &info, sizeof(info))) |
| 94 | return -EFAULT; | 94 | return -EFAULT; |
| @@ -103,8 +103,8 @@ static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer, · 8 unmodified lines | |||
| 103 | _old_mixer_info info; | 103 | _old_mixer_info info; |
| 104 | 104 | ||
| 105 | memset(&info, 0, sizeof(info)); | 105 | memset(&info, 0, sizeof(info)); |
| 106 | strlcpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); | 106 | strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); |
| 107 | strlcpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); | 107 | strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); |
| 108 | if (copy_to_user(_info, &info, sizeof(info))) | 108 | if (copy_to_user(_info, &info, sizeof(info))) |
| 109 | return -EFAULT; | 109 | return -EFAULT; |
| 110 | return 0; | 110 | return 0; |
| @@ -418,7 +418,7 @@ static long snd_mixer_oss_conv(long val, long omin, long omax, long nmin, long n · 307 unmodified lines | |||
| 418 | 418 | ||
| 419 | if (orange == 0) | 419 | if (orange == 0) |
| 420 | return 0; | 420 | return 0; |
| 421 | return ((nrange * (val - omin)) + (orange / 2)) / orange + nmin; | 421 | return DIV_ROUND_CLOSEST(nrange * (val - omin), orange) + nmin; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | /* convert from alsa native to oss values (0-100) */ | 424 | /* convert from alsa native to oss values (0-100) */ |
| @@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c · 74 unmodified lines | |||
| 499 | 499 | ||
| 500 | memset(&id, 0, sizeof(id)); | 500 | memset(&id, 0, sizeof(id)); |
| 501 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 501 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 502 | strlcpy(id.name, name, sizeof(id.name)); | 502 | strscpy(id.name, name, sizeof(id.name)); |
| 503 | id.index = index; | 503 | id.index = index; |
| 504 | return snd_ctl_find_id(card, &id); | 504 | return snd_ctl_find_id(card, &id); |
| 505 | } | 505 | } |
| @@ -1355,7 +1355,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) · 849 unmodified lines | |||
| 1355 | mixer->oss_dev_alloc = 1; | 1355 | mixer->oss_dev_alloc = 1; |
| 1356 | mixer->card = card; | 1356 | mixer->card = card; |
| 1357 | if (*card->mixername) | 1357 | if (*card->mixername) |
| 1358 | strlcpy(mixer->name, card->mixername, sizeof(mixer->name)); | 1358 | strscpy(mixer->name, card->mixername, sizeof(mixer->name)); |
| 1359 | else | 1359 | else |
| 1360 | snprintf(mixer->name, sizeof(mixer->name), | 1360 | snprintf(mixer->name, sizeof(mixer->name), |
| 1361 | "mixer%i", card->number); | 1361 | "mixer%i", card->number); |
| @@ -193,7 +193,7 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_ · 192 unmodified lines | |||
| 193 | if (plugin->src_format.rate < plugin->dst_format.rate) { | 193 | if (plugin->src_format.rate < plugin->dst_format.rate) { |
| 194 | res = (((frames * data->pitch) + (BITS/2)) >> SHIFT); | 194 | res = (((frames * data->pitch) + (BITS/2)) >> SHIFT); |
| 195 | } else { | 195 | } else { |
| 196 | res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch); | 196 | res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch); |
| 197 | } | 197 | } |
| 198 | if (data->old_src_frames > 0) { | 198 | if (data->old_src_frames > 0) { |
| 199 | snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames; | 199 | snd_pcm_sframes_t frames1 = frames, res1 = data->old_dst_frames; |
| @@ -224,7 +224,7 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_ · 24 unmodified lines | |||
| 224 | return 0; | 224 | return 0; |
| 225 | data = (struct rate_priv *)plugin->extra_data; | 225 | data = (struct rate_priv *)plugin->extra_data; |
| 226 | if (plugin->src_format.rate < plugin->dst_format.rate) { | 226 | if (plugin->src_format.rate < plugin->dst_format.rate) { |
| 227 | res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch); | 227 | res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch); |
| 228 | } else { | 228 | } else { |
| 229 | res = (((frames * data->pitch) + (BITS/2)) >> SHIFT); | 229 | res = (((frames * data->pitch) + (BITS/2)) >> SHIFT); |
| 230 | } | 230 | } |
| @@ -729,7 +729,7 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, · 728 unmodified lines | |||
| 729 | init_waitqueue_head(&pcm->open_wait); | 729 | init_waitqueue_head(&pcm->open_wait); |
| 730 | INIT_LIST_HEAD(&pcm->list); | 730 | INIT_LIST_HEAD(&pcm->list); |
| 731 | if (id) | 731 | if (id) |
| 732 | strlcpy(pcm->id, id, sizeof(pcm->id)); | 732 | strscpy(pcm->id, id, sizeof(pcm->id)); |
| 733 | 733 | ||
| 734 | err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 734 | err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
| 735 | playback_count); | 735 | playback_count); |
| @@ -1095,22 +1095,23 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) · 359 unmodified lines | |||
| 1095 | mutex_lock(&pcm->open_mutex); | 1095 | mutex_lock(&pcm->open_mutex); |
| 1096 | wake_up(&pcm->open_wait); | 1096 | wake_up(&pcm->open_wait); |
| 1097 | list_del_init(&pcm->list); | 1097 | list_del_init(&pcm->list); |
| 1098 | for (cidx = 0; cidx < 2; cidx++) { | 1098 | |
| 1099 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { | 1099 | for_each_pcm_substream(pcm, cidx, substream) { |
| 1100 | snd_pcm_stream_lock_irq(substream); | 1100 | snd_pcm_stream_lock_irq(substream); |
| 1101 | if (substream->runtime) { | 1101 | if (substream->runtime) { |
| 1102 | if (snd_pcm_running(substream)) | 1102 | if (snd_pcm_running(substream)) |
| 1103 | snd_pcm_stop(substream, | 1103 | snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); |
| 1104 | SNDRV_PCM_STATE_DISCONNECTED); | 1104 | /* to be sure, set the state unconditionally */ |
| 1105 | /* to be sure, set the state unconditionally */ | 1105 | substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; |
| 1106 | substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; | 1106 | wake_up(&substream->runtime->sleep); |
| 1107 | wake_up(&substream->runtime->sleep); | 1107 | wake_up(&substream->runtime->tsleep); |
| 1108 | wake_up(&substream->runtime->tsleep); | ||
| 1109 | } | ||
| 1110 | snd_pcm_stream_unlock_irq(substream); | ||
| 1111 | } | 1108 | } |
| 1109 | snd_pcm_stream_unlock_irq(substream); | ||
| 1112 | } | 1110 | } |
| 1113 | 1111 | ||
| 1112 | for_each_pcm_substream(pcm, cidx, substream) | ||
| 1113 | snd_pcm_sync_stop(substream, false); | ||
| 1114 | |||
| 1114 | pcm_call_notify(pcm, n_disconnect); | 1115 | pcm_call_notify(pcm, n_disconnect); |
| 1115 | for (cidx = 0; cidx < 2; cidx++) { | 1116 | for (cidx = 0; cidx < 2; cidx++) { |
| 1116 | snd_unregister_device(&pcm->streams[cidx].dev); | 1117 | snd_unregister_device(&pcm->streams[cidx].dev); |
| @@ -125,6 +125,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data( · 124 unmodified lines | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | slave_config->slave_id = dma_data->slave_id; | 127 | slave_config->slave_id = dma_data->slave_id; |
| 128 | slave_config->peripheral_config = dma_data->peripheral_config; | ||
| 129 | slave_config->peripheral_size = dma_data->peripheral_size; | ||
| 128 | } | 130 | } |
| 129 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); | 131 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); |
| 130 | 132 | ||
| @@ -63,6 +63,7 @@ static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {} · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | void __snd_pcm_xrun(struct snd_pcm_substream *substream); | 64 | void __snd_pcm_xrun(struct snd_pcm_substream *substream); |
| 65 | void snd_pcm_group_init(struct snd_pcm_group *group); | 65 | void snd_pcm_group_init(struct snd_pcm_group *group); |
| 66 | void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq); | ||
| 66 | 67 | ||
| 67 | #ifdef CONFIG_SND_DMA_SGBUF | 68 | #ifdef CONFIG_SND_DMA_SGBUF |
| 68 | struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, | 69 | struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, |
| @@ -71,4 +72,10 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 71 | 72 | ||
| 72 | #define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime) | 73 | #define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime) |
| 73 | 74 | ||
| 75 | /* loop over all PCM substreams */ | ||
| 76 | #define for_each_pcm_substream(pcm, str, subs) \ | ||
| 77 | for ((str) = 0; (str) < 2; (str)++) \ | ||
| 78 | for ((subs) = (pcm)->streams[str].substream; (subs); \ | ||
| 79 | (subs) = (subs)->next) | ||
| 80 | |||
| 74 | #endif /* __SOUND_CORE_PCM_LOCAL_H */ | 81 | #endif /* __SOUND_CORE_PCM_LOCAL_H */ |
| @@ -111,9 +111,8 @@ void snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) · 110 unmodified lines | |||
| 111 | struct snd_pcm_substream *substream; | 111 | struct snd_pcm_substream *substream; |
| 112 | int stream; | 112 | int stream; |
| 113 | 113 | ||
| 114 | for (stream = 0; stream < 2; stream++) | 114 | for_each_pcm_substream(pcm, stream, substream) |
| 115 | for (substream = pcm->streams[stream].substream; substream; substream = substream->next) | 115 | snd_pcm_lib_preallocate_free(substream); |
| 116 | snd_pcm_lib_preallocate_free(substream); | ||
| 117 | } | 116 | } |
| 118 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); | 117 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); |
| 119 | 118 | ||
| @@ -246,11 +245,8 @@ static void preallocate_pages_for_all(struct snd_pcm *pcm, int type, · 126 unmodified lines | |||
| 246 | struct snd_pcm_substream *substream; | 245 | struct snd_pcm_substream *substream; |
| 247 | int stream; | 246 | int stream; |
| 248 | 247 | ||
| 249 | for (stream = 0; stream < 2; stream++) | 248 | for_each_pcm_substream(pcm, stream, substream) |
| 250 | for (substream = pcm->streams[stream].substream; substream; | 249 | preallocate_pages(substream, type, data, size, max, managed); |
| 251 | substream = substream->next) | ||
| 252 | preallocate_pages(substream, type, data, size, max, | ||
| 253 | managed); | ||
| 254 | } | 250 | } |
| 255 | 251 | ||
| 256 | /** | 252 | /** |
| @@ -209,13 +209,13 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) · 208 unmodified lines | |||
| 209 | info->device = pcm->device; | 209 | info->device = pcm->device; |
| 210 | info->stream = substream->stream; | 210 | info->stream = substream->stream; |
| 211 | info->subdevice = substream->number; | 211 | info->subdevice = substream->number; |
| 212 | strlcpy(info->id, pcm->id, sizeof(info->id)); | 212 | strscpy(info->id, pcm->id, sizeof(info->id)); |
| 213 | strlcpy(info->name, pcm->name, sizeof(info->name)); | 213 | strscpy(info->name, pcm->name, sizeof(info->name)); |
| 214 | info->dev_class = pcm->dev_class; | 214 | info->dev_class = pcm->dev_class; |
| 215 | info->dev_subclass = pcm->dev_subclass; | 215 | info->dev_subclass = pcm->dev_subclass; |
| 216 | info->subdevices_count = pstr->substream_count; | 216 | info->subdevices_count = pstr->substream_count; |
| 217 | info->subdevices_avail = pstr->substream_count - pstr->substream_opened; | 217 | info->subdevices_avail = pstr->substream_count - pstr->substream_opened; |
| 218 | strlcpy(info->subname, substream->name, sizeof(info->subname)); | 218 | strscpy(info->subname, substream->name, sizeof(info->subname)); |
| 219 | 219 | ||
| 220 | return 0; | 220 | return 0; |
| 221 | } | 221 | } |
| @@ -583,13 +583,13 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream, · 361 unmodified lines | |||
| 583 | #endif | 583 | #endif |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | static void snd_pcm_sync_stop(struct snd_pcm_substream *substream) | 586 | void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq) |
| 587 | { | 587 | { |
| 588 | if (substream->runtime->stop_operating) { | 588 | if (substream->runtime && substream->runtime->stop_operating) { |
| 589 | substream->runtime->stop_operating = false; | 589 | substream->runtime->stop_operating = false; |
| 590 | if (substream->ops->sync_stop) | 590 | if (substream->ops && substream->ops->sync_stop) |
| 591 | substream->ops->sync_stop(substream); | 591 | substream->ops->sync_stop(substream); |
| 592 | else if (substream->pcm->card->sync_irq > 0) | 592 | else if (sync_irq && substream->pcm->card->sync_irq > 0) |
| 593 | synchronize_irq(substream->pcm->card->sync_irq); | 593 | synchronize_irq(substream->pcm->card->sync_irq); |
| 594 | } | 594 | } |
| 595 | } | 595 | } |
| @@ -686,7 +686,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, · 90 unmodified lines | |||
| 686 | if (atomic_read(&substream->mmap_count)) | 686 | if (atomic_read(&substream->mmap_count)) |
| 687 | return -EBADFD; | 687 | return -EBADFD; |
| 688 | 688 | ||
| 689 | snd_pcm_sync_stop(substream); | 689 | snd_pcm_sync_stop(substream, true); |
| 690 | 690 | ||
| 691 | params->rmask = ~0U; | 691 | params->rmask = ~0U; |
| 692 | err = snd_pcm_hw_refine(substream, params); | 692 | err = snd_pcm_hw_refine(substream, params); |
| @@ -809,7 +809,7 @@ static int do_hw_free(struct snd_pcm_substream *substream) · 116 unmodified lines | |||
| 809 | { | 809 | { |
| 810 | int result = 0; | 810 | int result = 0; |
| 811 | 811 | ||
| 812 | snd_pcm_sync_stop(substream); | 812 | snd_pcm_sync_stop(substream, true); |
| 813 | if (substream->ops->hw_free) | 813 | if (substream->ops->hw_free) |
| 814 | result = substream->ops->hw_free(substream); | 814 | result = substream->ops->hw_free(substream); |
| 815 | if (substream->managed_buffer_alloc) | 815 | if (substream->managed_buffer_alloc) |
| @@ -1421,8 +1421,10 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream, · 605 unmodified lines | |||
| 1421 | snd_pcm_state_t state) | 1421 | snd_pcm_state_t state) |
| 1422 | { | 1422 | { |
| 1423 | if (substream->runtime->trigger_master == substream && | 1423 | if (substream->runtime->trigger_master == substream && |
| 1424 | snd_pcm_running(substream)) | 1424 | snd_pcm_running(substream)) { |
| 1425 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); | 1425 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); |
| 1426 | substream->runtime->stop_operating = true; | ||
| 1427 | } | ||
| 1426 | return 0; /* unconditonally stop all substreams */ | 1428 | return 0; /* unconditonally stop all substreams */ |
| 1427 | } | 1429 | } |
| 1428 | 1430 | ||
| @@ -1435,7 +1437,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, · 6 unmodified lines | |||
| 1435 | runtime->status->state = state; | 1437 | runtime->status->state = state; |
| 1436 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP); | 1438 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP); |
| 1437 | } | 1439 | } |
| 1438 | runtime->stop_operating = true; | ||
| 1439 | wake_up(&runtime->sleep); | 1440 | wake_up(&runtime->sleep); |
| 1440 | wake_up(&runtime->tsleep); | 1441 | wake_up(&runtime->tsleep); |
| 1441 | } | 1442 | } |
| @@ -1615,6 +1616,7 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, · 173 unmodified lines | |||
| 1615 | if (! snd_pcm_running(substream)) | 1616 | if (! snd_pcm_running(substream)) |
| 1616 | return 0; | 1617 | return 0; |
| 1617 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); | 1618 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); |
| 1619 | runtime->stop_operating = true; | ||
| 1618 | return 0; /* suspend unconditionally */ | 1620 | return 0; /* suspend unconditionally */ |
| 1619 | } | 1621 | } |
| 1620 | 1622 | ||
| @@ -1672,25 +1674,26 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) · 51 unmodified lines | |||
| 1672 | if (! pcm) | 1674 | if (! pcm) |
| 1673 | return 0; | 1675 | return 0; |
| 1674 | 1676 | ||
| 1675 | for (stream = 0; stream < 2; stream++) { | 1677 | for_each_pcm_substream(pcm, stream, substream) { |
| 1676 | for (substream = pcm->streams[stream].substream; | 1678 | /* FIXME: the open/close code should lock this as well */ |
| 1677 | substream; substream = substream->next) { | 1679 | if (!substream->runtime) |
| 1678 | /* FIXME: the open/close code should lock this as well */ | 1680 | continue; |
| 1679 | if (substream->runtime == NULL) | ||
| 1680 | continue; | ||
| 1681 | 1681 | ||
| 1682 | /* | 1682 | /* |
| 1683 | * Skip BE dai link PCM's that are internal and may | 1683 | * Skip BE dai link PCM's that are internal and may |
| 1684 | * not have their substream ops set. | 1684 | * not have their substream ops set. |
| 1685 | */ | 1685 | */ |
| 1686 | if (!substream->ops) | 1686 | if (!substream->ops) |
| 1687 | continue; | 1687 | continue; |
| 1688 | 1688 | ||
| 1689 | err = snd_pcm_suspend(substream); | 1689 | err = snd_pcm_suspend(substream); |
| 1690 | if (err < 0 && err != -EBUSY) | 1690 | if (err < 0 && err != -EBUSY) |
| 1691 | return err; | 1691 | return err; |
| 1692 | } | ||
| 1693 | } | 1692 | } |
| 1693 | |||
| 1694 | for_each_pcm_substream(pcm, stream, substream) | ||
| 1695 | snd_pcm_sync_stop(substream, false); | ||
| 1696 | |||
| 1694 | return 0; | 1697 | return 0; |
| 1695 | } | 1698 | } |
| 1696 | EXPORT_SYMBOL(snd_pcm_suspend_all); | 1699 | EXPORT_SYMBOL(snd_pcm_suspend_all); |
| @@ -1736,7 +1739,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, · 39 unmodified lines | |||
| 1736 | snd_pcm_trigger_tstamp(substream); | 1739 | snd_pcm_trigger_tstamp(substream); |
| 1737 | runtime->status->state = runtime->status->suspended_state; | 1740 | runtime->status->state = runtime->status->suspended_state; |
| 1738 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); | 1741 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); |
| 1739 | snd_pcm_sync_stop(substream); | ||
| 1740 | } | 1742 | } |
| 1741 | 1743 | ||
| 1742 | static const struct action_ops snd_pcm_action_resume = { | 1744 | static const struct action_ops snd_pcm_action_resume = { |
| @@ -1866,7 +1868,7 @@ static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, · 123 unmodified lines | |||
| 1866 | snd_pcm_state_t state) | 1868 | snd_pcm_state_t state) |
| 1867 | { | 1869 | { |
| 1868 | int err; | 1870 | int err; |
| 1869 | snd_pcm_sync_stop(substream); | 1871 | snd_pcm_sync_stop(substream, true); |
| 1870 | err = substream->ops->prepare(substream); | 1872 | err = substream->ops->prepare(substream); |
| 1871 | if (err < 0) | 1873 | if (err < 0) |
| 1872 | return err; | 1874 | return err; |
| @@ -1686,7 +1686,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, · 1685 unmodified lines | |||
| 1686 | INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams); | 1686 | INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams); |
| 1687 | 1687 | ||
| 1688 | if (id != NULL) | 1688 | if (id != NULL) |
| 1689 | strlcpy(rmidi->id, id, sizeof(rmidi->id)); | 1689 | strscpy(rmidi->id, id, sizeof(rmidi->id)); |
| 1690 | 1690 | ||
| 1691 | snd_device_initialize(&rmidi->dev, card); | 1691 | snd_device_initialize(&rmidi->dev, card); |
| 1692 | rmidi->dev.release = release_rawmidi_device; | 1692 | rmidi->dev.release = release_rawmidi_device; |
| @@ -173,7 +173,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) · 172 unmodified lines | |||
| 173 | snd_use_lock_init(&mdev->use_lock); | 173 | snd_use_lock_init(&mdev->use_lock); |
| 174 | 174 | ||
| 175 | /* copy and truncate the name of synth device */ | 175 | /* copy and truncate the name of synth device */ |
| 176 | strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); | 176 | strscpy(mdev->name, pinfo->name, sizeof(mdev->name)); |
| 177 | 177 | ||
| 178 | /* create MIDI coder */ | 178 | /* create MIDI coder */ |
| 179 | if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { | 179 | if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { |
| @@ -647,7 +647,7 @@ snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info · 467 unmodified lines | |||
| 647 | inf->device = dev; | 647 | inf->device = dev; |
| 648 | inf->dev_type = 0; /* FIXME: ?? */ | 648 | inf->dev_type = 0; /* FIXME: ?? */ |
| 649 | inf->capabilities = 0; /* FIXME: ?? */ | 649 | inf->capabilities = 0; /* FIXME: ?? */ |
| 650 | strlcpy(inf->name, mdev->name, sizeof(inf->name)); | 650 | strscpy(inf->name, mdev->name, sizeof(inf->name)); |
| 651 | snd_use_lock_free(&mdev->use_lock); | 651 | snd_use_lock_free(&mdev->use_lock); |
| 652 | return 0; | 652 | return 0; |
| 653 | } | 653 | } |
| @@ -107,7 +107,7 @@ snd_seq_oss_synth_probe(struct device *_dev) · 106 unmodified lines | |||
| 107 | snd_use_lock_init(&rec->use_lock); | 107 | snd_use_lock_init(&rec->use_lock); |
| 108 | 108 | ||
| 109 | /* copy and truncate the name of synth device */ | 109 | /* copy and truncate the name of synth device */ |
| 110 | strlcpy(rec->name, dev->name, sizeof(rec->name)); | 110 | strscpy(rec->name, dev->name, sizeof(rec->name)); |
| 111 | 111 | ||
| 112 | /* registration */ | 112 | /* registration */ |
| 113 | spin_lock_irqsave(®ister_lock, flags); | 113 | spin_lock_irqsave(®ister_lock, flags); |
| @@ -617,7 +617,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in · 503 unmodified lines | |||
| 617 | inf->synth_subtype = 0; | 617 | inf->synth_subtype = 0; |
| 618 | inf->nr_voices = 16; | 618 | inf->nr_voices = 16; |
| 619 | inf->device = dev; | 619 | inf->device = dev; |
| 620 | strlcpy(inf->name, minf.name, sizeof(inf->name)); | 620 | strscpy(inf->name, minf.name, sizeof(inf->name)); |
| 621 | } else { | 621 | } else { |
| 622 | if ((rec = get_synthdev(dp, dev)) == NULL) | 622 | if ((rec = get_synthdev(dp, dev)) == NULL) |
| 623 | return -ENXIO; | 623 | return -ENXIO; |
| @@ -625,7 +625,7 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in · 1 unmodified line | |||
| 625 | inf->synth_subtype = rec->synth_subtype; | 625 | inf->synth_subtype = rec->synth_subtype; |
| 626 | inf->nr_voices = rec->nr_voices; | 626 | inf->nr_voices = rec->nr_voices; |
| 627 | inf->device = dev; | 627 | inf->device = dev; |
| 628 | strlcpy(inf->name, rec->name, sizeof(inf->name)); | 628 | strscpy(inf->name, rec->name, sizeof(inf->name)); |
| 629 | snd_use_lock_free(&rec->use_lock); | 629 | snd_use_lock_free(&rec->use_lock); |
| 630 | } | 630 | } |
| 631 | return 0; | 631 | return 0; |
| @@ -1584,7 +1584,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, · 1583 unmodified lines | |||
| 1584 | info->queue = q->queue; | 1584 | info->queue = q->queue; |
| 1585 | info->owner = q->owner; | 1585 | info->owner = q->owner; |
| 1586 | info->locked = q->locked; | 1586 | info->locked = q->locked; |
| 1587 | strlcpy(info->name, q->name, sizeof(info->name)); | 1587 | strscpy(info->name, q->name, sizeof(info->name)); |
| 1588 | queuefree(q); | 1588 | queuefree(q); |
| 1589 | 1589 | ||
| 1590 | return 0; | 1590 | return 0; |
| @@ -290,7 +290,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, · 289 unmodified lines | |||
| 290 | extlen = 0; | 290 | extlen = 0; |
| 291 | if (snd_seq_ev_is_variable(event)) { | 291 | if (snd_seq_ev_is_variable(event)) { |
| 292 | extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK; | 292 | extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK; |
| 293 | ncells = (extlen + sizeof(struct snd_seq_event) - 1) / sizeof(struct snd_seq_event); | 293 | ncells = DIV_ROUND_UP(extlen, sizeof(struct snd_seq_event)); |
| 294 | } | 294 | } |
| 295 | if (ncells >= pool->total_elements) | 295 | if (ncells >= pool->total_elements) |
| 296 | return -ENOMEM; | 296 | return -ENOMEM; |
| @@ -327,7 +327,7 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port, · 326 unmodified lines | |||
| 327 | 327 | ||
| 328 | /* set port name */ | 328 | /* set port name */ |
| 329 | if (info->name[0]) | 329 | if (info->name[0]) |
| 330 | strlcpy(port->name, info->name, sizeof(port->name)); | 330 | strscpy(port->name, info->name, sizeof(port->name)); |
| 331 | 331 | ||
| 332 | /* set capabilities */ | 332 | /* set capabilities */ |
| 333 | port->capability = info->capability; | 333 | port->capability = info->capability; |
| @@ -356,7 +356,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port, · 22 unmodified lines | |||
| 356 | return -EINVAL; | 356 | return -EINVAL; |
| 357 | 357 | ||
| 358 | /* get port name */ | 358 | /* get port name */ |
| 359 | strlcpy(info->name, port->name, sizeof(info->name)); | 359 | strscpy(info->name, port->name, sizeof(info->name)); |
| 360 | 360 | ||
| 361 | /* get capabilities */ | 361 | /* get capabilities */ |
| 362 | info->capability = port->capability; | 362 | info->capability = port->capability; |
| @@ -654,7 +654,7 @@ int snd_seq_event_port_attach(int client, · 291 unmodified lines | |||
| 654 | /* Set up the port */ | 654 | /* Set up the port */ |
| 655 | memset(&portinfo, 0, sizeof(portinfo)); | 655 | memset(&portinfo, 0, sizeof(portinfo)); |
| 656 | portinfo.addr.client = client; | 656 | portinfo.addr.client = client; |
| 657 | strlcpy(portinfo.name, portname ? portname : "Unnamed port", | 657 | strscpy(portinfo.name, portname ? portname : "Unnamed port", |
| 658 | sizeof(portinfo.name)); | 658 | sizeof(portinfo.name)); |
| 659 | 659 | ||
| 660 | portinfo.capability = cap; | 660 | portinfo.capability = cap; |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/time.h> | 9 | #include <linux/time.h> |
| 10 | #include <linux/device.h> | 10 | #include <linux/device.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/debugfs.h> | ||
| 12 | #include <sound/core.h> | 13 | #include <sound/core.h> |
| 13 | #include <sound/minors.h> | 14 | #include <sound/minors.h> |
| 14 | #include <sound/info.h> | 15 | #include <sound/info.h> |
| @@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); · 24 unmodified lines | |||
| 39 | int snd_ecards_limit; | 40 | int snd_ecards_limit; |
| 40 | EXPORT_SYMBOL(snd_ecards_limit); | 41 | EXPORT_SYMBOL(snd_ecards_limit); |
| 41 | 42 | ||
| 43 | #ifdef CONFIG_SND_DEBUG | ||
| 44 | struct dentry *sound_debugfs_root; | ||
| 45 | EXPORT_SYMBOL_GPL(sound_debugfs_root); | ||
| 46 | #endif | ||
| 47 | |||
| 42 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; | 48 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
| 43 | static DEFINE_MUTEX(sound_mutex); | 49 | static DEFINE_MUTEX(sound_mutex); |
| 44 | 50 | ||
| @@ -337,6 +343,8 @@ static const char *snd_device_type_name(int type) · 292 unmodified lines | |||
| 337 | return "sequencer"; | 343 | return "sequencer"; |
| 338 | case SNDRV_DEVICE_TYPE_TIMER: | 344 | case SNDRV_DEVICE_TYPE_TIMER: |
| 339 | return "timer"; | 345 | return "timer"; |
| 346 | case SNDRV_DEVICE_TYPE_COMPRESS: | ||
| 347 | return "compress"; | ||
| 340 | default: | 348 | default: |
| 341 | return "?"; | 349 | return "?"; |
| 342 | } | 350 | } |
| @@ -395,6 +403,10 @@ static int __init alsa_sound_init(void) · 52 unmodified lines | |||
| 395 | unregister_chrdev(major, "alsa"); | 403 | unregister_chrdev(major, "alsa"); |
| 396 | return -ENOMEM; | 404 | return -ENOMEM; |
| 397 | } | 405 | } |
| 406 | |||
| 407 | #ifdef CONFIG_SND_DEBUG | ||
| 408 | sound_debugfs_root = debugfs_create_dir("sound", NULL); | ||
| 409 | #endif | ||
| 398 | #ifndef MODULE | 410 | #ifndef MODULE |
| 399 | pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); | 411 | pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); |
| 400 | #endif | 412 | #endif |
| @@ -403,6 +415,9 @@ static int __init alsa_sound_init(void) · 2 unmodified lines | |||
| 403 | 415 | ||
| 404 | static void __exit alsa_sound_exit(void) | 416 | static void __exit alsa_sound_exit(void) |
| 405 | { | 417 | { |
| 418 | #ifdef CONFIG_SND_DEBUG | ||
| 419 | debugfs_remove(sound_debugfs_root); | ||
| 420 | #endif | ||
| 406 | snd_info_done(); | 421 | snd_info_done(); |
| 407 | unregister_chrdev(major, "alsa"); | 422 | unregister_chrdev(major, "alsa"); |
| 408 | } | 423 | } |
| @@ -959,7 +959,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, · 958 unmodified lines | |||
| 959 | timer->tmr_device = tid->device; | 959 | timer->tmr_device = tid->device; |
| 960 | timer->tmr_subdevice = tid->subdevice; | 960 | timer->tmr_subdevice = tid->subdevice; |
| 961 | if (id) | 961 | if (id) |
| 962 | strlcpy(timer->id, id, sizeof(timer->id)); | 962 | strscpy(timer->id, id, sizeof(timer->id)); |
| 963 | timer->sticks = 1; | 963 | timer->sticks = 1; |
| 964 | INIT_LIST_HEAD(&timer->device_list); | 964 | INIT_LIST_HEAD(&timer->device_list); |
| 965 | INIT_LIST_HEAD(&timer->open_list_head); | 965 | INIT_LIST_HEAD(&timer->open_list_head); |
| @@ -1659,8 +1659,8 @@ static int snd_timer_user_ginfo(struct file *file, · 693 unmodified lines | |||
| 1659 | ginfo->card = t->card ? t->card->number : -1; | 1659 | ginfo->card = t->card ? t->card->number : -1; |
| 1660 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) | 1660 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 1661 | ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; | 1661 | ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; |
| 1662 | strlcpy(ginfo->id, t->id, sizeof(ginfo->id)); | 1662 | strscpy(ginfo->id, t->id, sizeof(ginfo->id)); |
| 1663 | strlcpy(ginfo->name, t->name, sizeof(ginfo->name)); | 1663 | strscpy(ginfo->name, t->name, sizeof(ginfo->name)); |
| 1664 | ginfo->resolution = t->hw.resolution; | 1664 | ginfo->resolution = t->hw.resolution; |
| 1665 | if (t->hw.resolution_min > 0) { | 1665 | if (t->hw.resolution_min > 0) { |
| 1666 | ginfo->resolution_min = t->hw.resolution_min; | 1666 | ginfo->resolution_min = t->hw.resolution_min; |
| @@ -1814,8 +1814,8 @@ static int snd_timer_user_info(struct file *file, · 147 unmodified lines | |||
| 1814 | info->card = t->card ? t->card->number : -1; | 1814 | info->card = t->card ? t->card->number : -1; |
| 1815 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) | 1815 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 1816 | info->flags |= SNDRV_TIMER_FLG_SLAVE; | 1816 | info->flags |= SNDRV_TIMER_FLG_SLAVE; |
| 1817 | strlcpy(info->id, t->id, sizeof(info->id)); | 1817 | strscpy(info->id, t->id, sizeof(info->id)); |
| 1818 | strlcpy(info->name, t->name, sizeof(info->name)); | 1818 | strscpy(info->name, t->name, sizeof(info->name)); |
| 1819 | info->resolution = t->hw.resolution; | 1819 | info->resolution = t->hw.resolution; |
| 1820 | if (copy_to_user(_info, info, sizeof(*_info))) | 1820 | if (copy_to_user(_info, info, sizeof(*_info))) |
| 1821 | err = -EFAULT; | 1821 | err = -EFAULT; |
| @@ -61,8 +61,8 @@ static int snd_timer_user_info_compat(struct file *file, · 60 unmodified lines | |||
| 61 | info.card = t->card ? t->card->number : -1; | 61 | info.card = t->card ? t->card->number : -1; |
| 62 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) | 62 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 63 | info.flags |= SNDRV_TIMER_FLG_SLAVE; | 63 | info.flags |= SNDRV_TIMER_FLG_SLAVE; |
| 64 | strlcpy(info.id, t->id, sizeof(info.id)); | 64 | strscpy(info.id, t->id, sizeof(info.id)); |
| 65 | strlcpy(info.name, t->name, sizeof(info.name)); | 65 | strscpy(info.name, t->name, sizeof(info.name)); |
| 66 | info.resolution = t->hw.resolution; | 66 | info.resolution = t->hw.resolution; |
| 67 | if (copy_to_user(_info, &info, sizeof(*_info))) | 67 | if (copy_to_user(_info, &info, sizeof(*_info))) |
| 68 | return -EFAULT; | 68 | return -EFAULT; |
| @@ -219,7 +219,7 @@ static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm) · 218 unmodified lines | |||
| 219 | dpcm->period_update_pending = 1; | 219 | dpcm->period_update_pending = 1; |
| 220 | } | 220 | } |
| 221 | tick = dpcm->period_size_frac - dpcm->irq_pos; | 221 | tick = dpcm->period_size_frac - dpcm->irq_pos; |
| 222 | tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps; | 222 | tick = DIV_ROUND_UP(tick, dpcm->pcm_bps); |
| 223 | mod_timer(&dpcm->timer, jiffies + tick); | 223 | mod_timer(&dpcm->timer, jiffies + tick); |
| 224 | 224 | ||
| 225 | return 0; | 225 | return 0; |
| @@ -236,7 +236,7 @@ struct dummy_systimer_pcm { · 235 unmodified lines | |||
| 236 | static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) | 236 | static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) |
| 237 | { | 237 | { |
| 238 | mod_timer(&dpcm->timer, jiffies + | 238 | mod_timer(&dpcm->timer, jiffies + |
| 239 | (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate); | 239 | DIV_ROUND_UP(dpcm->frac_period_rest, dpcm->rate)); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm) | 242 | static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm) |
| @@ -97,7 +97,7 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name) · 96 unmodified lines | |||
| 97 | return; | 97 | return; |
| 98 | 98 | ||
| 99 | opl3->oss_seq_dev = dev; | 99 | opl3->oss_seq_dev = dev; |
| 100 | strlcpy(dev->name, name, sizeof(dev->name)); | 100 | strscpy(dev->name, name, sizeof(dev->name)); |
| 101 | arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); | 101 | arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); |
| 102 | arg->type = SYNTH_TYPE_FM; | 102 | arg->type = SYNTH_TYPE_FM; |
| 103 | if (opl3->hardware < OPL3_HW_OPL3) { | 103 | if (opl3->hardware < OPL3_HW_OPL3) { |
| @@ -290,7 +290,7 @@ int snd_opl3_load_patch(struct snd_opl3 *opl3, · 289 unmodified lines | |||
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | if (name) | 292 | if (name) |
| 293 | strlcpy(patch->name, name, sizeof(patch->name)); | 293 | strscpy(patch->name, name, sizeof(patch->name)); |
| 294 | 294 | ||
| 295 | return 0; | 295 | return 0; |
| 296 | } | 296 | } |
| @@ -1154,8 +1154,7 @@ static int vx_init_audio_io(struct vx_core *chip) · 1153 unmodified lines | |||
| 1154 | chip->ibl.size = 0; | 1154 | chip->ibl.size = 0; |
| 1155 | vx_set_ibl(chip, &chip->ibl); /* query the info */ | 1155 | vx_set_ibl(chip, &chip->ibl); /* query the info */ |
| 1156 | if (preferred > 0) { | 1156 | if (preferred > 0) { |
| 1157 | chip->ibl.size = ((preferred + chip->ibl.granularity - 1) / | 1157 | chip->ibl.size = roundup(preferred, chip->ibl.granularity); |
| 1158 | chip->ibl.granularity) * chip->ibl.granularity; | ||
| 1159 | if (chip->ibl.size > chip->ibl.max_size) | 1158 | if (chip->ibl.size > chip->ibl.max_size) |
| 1160 | chip->ibl.size = chip->ibl.max_size; | 1159 | chip->ibl.size = chip->ibl.max_size; |
| 1161 | } else | 1160 | } else |
| @@ -37,11 +37,9 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | memset(&event, 0, sizeof(event)); | 38 | memset(&event, 0, sizeof(event)); |
| 39 | count = min_t(long, count, sizeof(event.lock_status)); | 39 | count = min_t(long, count, sizeof(event.lock_status)); |
| 40 | if (bebob->dev_lock_changed) { | 40 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; |
| 41 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | 41 | event.lock_status.status = (bebob->dev_lock_count > 0); |
| 42 | event.lock_status.status = (bebob->dev_lock_count > 0); | 42 | bebob->dev_lock_changed = false; |
| 43 | bebob->dev_lock_changed = false; | ||
| 44 | } | ||
| 45 | 43 | ||
| 46 | spin_unlock_irq(&bebob->lock); | 44 | spin_unlock_irq(&bebob->lock); |
| 47 | 45 | ||
| @@ -80,7 +78,7 @@ hwdep_get_info(struct snd_bebob *bebob, void __user *arg) · 32 unmodified lines | |||
| 80 | info.card = dev->card->index; | 78 | info.card = dev->card->index; |
| 81 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 79 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 82 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 80 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 83 | strlcpy(info.device_name, dev_name(&dev->device), | 81 | strscpy(info.device_name, dev_name(&dev->device), |
| 84 | sizeof(info.device_name)); | 82 | sizeof(info.device_name)); |
| 85 | 83 | ||
| 86 | if (copy_to_user(arg, &info, sizeof(info))) | 84 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -1,5 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ | 2 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ |
| 3 | dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \ | 3 | dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \ |
| 4 | dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o | 4 | dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o \ |
| 5 | dice-harman.o | ||
| 5 | obj-$(CONFIG_SND_DICE) += snd-dice.o | 6 | obj-$(CONFIG_SND_DICE) += snd-dice.o |
| @@ -0,0 +1,26 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // dice-harman.c - a part of driver for DICE based devices | ||
| 3 | // | ||
| 4 | // Copyright (c) 2021 Takashi Sakamoto | ||
| 5 | // | ||
| 6 | // Licensed under the terms of the GNU General Public License, version 2. | ||
| 7 | |||
| 8 | #include "dice.h" | ||
| 9 | |||
| 10 | int snd_dice_detect_harman_formats(struct snd_dice *dice) | ||
| 11 | { | ||
| 12 | int i; | ||
| 13 | |||
| 14 | // Lexicon I-ONYX FW810s supports sampling transfer frequency up to | ||
| 15 | // 96.0 kHz, 12 PCM channels and 1 MIDI channel in its first tx stream | ||
| 16 | // , 10 PCM channels and 1 MIDI channel in its first rx stream for all | ||
| 17 | // of the frequencies. | ||
| 18 | for (i = 0; i < 2; ++i) { | ||
| 19 | dice->tx_pcm_chs[0][i] = 12; | ||
| 20 | dice->tx_midi_ports[0] = 1; | ||
| 21 | dice->rx_pcm_chs[0][i] = 10; | ||
| 22 | dice->rx_midi_ports[0] = 1; | ||
| 23 | } | ||
| 24 | |||
| 25 | return 0; | ||
| 26 | } | ||
| @@ -79,7 +79,7 @@ static int hwdep_get_info(struct snd_dice *dice, void __user *arg) · 78 unmodified lines | |||
| 79 | info.card = dev->card->index; | 79 | info.card = dev->card->index; |
| 80 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 80 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 81 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 82 | strlcpy(info.device_name, dev_name(&dev->device), | 82 | strscpy(info.device_name, dev_name(&dev->device), |
| 83 | sizeof(info.device_name)); | 83 | sizeof(info.device_name)); |
| 84 | 84 | ||
| 85 | if (copy_to_user(arg, &info, sizeof(info))) | 85 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -20,10 +20,12 @@ MODULE_LICENSE("GPL v2"); · 19 unmodified lines | |||
| 20 | #define OUI_MYTEK 0x001ee8 | 20 | #define OUI_MYTEK 0x001ee8 |
| 21 | #define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE. | 21 | #define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE. |
| 22 | #define OUI_PRESONUS 0x000a92 | 22 | #define OUI_PRESONUS 0x000a92 |
| 23 | #define OUI_HARMAN 0x000fd7 | ||
| 23 | 24 | ||
| 24 | #define DICE_CATEGORY_ID 0x04 | 25 | #define DICE_CATEGORY_ID 0x04 |
| 25 | #define WEISS_CATEGORY_ID 0x00 | 26 | #define WEISS_CATEGORY_ID 0x00 |
| 26 | #define LOUD_CATEGORY_ID 0x10 | 27 | #define LOUD_CATEGORY_ID 0x10 |
| 28 | #define HARMAN_CATEGORY_ID 0x20 | ||
| 27 | 29 | ||
| 28 | #define MODEL_ALESIS_IO_BOTH 0x000001 | 30 | #define MODEL_ALESIS_IO_BOTH 0x000001 |
| 29 | 31 | ||
| @@ -56,6 +58,8 @@ static int check_dice_category(struct fw_unit *unit) · 26 unmodified lines | |||
| 56 | category = WEISS_CATEGORY_ID; | 58 | category = WEISS_CATEGORY_ID; |
| 57 | else if (vendor == OUI_LOUD) | 59 | else if (vendor == OUI_LOUD) |
| 58 | category = LOUD_CATEGORY_ID; | 60 | category = LOUD_CATEGORY_ID; |
| 61 | else if (vendor == OUI_HARMAN) | ||
| 62 | category = HARMAN_CATEGORY_ID; | ||
| 59 | else | 63 | else |
| 60 | category = DICE_CATEGORY_ID; | 64 | category = DICE_CATEGORY_ID; |
| 61 | if (device->config_rom[3] != ((vendor << 8) | category) || | 65 | if (device->config_rom[3] != ((vendor << 8) | category) || |
| @@ -388,6 +392,14 @@ static const struct ieee1394_device_id dice_id_table[] = { · 326 unmodified lines | |||
| 388 | .model_id = 0x000008, | 392 | .model_id = 0x000008, |
| 389 | .driver_data = (kernel_ulong_t)snd_dice_detect_presonus_formats, | 393 | .driver_data = (kernel_ulong_t)snd_dice_detect_presonus_formats, |
| 390 | }, | 394 | }, |
| 395 | // Lexicon I-ONYX FW810S. | ||
| 396 | { | ||
| 397 | .match_flags = IEEE1394_MATCH_VENDOR_ID | | ||
| 398 | IEEE1394_MATCH_MODEL_ID, | ||
| 399 | .vendor_id = OUI_HARMAN, | ||
| 400 | .model_id = 0x000001, | ||
| 401 | .driver_data = (kernel_ulong_t)snd_dice_detect_harman_formats, | ||
| 402 | }, | ||
| 391 | { | 403 | { |
| 392 | .match_flags = IEEE1394_MATCH_VERSION, | 404 | .match_flags = IEEE1394_MATCH_VERSION, |
| 393 | .version = DICE_INTERFACE, | 405 | .version = DICE_INTERFACE, |
| @@ -233,5 +233,6 @@ int snd_dice_detect_alesis_mastercontrol_formats(struct snd_dice *dice); · 232 unmodified lines | |||
| 233 | int snd_dice_detect_extension_formats(struct snd_dice *dice); | 233 | int snd_dice_detect_extension_formats(struct snd_dice *dice); |
| 234 | int snd_dice_detect_mytek_formats(struct snd_dice *dice); | 234 | int snd_dice_detect_mytek_formats(struct snd_dice *dice); |
| 235 | int snd_dice_detect_presonus_formats(struct snd_dice *dice); | 235 | int snd_dice_detect_presonus_formats(struct snd_dice *dice); |
| 236 | int snd_dice_detect_harman_formats(struct snd_dice *dice); | ||
| 236 | 237 | ||
| 237 | #endif | 238 | #endif |
| @@ -87,7 +87,7 @@ static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg) · 86 unmodified lines | |||
| 87 | info.card = dev->card->index; | 87 | info.card = dev->card->index; |
| 88 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 88 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 89 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 89 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 90 | strlcpy(info.device_name, dev_name(&dev->device), | 90 | strscpy(info.device_name, dev_name(&dev->device), |
| 91 | sizeof(info.device_name)); | 91 | sizeof(info.device_name)); |
| 92 | 92 | ||
| 93 | if (copy_to_user(arg, &info, sizeof(info))) | 93 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, · 34 unmodified lines | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | memset(&event, 0, sizeof(event)); | 37 | memset(&event, 0, sizeof(event)); |
| 38 | if (ff->dev_lock_changed) { | 38 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; |
| 39 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | 39 | event.lock_status.status = (ff->dev_lock_count > 0); |
| 40 | event.lock_status.status = (ff->dev_lock_count > 0); | 40 | ff->dev_lock_changed = false; |
| 41 | ff->dev_lock_changed = false; | ||
| 42 | 41 | ||
| 43 | count = min_t(long, count, sizeof(event.lock_status)); | 42 | count = min_t(long, count, sizeof(event.lock_status)); |
| 44 | } | ||
| 45 | 43 | ||
| 46 | spin_unlock_irq(&ff->lock); | 44 | spin_unlock_irq(&ff->lock); |
| 47 | 45 | ||
| @@ -79,7 +77,7 @@ static int hwdep_get_info(struct snd_ff *ff, void __user *arg) · 31 unmodified lines | |||
| 79 | info.card = dev->card->index; | 77 | info.card = dev->card->index; |
| 80 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 78 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 79 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 82 | strlcpy(info.device_name, dev_name(&dev->device), | 80 | strscpy(info.device_name, dev_name(&dev->device), |
| 83 | sizeof(info.device_name)); | 81 | sizeof(info.device_name)); |
| 84 | 82 | ||
| 85 | if (copy_to_user(arg, &info, sizeof(info))) | 83 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -15,6 +15,61 @@ · 14 unmodified lines | |||
| 15 | #define LATTER_FETCH_MODE 0xffff00000010ULL | 15 | #define LATTER_FETCH_MODE 0xffff00000010ULL |
| 16 | #define LATTER_SYNC_STATUS 0x0000801c0000ULL | 16 | #define LATTER_SYNC_STATUS 0x0000801c0000ULL |
| 17 | 17 | ||
| 18 | // The content of sync status register differs between models. | ||
| 19 | // | ||
| 20 | // Fireface UCX: | ||
| 21 | // 0xf0000000: (unidentified) | ||
| 22 | // 0x0f000000: effective rate of sampling clock | ||
| 23 | // 0x00f00000: detected rate of word clock on BNC interface | ||
| 24 | // 0x000f0000: detected rate of ADAT or S/PDIF on optical interface | ||
| 25 | // 0x0000f000: detected rate of S/PDIF on coaxial interface | ||
| 26 | // 0x00000e00: effective source of sampling clock | ||
| 27 | // 0x00000e00: Internal | ||
| 28 | // 0x00000800: (unidentified) | ||
| 29 | // 0x00000600: Word clock on BNC interface | ||
| 30 | // 0x00000400: ADAT on optical interface | ||
| 31 | // 0x00000200: S/PDIF on coaxial or optical interface | ||
| 32 | // 0x00000100: Optical interface is used for ADAT signal | ||
| 33 | // 0x00000080: (unidentified) | ||
| 34 | // 0x00000040: Synchronized to word clock on BNC interface | ||
| 35 | // 0x00000020: Synchronized to ADAT or S/PDIF on optical interface | ||
| 36 | // 0x00000010: Synchronized to S/PDIF on coaxial interface | ||
| 37 | // 0x00000008: (unidentified) | ||
| 38 | // 0x00000004: Lock word clock on BNC interface | ||
| 39 | // 0x00000002: Lock ADAT or S/PDIF on optical interface | ||
| 40 | // 0x00000001: Lock S/PDIF on coaxial interface | ||
| 41 | // | ||
| 42 | // Fireface 802 (and perhaps UFX): | ||
| 43 | // 0xf0000000: effective rate of sampling clock | ||
| 44 | // 0x0f000000: detected rate of ADAT-B on 2nd optical interface | ||
| 45 | // 0x00f00000: detected rate of ADAT-A on 1st optical interface | ||
| 46 | // 0x000f0000: detected rate of AES/EBU on XLR or coaxial interface | ||
| 47 | // 0x0000f000: detected rate of word clock on BNC interface | ||
| 48 | // 0x00000e00: effective source of sampling clock | ||
| 49 | // 0x00000e00: internal | ||
| 50 | // 0x00000800: ADAT-B | ||
| 51 | // 0x00000600: ADAT-A | ||
| 52 | // 0x00000400: AES/EBU | ||
| 53 | // 0x00000200: Word clock | ||
| 54 | // 0x00000080: Synchronized to ADAT-B on 2nd optical interface | ||
| 55 | // 0x00000040: Synchronized to ADAT-A on 1st optical interface | ||
| 56 | // 0x00000020: Synchronized to AES/EBU on XLR or 2nd optical interface | ||
| 57 | // 0x00000010: Synchronized to word clock on BNC interface | ||
| 58 | // 0x00000008: Lock ADAT-B on 2nd optical interface | ||
| 59 | // 0x00000004: Lock ADAT-A on 1st optical interface | ||
| 60 | // 0x00000002: Lock AES/EBU on XLR or 2nd optical interface | ||
| 61 | // 0x00000001: Lock word clock on BNC interface | ||
| 62 | // | ||
| 63 | // The pattern for rate bits: | ||
| 64 | // 0x00: 32.0 kHz | ||
| 65 | // 0x01: 44.1 kHz | ||
| 66 | // 0x02: 48.0 kHz | ||
| 67 | // 0x04: 64.0 kHz | ||
| 68 | // 0x05: 88.2 kHz | ||
| 69 | // 0x06: 96.0 kHz | ||
| 70 | // 0x08: 128.0 kHz | ||
| 71 | // 0x09: 176.4 kHz | ||
| 72 | // 0x0a: 192.0 kHz | ||
| 18 | static int parse_clock_bits(u32 data, unsigned int *rate, | 73 | static int parse_clock_bits(u32 data, unsigned int *rate, |
| 19 | enum snd_ff_clock_src *src, | 74 | enum snd_ff_clock_src *src, |
| 20 | enum snd_ff_unit_version unit_version) | 75 | enum snd_ff_unit_version unit_version) |
| @@ -23,35 +78,48 @@ static int parse_clock_bits(u32 data, unsigned int *rate, · 2 unmodified lines | |||
| 23 | unsigned int rate; | 78 | unsigned int rate; |
| 24 | u32 flag; | 79 | u32 flag; |
| 25 | } *rate_entry, rate_entries[] = { | 80 | } *rate_entry, rate_entries[] = { |
| 26 | { 32000, 0x00000000, }, | 81 | { 32000, 0x00, }, |
| 27 | { 44100, 0x01000000, }, | 82 | { 44100, 0x01, }, |
| 28 | { 48000, 0x02000000, }, | 83 | { 48000, 0x02, }, |
| 29 | { 64000, 0x04000000, }, | 84 | { 64000, 0x04, }, |
| 30 | { 88200, 0x05000000, }, | 85 | { 88200, 0x05, }, |
| 31 | { 96000, 0x06000000, }, | 86 | { 96000, 0x06, }, |
| 32 | { 128000, 0x08000000, }, | 87 | { 128000, 0x08, }, |
| 33 | { 176400, 0x09000000, }, | 88 | { 176400, 0x09, }, |
| 34 | { 192000, 0x0a000000, }, | 89 | { 192000, 0x0a, }, |
| 35 | }; | 90 | }; |
| 36 | static const struct { | 91 | static const struct { |
| 37 | enum snd_ff_clock_src src; | 92 | enum snd_ff_clock_src src; |
| 38 | u32 flag; | 93 | u32 flag; |
| 39 | } *clk_entry, clk_entries[] = { | 94 | } *clk_entry, *clk_entries, ucx_clk_entries[] = { |
| 40 | { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, }, | 95 | { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, }, |
| 41 | { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, }, | 96 | { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, }, |
| 42 | { SND_FF_CLOCK_SRC_WORD, 0x00000600, }, | 97 | { SND_FF_CLOCK_SRC_WORD, 0x00000600, }, |
| 43 | { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, }, | 98 | { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, }, |
| 99 | }, ufx_ff802_clk_entries[] = { | ||
| 100 | { SND_FF_CLOCK_SRC_WORD, 0x00000200, }, | ||
| 101 | { SND_FF_CLOCK_SRC_SPDIF, 0x00000400, }, | ||
| 102 | { SND_FF_CLOCK_SRC_ADAT1, 0x00000600, }, | ||
| 103 | { SND_FF_CLOCK_SRC_ADAT2, 0x00000800, }, | ||
| 104 | { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, }, | ||
| 44 | }; | 105 | }; |
| 106 | u32 rate_bits; | ||
| 107 | unsigned int clk_entry_count; | ||
| 45 | int i; | 108 | int i; |
| 46 | 109 | ||
| 47 | if (unit_version != SND_FF_UNIT_VERSION_UCX) { | 110 | if (unit_version == SND_FF_UNIT_VERSION_UCX) { |
| 48 | // e.g. 0x00fe0f20 but expected 0x00eff002. | 111 | rate_bits = (data & 0x0f000000) >> 24; |
| 49 | data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4); | 112 | clk_entries = ucx_clk_entries; |
| 113 | clk_entry_count = ARRAY_SIZE(ucx_clk_entries); | ||
| 114 | } else { | ||
| 115 | rate_bits = (data & 0xf0000000) >> 28; | ||
| 116 | clk_entries = ufx_ff802_clk_entries; | ||
| 117 | clk_entry_count = ARRAY_SIZE(ufx_ff802_clk_entries); | ||
| 50 | } | 118 | } |
| 51 | 119 | ||
| 52 | for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { | 120 | for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { |
| 53 | rate_entry = rate_entries + i; | 121 | rate_entry = rate_entries + i; |
| 54 | if ((data & 0x0f000000) == rate_entry->flag) { | 122 | if (rate_bits == rate_entry->flag) { |
| 55 | *rate = rate_entry->rate; | 123 | *rate = rate_entry->rate; |
| 56 | break; | 124 | break; |
| 57 | } | 125 | } |
| @@ -59,14 +127,14 @@ static int parse_clock_bits(u32 data, unsigned int *rate, · 1 unmodified line | |||
| 59 | if (i == ARRAY_SIZE(rate_entries)) | 127 | if (i == ARRAY_SIZE(rate_entries)) |
| 60 | return -EIO; | 128 | return -EIO; |
| 61 | 129 | ||
| 62 | for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { | 130 | for (i = 0; i < clk_entry_count; ++i) { |
| 63 | clk_entry = clk_entries + i; | 131 | clk_entry = clk_entries + i; |
| 64 | if ((data & 0x000e00) == clk_entry->flag) { | 132 | if ((data & 0x000e00) == clk_entry->flag) { |
| 65 | *src = clk_entry->src; | 133 | *src = clk_entry->src; |
| 66 | break; | 134 | break; |
| 67 | } | 135 | } |
| 68 | } | 136 | } |
| 69 | if (i == ARRAY_SIZE(clk_entries)) | 137 | if (i == clk_entry_count) |
| 70 | return -EIO; | 138 | return -EIO; |
| 71 | 139 | ||
| 72 | return 0; | 140 | return 0; |
| @@ -249,16 +317,22 @@ static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer · 176 unmodified lines | |||
| 249 | char *const label; | 317 | char *const label; |
| 250 | u32 locked_mask; | 318 | u32 locked_mask; |
| 251 | u32 synced_mask; | 319 | u32 synced_mask; |
| 252 | } *clk_entry, clk_entries[] = { | 320 | } *clk_entry, *clk_entries, ucx_clk_entries[] = { |
| 253 | { "S/PDIF", 0x00000001, 0x00000010, }, | 321 | { "S/PDIF", 0x00000001, 0x00000010, }, |
| 254 | { "ADAT", 0x00000002, 0x00000020, }, | 322 | { "ADAT", 0x00000002, 0x00000020, }, |
| 255 | { "WDClk", 0x00000004, 0x00000040, }, | 323 | { "WDClk", 0x00000004, 0x00000040, }, |
| 324 | }, ufx_ff802_clk_entries[] = { | ||
| 325 | { "WDClk", 0x00000001, 0x00000010, }, | ||
| 326 | { "AES/EBU", 0x00000002, 0x00000020, }, | ||
| 327 | { "ADAT-A", 0x00000004, 0x00000040, }, | ||
| 328 | { "ADAT-B", 0x00000008, 0x00000080, }, | ||
| 256 | }; | 329 | }; |
| 257 | __le32 reg; | 330 | __le32 reg; |
| 258 | u32 data; | 331 | u32 data; |
| 259 | unsigned int rate; | 332 | unsigned int rate; |
| 260 | enum snd_ff_clock_src src; | 333 | enum snd_ff_clock_src src; |
| 261 | const char *label; | 334 | const char *label; |
| 335 | unsigned int clk_entry_count; | ||
| 262 | int i; | 336 | int i; |
| 263 | int err; | 337 | int err; |
| 264 | 338 | ||
| @@ -270,7 +344,15 @@ static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer · 5 unmodified lines | |||
| 270 | 344 | ||
| 271 | snd_iprintf(buffer, "External source detection:\n"); | 345 | snd_iprintf(buffer, "External source detection:\n"); |
| 272 | 346 | ||
| 273 | for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) { | 347 | if (ff->unit_version == SND_FF_UNIT_VERSION_UCX) { |
| 348 | clk_entries = ucx_clk_entries; | ||
| 349 | clk_entry_count = ARRAY_SIZE(ucx_clk_entries); | ||
| 350 | } else { | ||
| 351 | clk_entries = ufx_ff802_clk_entries; | ||
| 352 | clk_entry_count = ARRAY_SIZE(ufx_ff802_clk_entries); | ||
| 353 | } | ||
| 354 | |||
| 355 | for (i = 0; i < clk_entry_count; ++i) { | ||
| 274 | clk_entry = clk_entries + i; | 356 | clk_entry = clk_entries + i; |
| 275 | snd_iprintf(buffer, "%s: ", clk_entry->label); | 357 | snd_iprintf(buffer, "%s: ", clk_entry->label); |
| 276 | if (data & clk_entry->locked_mask) { | 358 | if (data & clk_entry->locked_mask) { |
| @@ -212,7 +212,7 @@ hwdep_get_info(struct snd_efw *efw, void __user *arg) · 211 unmodified lines | |||
| 212 | info.card = dev->card->index; | 212 | info.card = dev->card->index; |
| 213 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 213 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 214 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 214 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 215 | strlcpy(info.device_name, dev_name(&dev->device), | 215 | strscpy(info.device_name, dev_name(&dev->device), |
| 216 | sizeof(info.device_name)); | 216 | sizeof(info.device_name)); |
| 217 | 217 | ||
| 218 | if (copy_to_user(arg, &info, sizeof(info))) | 218 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -86,7 +86,7 @@ static int hwdep_get_info(struct snd_motu *motu, void __user *arg) · 85 unmodified lines | |||
| 86 | info.card = dev->card->index; | 86 | info.card = dev->card->index; |
| 87 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 87 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 88 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 88 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 89 | strlcpy(info.device_name, dev_name(&dev->device), | 89 | strscpy(info.device_name, dev_name(&dev->device), |
| 90 | sizeof(info.device_name)); | 90 | sizeof(info.device_name)); |
| 91 | 91 | ||
| 92 | if (copy_to_user(arg, &info, sizeof(info))) | 92 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -35,13 +35,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, · 34 unmodified lines | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | memset(&event, 0, sizeof(event)); | 37 | memset(&event, 0, sizeof(event)); |
| 38 | if (oxfw->dev_lock_changed) { | 38 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; |
| 39 | event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | 39 | event.lock_status.status = (oxfw->dev_lock_count > 0); |
| 40 | event.lock_status.status = (oxfw->dev_lock_count > 0); | 40 | oxfw->dev_lock_changed = false; |
| 41 | oxfw->dev_lock_changed = false; | ||
| 42 | 41 | ||
| 43 | count = min_t(long, count, sizeof(event.lock_status)); | 42 | count = min_t(long, count, sizeof(event.lock_status)); |
| 44 | } | ||
| 45 | 43 | ||
| 46 | spin_unlock_irq(&oxfw->lock); | 44 | spin_unlock_irq(&oxfw->lock); |
| 47 | 45 | ||
| @@ -79,7 +77,7 @@ static int hwdep_get_info(struct snd_oxfw *oxfw, void __user *arg) · 31 unmodified lines | |||
| 79 | info.card = dev->card->index; | 77 | info.card = dev->card->index; |
| 80 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 78 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 79 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 82 | strlcpy(info.device_name, dev_name(&dev->device), | 80 | strscpy(info.device_name, dev_name(&dev->device), |
| 83 | sizeof(info.device_name)); | 81 | sizeof(info.device_name)); |
| 84 | 82 | ||
| 85 | if (copy_to_user(arg, &info, sizeof(info))) | 83 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -154,7 +154,7 @@ static int hwdep_get_info(struct snd_tscm *tscm, void __user *arg) · 153 unmodified lines | |||
| 154 | info.card = dev->card->index; | 154 | info.card = dev->card->index; |
| 155 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); | 155 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 156 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); | 156 | *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); |
| 157 | strlcpy(info.device_name, dev_name(&dev->device), | 157 | strscpy(info.device_name, dev_name(&dev->device), |
| 158 | sizeof(info.device_name)); | 158 | sizeof(info.device_name)); |
| 159 | 159 | ||
| 160 | if (copy_to_user(arg, &info, sizeof(info))) | 160 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -46,3 +46,17 @@ config SND_INTEL_DSP_CONFIG · 45 unmodified lines | |||
| 46 | select SND_INTEL_NHLT if ACPI | 46 | select SND_INTEL_NHLT if ACPI |
| 47 | # this config should be selected only for Intel DSP platforms. | 47 | # this config should be selected only for Intel DSP platforms. |
| 48 | # A fallback is provided so that the code compiles in all cases. | 48 | # A fallback is provided so that the code compiles in all cases. |
| 49 | |||
| 50 | config SND_INTEL_BYT_PREFER_SOF | ||
| 51 | bool "Prefer SOF driver over SST on BY/CHT platforms" | ||
| 52 | depends on SND_SST_ATOM_HIFI2_PLATFORM_ACPI && SND_SOC_SOF_BAYTRAIL | ||
| 53 | default n | ||
| 54 | help | ||
| 55 | The kernel has 2 drivers for the Low Power Engine audio-block on | ||
| 56 | Bay- and Cherry-Trail SoCs. The old SST driver and the new SOF | ||
| 57 | driver. If both drivers are enabled then the kernel will default | ||
| 58 | to using the old SST driver, unless told otherwise through the | ||
| 59 | snd_intel_dspcfg.dsp_driver module-parameter. | ||
| 60 | |||
| 61 | Set this option to Y to make the kernel default to the new SOF | ||
| 62 | driver instead. | ||
| @@ -332,3 +332,40 @@ int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, · 331 unmodified lines | |||
| 332 | return ret; | 332 | return ret; |
| 333 | } | 333 | } |
| 334 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put); | 334 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put); |
| 335 | |||
| 336 | static void hdac_ext_codec_link_up(struct hdac_device *codec) | ||
| 337 | { | ||
| 338 | const char *devname = dev_name(&codec->dev); | ||
| 339 | struct hdac_ext_link *hlink = | ||
| 340 | snd_hdac_ext_bus_get_link(codec->bus, devname); | ||
| 341 | |||
| 342 | if (hlink) | ||
| 343 | snd_hdac_ext_bus_link_get(codec->bus, hlink); | ||
| 344 | } | ||
| 345 | |||
| 346 | static void hdac_ext_codec_link_down(struct hdac_device *codec) | ||
| 347 | { | ||
| 348 | const char *devname = dev_name(&codec->dev); | ||
| 349 | struct hdac_ext_link *hlink = | ||
| 350 | snd_hdac_ext_bus_get_link(codec->bus, devname); | ||
| 351 | |||
| 352 | if (hlink) | ||
| 353 | snd_hdac_ext_bus_link_put(codec->bus, hlink); | ||
| 354 | } | ||
| 355 | |||
| 356 | void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable) | ||
| 357 | { | ||
| 358 | struct hdac_bus *bus = codec->bus; | ||
| 359 | bool oldstate = test_bit(codec->addr, &bus->codec_powered); | ||
| 360 | |||
| 361 | if (enable == oldstate) | ||
| 362 | return; | ||
| 363 | |||
| 364 | snd_hdac_bus_link_power(codec, enable); | ||
| 365 | |||
| 366 | if (enable) | ||
| 367 | hdac_ext_codec_link_up(codec); | ||
| 368 | else | ||
| 369 | hdac_ext_codec_link_down(codec); | ||
| 370 | } | ||
| 371 | EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power); | ||
| @@ -17,6 +17,7 @@ static void snd_hdac_bus_process_unsol_events(struct work_struct *work); · 16 unmodified lines | |||
| 17 | static const struct hdac_bus_ops default_ops = { | 17 | static const struct hdac_bus_ops default_ops = { |
| 18 | .command = snd_hdac_bus_send_cmd, | 18 | .command = snd_hdac_bus_send_cmd, |
| 19 | .get_response = snd_hdac_bus_get_response, | 19 | .get_response = snd_hdac_bus_get_response, |
| 20 | .link_power = snd_hdac_bus_link_power, | ||
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 22 | /** | 23 | /** |
| @@ -264,3 +265,25 @@ void snd_hdac_aligned_write(unsigned int val, void __iomem *addr, · 241 unmodified lines | |||
| 264 | } | 265 | } |
| 265 | EXPORT_SYMBOL_GPL(snd_hdac_aligned_write); | 266 | EXPORT_SYMBOL_GPL(snd_hdac_aligned_write); |
| 266 | #endif /* CONFIG_SND_HDA_ALIGNED_MMIO */ | 267 | #endif /* CONFIG_SND_HDA_ALIGNED_MMIO */ |
| 268 | |||
| 269 | void snd_hdac_codec_link_up(struct hdac_device *codec) | ||
| 270 | { | ||
| 271 | struct hdac_bus *bus = codec->bus; | ||
| 272 | |||
| 273 | if (bus->ops->link_power) | ||
| 274 | bus->ops->link_power(codec, true); | ||
| 275 | else | ||
| 276 | snd_hdac_bus_link_power(codec, true); | ||
| 277 | } | ||
| 278 | EXPORT_SYMBOL_GPL(snd_hdac_codec_link_up); | ||
| 279 | |||
| 280 | void snd_hdac_codec_link_down(struct hdac_device *codec) | ||
| 281 | { | ||
| 282 | struct hdac_bus *bus = codec->bus; | ||
| 283 | |||
| 284 | if (bus->ops->link_power) | ||
| 285 | bus->ops->link_power(codec, false); | ||
| 286 | else | ||
| 287 | snd_hdac_bus_link_power(codec, false); | ||
| 288 | } | ||
| 289 | EXPORT_SYMBOL_GPL(snd_hdac_codec_link_down); | ||
| @@ -648,3 +648,17 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus) · 647 unmodified lines | |||
| 648 | snd_dma_free_pages(&bus->posbuf); | 648 | snd_dma_free_pages(&bus->posbuf); |
| 649 | } | 649 | } |
| 650 | EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages); | 650 | EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages); |
| 651 | |||
| 652 | /** | ||
| 653 | * snd_hdac_bus_link_power - power up/down codec link | ||
| 654 | * @codec: HD-audio device | ||
| 655 | * @enable: whether to power-up the link | ||
| 656 | */ | ||
| 657 | void snd_hdac_bus_link_power(struct hdac_device *codec, bool enable) | ||
| 658 | { | ||
| 659 | if (enable) | ||
| 660 | set_bit(codec->addr, &codec->bus->codec_powered); | ||
| 661 | else | ||
| 662 | clear_bit(codec->addr, &codec->bus->codec_powered); | ||
| 663 | } | ||
| 664 | EXPORT_SYMBOL_GPL(snd_hdac_bus_link_power); | ||
| @@ -435,12 +435,11 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev) · 434 unmodified lines | |||
| 435 | pos_adj = bus->bdl_pos_adj; | 435 | pos_adj = bus->bdl_pos_adj; |
| 436 | if (!azx_dev->no_period_wakeup && pos_adj > 0) { | 436 | if (!azx_dev->no_period_wakeup && pos_adj > 0) { |
| 437 | pos_align = pos_adj; | 437 | pos_align = pos_adj; |
| 438 | pos_adj = (pos_adj * runtime->rate + 47999) / 48000; | 438 | pos_adj = DIV_ROUND_UP(pos_adj * runtime->rate, 48000); |
| 439 | if (!pos_adj) | 439 | if (!pos_adj) |
| 440 | pos_adj = pos_align; | 440 | pos_adj = pos_align; |
| 441 | else | 441 | else |
| 442 | pos_adj = ((pos_adj + pos_align - 1) / pos_align) * | 442 | pos_adj = roundup(pos_adj, pos_align); |
| 443 | pos_align; | ||
| 444 | pos_adj = frames_to_bytes(runtime, pos_adj); | 443 | pos_adj = frames_to_bytes(runtime, pos_adj); |
| 445 | if (pos_adj >= period_bytes) { | 444 | if (pos_adj >= period_bytes) { |
| 446 | dev_warn(bus->dev, "Too big adjustment %d\n", | 445 | dev_warn(bus->dev, "Too big adjustment %d\n", |
| @@ -66,7 +66,7 @@ static struct attribute *hdac_dev_attrs[] = { · 65 unmodified lines | |||
| 66 | NULL | 66 | NULL |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | static struct attribute_group hdac_dev_attr_group = { | 69 | static const struct attribute_group hdac_dev_attr_group = { |
| 70 | .attrs = hdac_dev_attrs, | 70 | .attrs = hdac_dev_attrs, |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| @@ -321,6 +321,18 @@ static const struct config_entry config_table[] = { · 320 unmodified lines | |||
| 321 | }, | 321 | }, |
| 322 | #endif | 322 | #endif |
| 323 | 323 | ||
| 324 | /* Alder Lake */ | ||
| 325 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) | ||
| 326 | { | ||
| 327 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | ||
| 328 | .device = 0x7ad0, | ||
| 329 | }, | ||
| 330 | { | ||
| 331 | .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, | ||
| 332 | .device = 0x51c8, | ||
| 333 | }, | ||
| 334 | #endif | ||
| 335 | |||
| 324 | }; | 336 | }; |
| 325 | 337 | ||
| 326 | static const struct config_entry *snd_intel_dsp_find_config | 338 | static const struct config_entry *snd_intel_dsp_find_config |
| @@ -452,35 +464,30 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci) · 125 unmodified lines | |||
| 452 | } | 464 | } |
| 453 | EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); | 465 | EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe); |
| 454 | 466 | ||
| 467 | /* Should we default to SOF or SST for BYT/CHT ? */ | ||
| 468 | #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \ | ||
| 469 | !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | ||
| 470 | #define FLAG_SST_OR_SOF_BYT FLAG_SOF | ||
| 471 | #else | ||
| 472 | #define FLAG_SST_OR_SOF_BYT FLAG_SST | ||
| 473 | #endif | ||
| 474 | |||
| 455 | /* | 475 | /* |
| 456 | * configuration table | 476 | * configuration table |
| 457 | * - the order of similar ACPI ID entries is important! | 477 | * - the order of similar ACPI ID entries is important! |
| 458 | * - the first successful match will win | 478 | * - the first successful match will win |
| 459 | */ | 479 | */ |
| 460 | static const struct config_entry acpi_config_table[] = { | 480 | static const struct config_entry acpi_config_table[] = { |
| 481 | #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \ | ||
| 482 | IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | ||
| 461 | /* BayTrail */ | 483 | /* BayTrail */ |
| 462 | #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | ||
| 463 | { | ||
| 464 | .flags = FLAG_SST, | ||
| 465 | .acpi_hid = "80860F28", | ||
| 466 | }, | ||
| 467 | #endif | ||
| 468 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | ||
| 469 | { | 484 | { |
| 470 | .flags = FLAG_SOF, | 485 | .flags = FLAG_SST_OR_SOF_BYT, |
| 471 | .acpi_hid = "80860F28", | 486 | .acpi_hid = "80860F28", |
| 472 | }, | 487 | }, |
| 473 | #endif | ||
| 474 | /* CherryTrail */ | 488 | /* CherryTrail */ |
| 475 | #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | ||
| 476 | { | 489 | { |
| 477 | .flags = FLAG_SST, | 490 | .flags = FLAG_SST_OR_SOF_BYT, |
| 478 | .acpi_hid = "808622A8", | ||
| 479 | }, | ||
| 480 | #endif | ||
| 481 | #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | ||
| 482 | { | ||
| 483 | .flags = FLAG_SOF, | ||
| 484 | .acpi_hid = "808622A8", | 491 | .acpi_hid = "808622A8", |
| 485 | }, | 492 | }, |
| 486 | #endif | 493 | #endif |
| @@ -84,7 +84,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name, · 83 unmodified lines | |||
| 84 | list_add_tail(&bus->buses, &master->buses); | 84 | list_add_tail(&bus->buses, &master->buses); |
| 85 | bus->master = master; | 85 | bus->master = master; |
| 86 | } | 86 | } |
| 87 | strlcpy(bus->name, name, sizeof(bus->name)); | 87 | strscpy(bus->name, name, sizeof(bus->name)); |
| 88 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops); | 88 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops); |
| 89 | if (err < 0) { | 89 | if (err < 0) { |
| 90 | snd_i2c_bus_free(bus); | 90 | snd_i2c_bus_free(bus); |
| @@ -108,7 +108,7 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name, · 17 unmodified lines | |||
| 108 | if (device == NULL) | 108 | if (device == NULL) |
| 109 | return -ENOMEM; | 109 | return -ENOMEM; |
| 110 | device->addr = addr; | 110 | device->addr = addr; |
| 111 | strlcpy(device->name, name, sizeof(device->name)); | 111 | strscpy(device->name, name, sizeof(device->name)); |
| 112 | list_add_tail(&device->list, &bus->devices); | 112 | list_add_tail(&device->list, &bus->devices); |
| 113 | device->bus = bus; | 113 | device->bus = bus; |
| 114 | *rdevice = device; | 114 | *rdevice = device; |
| @@ -95,8 +95,8 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) · 94 unmodified lines | |||
| 95 | if (error < 0) | 95 | if (error < 0) |
| 96 | goto out; | 96 | goto out; |
| 97 | 97 | ||
| 98 | strlcpy(card->driver, "AD1848", sizeof(card->driver)); | 98 | strscpy(card->driver, "AD1848", sizeof(card->driver)); |
| 99 | strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | 99 | strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); |
| 100 | 100 | ||
| 101 | if (!thinkpad[n]) | 101 | if (!thinkpad[n]) |
| 102 | snprintf(card->longname, sizeof(card->longname), | 102 | snprintf(card->longname, sizeof(card->longname), |
| @@ -118,10 +118,9 @@ out: snd_card_free(card); · 15 unmodified lines | |||
| 118 | return error; | 118 | return error; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static int snd_ad1848_remove(struct device *dev, unsigned int n) | 121 | static void snd_ad1848_remove(struct device *dev, unsigned int n) |
| 122 | { | 122 | { |
| 123 | snd_card_free(dev_get_drvdata(dev)); | 123 | snd_card_free(dev_get_drvdata(dev)); |
| 124 | return 0; | ||
| 125 | } | 124 | } |
| 126 | 125 | ||
| 127 | #ifdef CONFIG_PM | 126 | #ifdef CONFIG_PM |
| @@ -97,10 +97,9 @@ out: snd_card_free(card); · 96 unmodified lines | |||
| 97 | return error; | 97 | return error; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static int snd_adlib_remove(struct device *dev, unsigned int n) | 100 | static void snd_adlib_remove(struct device *dev, unsigned int n) |
| 101 | { | 101 | { |
| 102 | snd_card_free(dev_get_drvdata(dev)); | 102 | snd_card_free(dev_get_drvdata(dev)); |
| 103 | return 0; | ||
| 104 | } | 103 | } |
| 105 | 104 | ||
| 106 | static struct isa_driver snd_adlib_driver = { | 105 | static struct isa_driver snd_adlib_driver = { |
| @@ -403,7 +403,7 @@ error: · 402 unmodified lines | |||
| 403 | return err; | 403 | return err; |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | static int snd_cmi8328_remove(struct device *pdev, unsigned int dev) | 406 | static void snd_cmi8328_remove(struct device *pdev, unsigned int dev) |
| 407 | { | 407 | { |
| 408 | struct snd_card *card = dev_get_drvdata(pdev); | 408 | struct snd_card *card = dev_get_drvdata(pdev); |
| 409 | struct snd_cmi8328 *cmi = card->private_data; | 409 | struct snd_cmi8328 *cmi = card->private_data; |
| @@ -420,7 +420,6 @@ static int snd_cmi8328_remove(struct device *pdev, unsigned int dev) · 10 unmodified lines | |||
| 420 | snd_cmi8328_cfg_write(cmi->port, CFG2, 0); | 420 | snd_cmi8328_cfg_write(cmi->port, CFG2, 0); |
| 421 | snd_cmi8328_cfg_write(cmi->port, CFG3, 0); | 421 | snd_cmi8328_cfg_write(cmi->port, CFG3, 0); |
| 422 | snd_card_free(card); | 422 | snd_card_free(card); |
| 423 | return 0; | ||
| 424 | } | 423 | } |
| 425 | 424 | ||
| 426 | #ifdef CONFIG_PM | 425 | #ifdef CONFIG_PM |
| @@ -631,11 +631,10 @@ static int snd_cmi8330_isa_probe(struct device *pdev, · 630 unmodified lines | |||
| 631 | return 0; | 631 | return 0; |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | static int snd_cmi8330_isa_remove(struct device *devptr, | 634 | static void snd_cmi8330_isa_remove(struct device *devptr, |
| 635 | unsigned int dev) | 635 | unsigned int dev) |
| 636 | { | 636 | { |
| 637 | snd_card_free(dev_get_drvdata(devptr)); | 637 | snd_card_free(dev_get_drvdata(devptr)); |
| 638 | return 0; | ||
| 639 | } | 638 | } |
| 640 | 639 | ||
| 641 | #ifdef CONFIG_PM | 640 | #ifdef CONFIG_PM |
| @@ -95,8 +95,8 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) · 94 unmodified lines | |||
| 95 | if (error < 0) | 95 | if (error < 0) |
| 96 | goto out; | 96 | goto out; |
| 97 | 97 | ||
| 98 | strlcpy(card->driver, "CS4231", sizeof(card->driver)); | 98 | strscpy(card->driver, "CS4231", sizeof(card->driver)); |
| 99 | strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | 99 | strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); |
| 100 | 100 | ||
| 101 | if (dma2[n] < 0) | 101 | if (dma2[n] < 0) |
| 102 | snprintf(card->longname, sizeof(card->longname), | 102 | snprintf(card->longname, sizeof(card->longname), |
| @@ -135,10 +135,9 @@ out: snd_card_free(card); · 32 unmodified lines | |||
| 135 | return error; | 135 | return error; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int snd_cs4231_remove(struct device *dev, unsigned int n) | 138 | static void snd_cs4231_remove(struct device *dev, unsigned int n) |
| 139 | { | 139 | { |
| 140 | snd_card_free(dev_get_drvdata(dev)); | 140 | snd_card_free(dev_get_drvdata(dev)); |
| 141 | return 0; | ||
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | #ifdef CONFIG_PM | 143 | #ifdef CONFIG_PM |
| @@ -405,8 +405,8 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) · 404 unmodified lines | |||
| 405 | if (err < 0) | 405 | if (err < 0) |
| 406 | return err; | 406 | return err; |
| 407 | } | 407 | } |
| 408 | strlcpy(card->driver, chip->pcm->name, sizeof(card->driver)); | 408 | strscpy(card->driver, chip->pcm->name, sizeof(card->driver)); |
| 409 | strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | 409 | strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); |
| 410 | if (dma2[dev] < 0) | 410 | if (dma2[dev] < 0) |
| 411 | snprintf(card->longname, sizeof(card->longname), | 411 | snprintf(card->longname, sizeof(card->longname), |
| 412 | "%s at 0x%lx, irq %i, dma %i", | 412 | "%s at 0x%lx, irq %i, dma %i", |
| @@ -487,11 +487,10 @@ static int snd_cs423x_isa_probe(struct device *pdev, · 74 unmodified lines | |||
| 487 | return 0; | 487 | return 0; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | static int snd_cs423x_isa_remove(struct device *pdev, | 490 | static void snd_cs423x_isa_remove(struct device *pdev, |
| 491 | unsigned int dev) | 491 | unsigned int dev) |
| 492 | { | 492 | { |
| 493 | snd_card_free(dev_get_drvdata(pdev)); | 493 | snd_card_free(dev_get_drvdata(pdev)); |
| 494 | return 0; | ||
| 495 | } | 494 | } |
| 496 | 495 | ||
| 497 | #ifdef CONFIG_PM | 496 | #ifdef CONFIG_PM |
| @@ -133,8 +133,8 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n) · 132 unmodified lines | |||
| 133 | if (error < 0) | 133 | if (error < 0) |
| 134 | return error; | 134 | return error; |
| 135 | 135 | ||
| 136 | strlcpy(card->driver, "ES1688", sizeof(card->driver)); | 136 | strscpy(card->driver, "ES1688", sizeof(card->driver)); |
| 137 | strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | 137 | strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); |
| 138 | snprintf(card->longname, sizeof(card->longname), | 138 | snprintf(card->longname, sizeof(card->longname), |
| 139 | "%s at 0x%lx, irq %i, dma %i", chip->pcm->name, chip->port, | 139 | "%s at 0x%lx, irq %i, dma %i", chip->pcm->name, chip->port, |
| 140 | chip->irq, chip->dma8); | 140 | chip->irq, chip->dma8); |
| @@ -192,10 +192,9 @@ out: · 51 unmodified lines | |||
| 192 | return error; | 192 | return error; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int snd_es1688_isa_remove(struct device *dev, unsigned int n) | 195 | static void snd_es1688_isa_remove(struct device *dev, unsigned int n) |
| 196 | { | 196 | { |
| 197 | snd_card_free(dev_get_drvdata(dev)); | 197 | snd_card_free(dev_get_drvdata(dev)); |
| 198 | return 0; | ||
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | static struct isa_driver snd_es1688_driver = { | 200 | static struct isa_driver snd_es1688_driver = { |
| @@ -2210,11 +2210,10 @@ static int snd_es18xx_isa_probe(struct device *pdev, unsigned int dev) · 2209 unmodified lines | |||
| 2210 | } | 2210 | } |
| 2211 | } | 2211 | } |
| 2212 | 2212 | ||
| 2213 | static int snd_es18xx_isa_remove(struct device *devptr, | 2213 | static void snd_es18xx_isa_remove(struct device *devptr, |
| 2214 | unsigned int dev) | 2214 | unsigned int dev) |
| 2215 | { | 2215 | { |
| 2216 | snd_card_free(dev_get_drvdata(devptr)); | 2216 | snd_card_free(dev_get_drvdata(devptr)); |
| 2217 | return 0; | ||
| 2218 | } | 2217 | } |
| 2219 | 2218 | ||
| 2220 | #ifdef CONFIG_PM | 2219 | #ifdef CONFIG_PM |
| @@ -608,10 +608,9 @@ error: · 607 unmodified lines | |||
| 608 | return err; | 608 | return err; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | static int snd_galaxy_remove(struct device *dev, unsigned int n) | 611 | static void snd_galaxy_remove(struct device *dev, unsigned int n) |
| 612 | { | 612 | { |
| 613 | snd_card_free(dev_get_drvdata(dev)); | 613 | snd_card_free(dev_get_drvdata(dev)); |
| 614 | return 0; | ||
| 615 | } | 614 | } |
| 616 | 615 | ||
| 617 | static struct isa_driver snd_galaxy_driver = { | 616 | static struct isa_driver snd_galaxy_driver = { |
| @@ -195,10 +195,9 @@ out: snd_card_free(card); · 194 unmodified lines | |||
| 195 | return error; | 195 | return error; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | static int snd_gusclassic_remove(struct device *dev, unsigned int n) | 198 | static void snd_gusclassic_remove(struct device *dev, unsigned int n) |
| 199 | { | 199 | { |
| 200 | snd_card_free(dev_get_drvdata(dev)); | 200 | snd_card_free(dev_get_drvdata(dev)); |
| 201 | return 0; | ||
| 202 | } | 201 | } |
| 203 | 202 | ||
| 204 | static struct isa_driver snd_gusclassic_driver = { | 203 | static struct isa_driver snd_gusclassic_driver = { |
| @@ -324,10 +324,9 @@ out: snd_card_free(card); · 323 unmodified lines | |||
| 324 | return error; | 324 | return error; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | static int snd_gusextreme_remove(struct device *dev, unsigned int n) | 327 | static void snd_gusextreme_remove(struct device *dev, unsigned int n) |
| 328 | { | 328 | { |
| 329 | snd_card_free(dev_get_drvdata(dev)); | 329 | snd_card_free(dev_get_drvdata(dev)); |
| 330 | return 0; | ||
| 331 | } | 330 | } |
| 332 | 331 | ||
| 333 | static struct isa_driver snd_gusextreme_driver = { | 332 | static struct isa_driver snd_gusextreme_driver = { |
| @@ -338,10 +338,9 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev) · 337 unmodified lines | |||
| 338 | return err; | 338 | return err; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | static int snd_gusmax_remove(struct device *devptr, unsigned int dev) | 341 | static void snd_gusmax_remove(struct device *devptr, unsigned int dev) |
| 342 | { | 342 | { |
| 343 | snd_card_free(dev_get_drvdata(devptr)); | 343 | snd_card_free(dev_get_drvdata(devptr)); |
| 344 | return 0; | ||
| 345 | } | 344 | } |
| 346 | 345 | ||
| 347 | #define DEV_NAME "gusmax" | 346 | #define DEV_NAME "gusmax" |
| @@ -825,10 +825,9 @@ static int snd_interwave_isa_probe(struct device *pdev, · 824 unmodified lines | |||
| 825 | } | 825 | } |
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev) | 828 | static void snd_interwave_isa_remove(struct device *devptr, unsigned int dev) |
| 829 | { | 829 | { |
| 830 | snd_card_free(dev_get_drvdata(devptr)); | 830 | snd_card_free(dev_get_drvdata(devptr)); |
| 831 | return 0; | ||
| 832 | } | 831 | } |
| 833 | 832 | ||
| 834 | static struct isa_driver snd_interwave_driver = { | 833 | static struct isa_driver snd_interwave_driver = { |
| @@ -1049,10 +1049,9 @@ cfg_error: · 1048 unmodified lines | |||
| 1049 | #endif | 1049 | #endif |
| 1050 | } | 1050 | } |
| 1051 | 1051 | ||
| 1052 | static int snd_msnd_isa_remove(struct device *pdev, unsigned int dev) | 1052 | static void snd_msnd_isa_remove(struct device *pdev, unsigned int dev) |
| 1053 | { | 1053 | { |
| 1054 | snd_msnd_unload(dev_get_drvdata(pdev)); | 1054 | snd_msnd_unload(dev_get_drvdata(pdev)); |
| 1055 | return 0; | ||
| 1056 | } | 1055 | } |
| 1057 | 1056 | ||
| 1058 | static struct isa_driver snd_msnd_driver = { | 1057 | static struct isa_driver snd_msnd_driver = { |
| @@ -878,11 +878,10 @@ static int snd_opl3sa2_isa_probe(struct device *pdev, · 877 unmodified lines | |||
| 878 | return 0; | 878 | return 0; |
| 879 | } | 879 | } |
| 880 | 880 | ||
| 881 | static int snd_opl3sa2_isa_remove(struct device *devptr, | 881 | static void snd_opl3sa2_isa_remove(struct device *devptr, |
| 882 | unsigned int dev) | 882 | unsigned int dev) |
| 883 | { | 883 | { |
| 884 | snd_card_free(dev_get_drvdata(devptr)); | 884 | snd_card_free(dev_get_drvdata(devptr)); |
| 885 | return 0; | ||
| 886 | } | 885 | } |
| 887 | 886 | ||
| 888 | #ifdef CONFIG_PM | 887 | #ifdef CONFIG_PM |
| @@ -1480,11 +1480,10 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n) · 1479 unmodified lines | |||
| 1480 | return 0; | 1480 | return 0; |
| 1481 | } | 1481 | } |
| 1482 | 1482 | ||
| 1483 | static int snd_miro_isa_remove(struct device *devptr, | 1483 | static void snd_miro_isa_remove(struct device *devptr, |
| 1484 | unsigned int dev) | 1484 | unsigned int dev) |
| 1485 | { | 1485 | { |
| 1486 | snd_card_free(dev_get_drvdata(devptr)); | 1486 | snd_card_free(dev_get_drvdata(devptr)); |
| 1487 | return 0; | ||
| 1488 | } | 1487 | } |
| 1489 | 1488 | ||
| 1490 | #define DEV_NAME "miro" | 1489 | #define DEV_NAME "miro" |
| @@ -1024,11 +1024,10 @@ static int snd_opti9xx_isa_probe(struct device *devptr, · 1023 unmodified lines | |||
| 1024 | return 0; | 1024 | return 0; |
| 1025 | } | 1025 | } |
| 1026 | 1026 | ||
| 1027 | static int snd_opti9xx_isa_remove(struct device *devptr, | 1027 | static void snd_opti9xx_isa_remove(struct device *devptr, |
| 1028 | unsigned int dev) | 1028 | unsigned int dev) |
| 1029 | { | 1029 | { |
| 1030 | snd_card_free(dev_get_drvdata(devptr)); | 1030 | snd_card_free(dev_get_drvdata(devptr)); |
| 1031 | return 0; | ||
| 1032 | } | 1031 | } |
| 1033 | 1032 | ||
| 1034 | #ifdef CONFIG_PM | 1033 | #ifdef CONFIG_PM |
| @@ -339,12 +339,11 @@ err_free: · 338 unmodified lines | |||
| 339 | return err; | 339 | return err; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | static int snd_jazz16_remove(struct device *devptr, unsigned int dev) | 342 | static void snd_jazz16_remove(struct device *devptr, unsigned int dev) |
| 343 | { | 343 | { |
| 344 | struct snd_card *card = dev_get_drvdata(devptr); | 344 | struct snd_card *card = dev_get_drvdata(devptr); |
| 345 | 345 | ||
| 346 | snd_card_free(card); | 346 | snd_card_free(card); |
| 347 | return 0; | ||
| 348 | } | 347 | } |
| 349 | 348 | ||
| 350 | #ifdef CONFIG_PM | 349 | #ifdef CONFIG_PM |
| @@ -547,10 +547,9 @@ static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev) · 546 unmodified lines | |||
| 547 | } | 547 | } |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static int snd_sb16_isa_remove(struct device *pdev, unsigned int dev) | 550 | static void snd_sb16_isa_remove(struct device *pdev, unsigned int dev) |
| 551 | { | 551 | { |
| 552 | snd_card_free(dev_get_drvdata(pdev)); | 552 | snd_card_free(dev_get_drvdata(pdev)); |
| 553 | return 0; | ||
| 554 | } | 553 | } |
| 555 | 554 | ||
| 556 | #ifdef CONFIG_PM | 555 | #ifdef CONFIG_PM |
| @@ -388,7 +388,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p, · 387 unmodified lines | |||
| 388 | return err; | 388 | return err; |
| 389 | 389 | ||
| 390 | /* fill in codec header */ | 390 | /* fill in codec header */ |
| 391 | strlcpy(p->codec_name, info.codec_name, sizeof(p->codec_name)); | 391 | strscpy(p->codec_name, info.codec_name, sizeof(p->codec_name)); |
| 392 | p->func_nr = func_nr; | 392 | p->func_nr = func_nr; |
| 393 | p->mode = le16_to_cpu(funcdesc_h.flags_play_rec); | 393 | p->mode = le16_to_cpu(funcdesc_h.flags_play_rec); |
| 394 | switch (le16_to_cpu(funcdesc_h.VOC_type)) { | 394 | switch (le16_to_cpu(funcdesc_h.VOC_type)) { |
| @@ -192,10 +192,9 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev) · 191 unmodified lines | |||
| 192 | return err; | 192 | return err; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int snd_sb8_remove(struct device *pdev, unsigned int dev) | 195 | static void snd_sb8_remove(struct device *pdev, unsigned int dev) |
| 196 | { | 196 | { |
| 197 | snd_card_free(dev_get_drvdata(pdev)); | 197 | snd_card_free(dev_get_drvdata(pdev)); |
| 198 | return 0; | ||
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | #ifdef CONFIG_PM | 200 | #ifdef CONFIG_PM |
| @@ -482,7 +482,7 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty · 481 unmodified lines | |||
| 482 | ctl = snd_ctl_new1(&newctls[type], chip); | 482 | ctl = snd_ctl_new1(&newctls[type], chip); |
| 483 | if (! ctl) | 483 | if (! ctl) |
| 484 | return -ENOMEM; | 484 | return -ENOMEM; |
| 485 | strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); | 485 | strscpy(ctl->id.name, name, sizeof(ctl->id.name)); |
| 486 | ctl->id.index = index; | 486 | ctl->id.index = index; |
| 487 | ctl->private_value = value; | 487 | ctl->private_value = value; |
| 488 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) | 488 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) |
| @@ -672,7 +672,7 @@ err_exit: · 671 unmodified lines | |||
| 672 | return err; | 672 | return err; |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | static int snd_sc6000_remove(struct device *devptr, unsigned int dev) | 675 | static void snd_sc6000_remove(struct device *devptr, unsigned int dev) |
| 676 | { | 676 | { |
| 677 | struct snd_card *card = dev_get_drvdata(devptr); | 677 | struct snd_card *card = dev_get_drvdata(devptr); |
| 678 | char __iomem **vport = card->private_data; | 678 | char __iomem **vport = card->private_data; |
| @@ -684,7 +684,6 @@ static int snd_sc6000_remove(struct device *devptr, unsigned int dev) · 5 unmodified lines | |||
| 684 | release_region(mss_port[dev], 4); | 684 | release_region(mss_port[dev], 4); |
| 685 | 685 | ||
| 686 | snd_card_free(card); | 686 | snd_card_free(card); |
| 687 | return 0; | ||
| 688 | } | 687 | } |
| 689 | 688 | ||
| 690 | static struct isa_driver snd_sc6000_driver = { | 689 | static struct isa_driver snd_sc6000_driver = { |
| @@ -1183,10 +1183,9 @@ _release_card: · 1182 unmodified lines | |||
| 1183 | return ret; | 1183 | return ret; |
| 1184 | } | 1184 | } |
| 1185 | 1185 | ||
| 1186 | static int snd_sscape_remove(struct device *devptr, unsigned int dev) | 1186 | static void snd_sscape_remove(struct device *devptr, unsigned int dev) |
| 1187 | { | 1187 | { |
| 1188 | snd_card_free(dev_get_drvdata(devptr)); | 1188 | snd_card_free(dev_get_drvdata(devptr)); |
| 1189 | return 0; | ||
| 1190 | } | 1189 | } |
| 1191 | 1190 | ||
| 1192 | #define DEV_NAME "sscape" | 1191 | #define DEV_NAME "sscape" |
| @@ -565,11 +565,10 @@ static int snd_wavefront_isa_probe(struct device *pdev, · 564 unmodified lines | |||
| 565 | return 0; | 565 | return 0; |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | static int snd_wavefront_isa_remove(struct device *devptr, | 568 | static void snd_wavefront_isa_remove(struct device *devptr, |
| 569 | unsigned int dev) | 569 | unsigned int dev) |
| 570 | { | 570 | { |
| 571 | snd_card_free(dev_get_drvdata(devptr)); | 571 | snd_card_free(dev_get_drvdata(devptr)); |
| 572 | return 0; | ||
| 573 | } | 572 | } |
| 574 | 573 | ||
| 575 | #define DEV_NAME "wavefront" | 574 | #define DEV_NAME "wavefront" |
| @@ -355,8 +355,8 @@ static int mixer_ioctl(struct file *file, u_int cmd, u_long arg) · 354 unmodified lines | |||
| 355 | { | 355 | { |
| 356 | mixer_info info; | 356 | mixer_info info; |
| 357 | memset(&info, 0, sizeof(info)); | 357 | memset(&info, 0, sizeof(info)); |
| 358 | strlcpy(info.id, dmasound.mach.name2, sizeof(info.id)); | 358 | strscpy(info.id, dmasound.mach.name2, sizeof(info.id)); |
| 359 | strlcpy(info.name, dmasound.mach.name2, sizeof(info.name)); | 359 | strscpy(info.name, dmasound.mach.name2, sizeof(info.name)); |
| 360 | info.modify_counter = mixer.modify_counter; | 360 | info.modify_counter = mixer.modify_counter; |
| 361 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | 361 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) |
| 362 | return -EFAULT; | 362 | return -EFAULT; |
| @@ -857,8 +857,7 @@ snd_ad1889_create(struct snd_card *card, · 856 unmodified lines | |||
| 857 | return err; | 857 | return err; |
| 858 | 858 | ||
| 859 | /* check PCI availability (32bit DMA) */ | 859 | /* check PCI availability (32bit DMA) */ |
| 860 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | 860 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { |
| 861 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | ||
| 862 | dev_err(card->dev, "error setting 32-bit DMA mask.\n"); | 861 | dev_err(card->dev, "error setting 32-bit DMA mask.\n"); |
| 863 | pci_disable_device(pci); | 862 | pci_disable_device(pci); |
| 864 | return -ENXIO; | 863 | return -ENXIO; |
| @@ -2057,8 +2057,7 @@ static int snd_ali_create(struct snd_card *card, · 2056 unmodified lines | |||
| 2057 | if (err < 0) | 2057 | if (err < 0) |
| 2058 | return err; | 2058 | return err; |
| 2059 | /* check, if we can restrict PCI DMA transfers to 31 bits */ | 2059 | /* check, if we can restrict PCI DMA transfers to 31 bits */ |
| 2060 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(31)) < 0 || | 2060 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31))) { |
| 2061 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(31)) < 0) { | ||
| 2062 | dev_err(card->dev, | 2061 | dev_err(card->dev, |
| 2063 | "architecture does not support 31bit PCI busmaster DMA\n"); | 2062 | "architecture does not support 31bit PCI busmaster DMA\n"); |
| 2064 | pci_disable_device(pci); | 2063 | pci_disable_device(pci); |
| @@ -625,8 +625,7 @@ static int snd_als300_create(struct snd_card *card, · 624 unmodified lines | |||
| 625 | if ((err = pci_enable_device(pci)) < 0) | 625 | if ((err = pci_enable_device(pci)) < 0) |
| 626 | return err; | 626 | return err; |
| 627 | 627 | ||
| 628 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | 628 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { |
| 629 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | ||
| 630 | dev_err(card->dev, "error setting 28bit DMA mask\n"); | 629 | dev_err(card->dev, "error setting 28bit DMA mask\n"); |
| 631 | pci_disable_device(pci); | 630 | pci_disable_device(pci); |
| 632 | return -ENXIO; | 631 | return -ENXIO; |
| @@ -837,8 +837,7 @@ static int snd_card_als4000_probe(struct pci_dev *pci, · 836 unmodified lines | |||
| 837 | return err; | 837 | return err; |
| 838 | } | 838 | } |
| 839 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 839 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 840 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | 840 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { |
| 841 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | ||
| 842 | dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n"); | 841 | dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n"); |
| 843 | pci_disable_device(pci); | 842 | pci_disable_device(pci); |
| 844 | return -ENXIO; | 843 | return -ENXIO; |
| @@ -52,7 +52,7 @@ void hpi_debug_data(u16 *pdata, u32 len) · 51 unmodified lines | |||
| 52 | int lines; | 52 | int lines; |
| 53 | int cols = 8; | 53 | int cols = 8; |
| 54 | 54 | ||
| 55 | lines = (len + cols - 1) / cols; | 55 | lines = DIV_ROUND_UP(len, cols); |
| 56 | if (lines > 8) | 56 | if (lines > 8) |
| 57 | lines = 8; | 57 | lines = 8; |
| 58 | 58 | ||
| @@ -151,8 +151,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) · 150 unmodified lines | |||
| 151 | // check PCI availability (DMA). | 151 | // check PCI availability (DMA). |
| 152 | if ((err = pci_enable_device(pci)) < 0) | 152 | if ((err = pci_enable_device(pci)) < 0) |
| 153 | return err; | 153 | return err; |
| 154 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | 154 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { |
| 155 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | ||
| 156 | dev_err(card->dev, "error to set DMA mask\n"); | 155 | dev_err(card->dev, "error to set DMA mask\n"); |
| 157 | pci_disable_device(pci); | 156 | pci_disable_device(pci); |
| 158 | return -ENXIO; | 157 | return -ENXIO; |
| @@ -236,8 +236,7 @@ static int snd_aw2_create(struct snd_card *card, · 235 unmodified lines | |||
| 236 | pci_set_master(pci); | 236 | pci_set_master(pci); |
| 237 | 237 | ||
| 238 | /* check PCI availability (32bit DMA) */ | 238 | /* check PCI availability (32bit DMA) */ |
| 239 | if ((dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) || | 239 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { |
| 240 | (dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0)) { | ||
| 241 | dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); | 240 | dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); |
| 242 | pci_disable_device(pci); | 241 | pci_disable_device(pci); |
| 243 | return -ENXIO; | 242 | return -ENXIO; |
| @@ -2379,8 +2379,7 @@ snd_azf3328_create(struct snd_card *card, · 2378 unmodified lines | |||
| 2379 | chip->irq = -1; | 2379 | chip->irq = -1; |
| 2380 | 2380 | ||
| 2381 | /* check if we can restrict PCI DMA transfers to 24 bits */ | 2381 | /* check if we can restrict PCI DMA transfers to 24 bits */ |
| 2382 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | 2382 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { |
| 2383 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | ||
| 2384 | dev_err(card->dev, | 2383 | dev_err(card->dev, |
| 2385 | "architecture does not support 24bit PCI busmaster DMA\n" | 2384 | "architecture does not support 24bit PCI busmaster DMA\n" |
| 2386 | ); | 2385 | ); |
| @@ -2448,7 +2447,7 @@ snd_azf3328_create(struct snd_card *card, · 61 unmodified lines | |||
| 2448 | 2447 | ||
| 2449 | /* shutdown codecs to reduce power / noise */ | 2448 | /* shutdown codecs to reduce power / noise */ |
| 2450 | /* have ...ctrl_codec_activity() act properly */ | 2449 | /* have ...ctrl_codec_activity() act properly */ |
| 2451 | codec->running = 1; | 2450 | codec->running = true; |
| 2452 | snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); | 2451 | snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); |
| 2453 | 2452 | ||
| 2454 | spin_lock_irq(codec->lock); | 2453 | spin_lock_irq(codec->lock); |
| @@ -327,7 +327,8 @@ static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id) · 326 unmodified lines | |||
| 327 | current_block = chip->current_line * 16 / chip->lines; | 327 | current_block = chip->current_line * 16 / chip->lines; |
| 328 | irq_block = status >> INT_RISCS_SHIFT; | 328 | irq_block = status >> INT_RISCS_SHIFT; |
| 329 | if (current_block != irq_block) | 329 | if (current_block != irq_block) |
| 330 | chip->current_line = (irq_block * chip->lines + 15) / 16; | 330 | chip->current_line = DIV_ROUND_UP(irq_block * chip->lines, |
| 331 | 16); | ||
| 331 | 332 | ||
| 332 | snd_pcm_period_elapsed(chip->substream); | 333 | snd_pcm_period_elapsed(chip->substream); |
| 333 | } | 334 | } |
| @@ -1605,8 +1605,7 @@ static int snd_ca0106_create(int dev, struct snd_card *card, · 1604 unmodified lines | |||
| 1605 | err = pci_enable_device(pci); | 1605 | err = pci_enable_device(pci); |
| 1606 | if (err < 0) | 1606 | if (err < 0) |
| 1607 | return err; | 1607 | return err; |
| 1608 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | 1608 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { |
| 1609 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | ||
| 1610 | dev_err(card->dev, "error to set 32bit mask DMA\n"); | 1609 | dev_err(card->dev, "error to set 32bit mask DMA\n"); |
| 1611 | pci_disable_device(pci); | 1610 | pci_disable_device(pci); |
| 1612 | return -ENXIO; | 1611 | return -ENXIO; |
| @@ -813,7 +813,7 @@ static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned · 812 unmodified lines | |||
| 813 | correctionPerGOF = tmp1 / GOF_PER_SEC; | 813 | correctionPerGOF = tmp1 / GOF_PER_SEC; |
| 814 | tmp1 -= correctionPerGOF * GOF_PER_SEC; | 814 | tmp1 -= correctionPerGOF * GOF_PER_SEC; |
| 815 | correctionPerSec = tmp1; | 815 | correctionPerSec = tmp1; |
| 816 | initialDelay = ((48000 * 24) + rate - 1) / rate; | 816 | initialDelay = DIV_ROUND_UP(48000 * 24, rate); |
| 817 | 817 | ||
| 818 | /* | 818 | /* |
| 819 | * Fill in the VariDecimate control block. | 819 | * Fill in the VariDecimate control block. |
| @@ -269,8 +269,7 @@ static int snd_cs5535audio_create(struct snd_card *card, · 268 unmodified lines | |||
| 269 | if ((err = pci_enable_device(pci)) < 0) | 269 | if ((err = pci_enable_device(pci)) < 0) |
| 270 | return err; | 270 | return err; |
| 271 | 271 | ||
| 272 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | 272 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { |
| 273 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | ||
| 274 | dev_warn(card->dev, "unable to get 32bit dma\n"); | 273 | dev_warn(card->dev, "unable to get 32bit dma\n"); |
| 275 | err = -ENXIO; | 274 | err = -ENXIO; |
| 276 | goto pcifail; | 275 | goto pcifail; |
| @@ -158,13 +158,13 @@ int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) · 157 unmodified lines | |||
| 158 | /* drop the original AD1888 HPF control */ | 158 | /* drop the original AD1888 HPF control */ |
| 159 | memset(&elem, 0, sizeof(elem)); | 159 | memset(&elem, 0, sizeof(elem)); |
| 160 | elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 160 | elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 161 | strlcpy(elem.name, "High Pass Filter Enable", sizeof(elem.name)); | 161 | strscpy(elem.name, "High Pass Filter Enable", sizeof(elem.name)); |
| 162 | snd_ctl_remove_id(card, &elem); | 162 | snd_ctl_remove_id(card, &elem); |
| 163 | 163 | ||
| 164 | /* drop the original V_REFOUT control */ | 164 | /* drop the original V_REFOUT control */ |
| 165 | memset(&elem, 0, sizeof(elem)); | 165 | memset(&elem, 0, sizeof(elem)); |
| 166 | elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 166 | elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 167 | strlcpy(elem.name, "V_REFOUT Enable", sizeof(elem.name)); | 167 | strscpy(elem.name, "V_REFOUT Enable", sizeof(elem.name)); |
| 168 | snd_ctl_remove_id(card, &elem); | 168 | snd_ctl_remove_id(card, &elem); |
| 169 | 169 | ||
| 170 | /* add the OLPC-specific controls */ | 170 | /* add the OLPC-specific controls */ |
| @@ -1901,12 +1901,8 @@ static int hw_card_start(struct hw *hw) · 1900 unmodified lines | |||
| 1901 | return err; | 1901 | return err; |
| 1902 | 1902 | ||
| 1903 | /* Set DMA transfer mask */ | 1903 | /* Set DMA transfer mask */ |
| 1904 | if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | 1904 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) |
| 1905 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | 1905 | dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); |
| 1906 | } else { | ||
| 1907 | dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 1908 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 1909 | } | ||
| 1910 | 1906 | ||
| 1911 | if (!hw->io_base) { | 1907 | if (!hw->io_base) { |
| 1912 | err = pci_request_regions(pci, "XFi"); | 1908 | err = pci_request_regions(pci, "XFi"); |
| @@ -2026,12 +2026,8 @@ static int hw_card_start(struct hw *hw) · 2025 unmodified lines | |||
| 2026 | return err; | 2026 | return err; |
| 2027 | 2027 | ||
| 2028 | /* Set DMA transfer mask */ | 2028 | /* Set DMA transfer mask */ |
| 2029 | if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | 2029 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) |
| 2030 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | 2030 | dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); |
| 2031 | } else { | ||
| 2032 | dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 2033 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 2034 | } | ||
| 2035 | 2031 | ||
| 2036 | if (!hw->io_base) { | 2032 | if (!hw->io_base) { |
| 2037 | err = pci_request_regions(pci, "XFi"); | 2033 | err = pci_request_regions(pci, "XFi"); |
| @@ -433,7 +433,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc, · 432 unmodified lines | |||
| 433 | pcm->private_data = atc; | 433 | pcm->private_data = atc; |
| 434 | pcm->info_flags = 0; | 434 | pcm->info_flags = 0; |
| 435 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; | 435 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; |
| 436 | strlcpy(pcm->name, device_name, sizeof(pcm->name)); | 436 | strscpy(pcm->name, device_name, sizeof(pcm->name)); |
| 437 | 437 | ||
| 438 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); | 438 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); |
| 439 | 439 | ||
| @@ -209,7 +209,7 @@ int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type, · 208 unmodified lines | |||
| 209 | 209 | ||
| 210 | mgr->type = NUM_RSCTYP; | 210 | mgr->type = NUM_RSCTYP; |
| 211 | 211 | ||
| 212 | mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL); | 212 | mgr->rscs = kzalloc(DIV_ROUND_UP(amount, 8), GFP_KERNEL); |
| 213 | if (!mgr->rscs) | 213 | if (!mgr->rscs) |
| 214 | return -ENOMEM; | 214 | return -ENOMEM; |
| 215 | 215 | ||
| @@ -168,9 +168,9 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci, · 167 unmodified lines | |||
| 168 | } | 168 | } |
| 169 | #endif | 169 | #endif |
| 170 | 170 | ||
| 171 | strlcpy(card->driver, emu->card_capabilities->driver, | 171 | strscpy(card->driver, emu->card_capabilities->driver, |
| 172 | sizeof(card->driver)); | 172 | sizeof(card->driver)); |
| 173 | strlcpy(card->shortname, emu->card_capabilities->name, | 173 | strscpy(card->shortname, emu->card_capabilities->name, |
| 174 | sizeof(card->shortname)); | 174 | sizeof(card->shortname)); |
| 175 | snprintf(card->longname, sizeof(card->longname), | 175 | snprintf(card->longname, sizeof(card->longname), |
| 176 | "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", | 176 | "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", |
| @@ -1869,7 +1869,7 @@ int snd_emu10k1_create(struct snd_card *card, · 1868 unmodified lines | |||
| 1869 | emu->serial); | 1869 | emu->serial); |
| 1870 | 1870 | ||
| 1871 | if (!*card->id && c->id) | 1871 | if (!*card->id && c->id) |
| 1872 | strlcpy(card->id, c->id, sizeof(card->id)); | 1872 | strscpy(card->id, c->id, sizeof(card->id)); |
| 1873 | 1873 | ||
| 1874 | is_audigy = emu->audigy = c->emu10k2_chip; | 1874 | is_audigy = emu->audigy = c->emu10k2_chip; |
| 1875 | 1875 | ||
| @@ -940,7 +940,7 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, · 939 unmodified lines | |||
| 940 | memset(gctl, 0, sizeof(*gctl)); | 940 | memset(gctl, 0, sizeof(*gctl)); |
| 941 | id = &ctl->kcontrol->id; | 941 | id = &ctl->kcontrol->id; |
| 942 | gctl->id.iface = (__force int)id->iface; | 942 | gctl->id.iface = (__force int)id->iface; |
| 943 | strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name)); | 943 | strscpy(gctl->id.name, id->name, sizeof(gctl->id.name)); |
| 944 | gctl->id.index = id->index; | 944 | gctl->id.index = id->index; |
| 945 | gctl->id.device = id->device; | 945 | gctl->id.device = id->device; |
| 946 | gctl->id.subdevice = id->subdevice; | 946 | gctl->id.subdevice = id->subdevice; |
| @@ -976,7 +976,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, · 29 unmodified lines | |||
| 976 | err = snd_emu10k1_verify_controls(emu, icode, in_kernel); | 976 | err = snd_emu10k1_verify_controls(emu, icode, in_kernel); |
| 977 | if (err < 0) | 977 | if (err < 0) |
| 978 | goto __error; | 978 | goto __error; |
| 979 | strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); | 979 | strscpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); |
| 980 | /* stop FX processor - this may be dangerous, but it's better to miss | 980 | /* stop FX processor - this may be dangerous, but it's better to miss |
| 981 | some samples than generate wrong ones - [jk] */ | 981 | some samples than generate wrong ones - [jk] */ |
| 982 | if (emu->audigy) | 982 | if (emu->audigy) |
| @@ -1015,7 +1015,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, · 32 unmodified lines | |||
| 1015 | int err; | 1015 | int err; |
| 1016 | 1016 | ||
| 1017 | mutex_lock(&emu->fx8010.lock); | 1017 | mutex_lock(&emu->fx8010.lock); |
| 1018 | strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name)); | 1018 | strscpy(icode->name, emu->fx8010.name, sizeof(icode->name)); |
| 1019 | /* ok, do the main job */ | 1019 | /* ok, do the main job */ |
| 1020 | err = snd_emu10k1_gpr_peek(emu, icode); | 1020 | err = snd_emu10k1_gpr_peek(emu, icode); |
| 1021 | if (err >= 0) | 1021 | if (err >= 0) |
| @@ -375,7 +375,7 @@ int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size, · 374 unmodified lines | |||
| 375 | struct snd_dma_buffer *dmab) | 375 | struct snd_dma_buffer *dmab) |
| 376 | { | 376 | { |
| 377 | if (emu->iommu_workaround) { | 377 | if (emu->iommu_workaround) { |
| 378 | size_t npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; | 378 | size_t npages = DIV_ROUND_UP(size, PAGE_SIZE); |
| 379 | size_t size_real = npages * PAGE_SIZE; | 379 | size_t size_real = npages * PAGE_SIZE; |
| 380 | 380 | ||
| 381 | /* | 381 | /* |
| @@ -752,7 +752,7 @@ static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) · 751 unmodified lines | |||
| 752 | unsigned int freq, r; | 752 | unsigned int freq, r; |
| 753 | 753 | ||
| 754 | mutex_lock(&ensoniq->src_mutex); | 754 | mutex_lock(&ensoniq->src_mutex); |
| 755 | freq = ((rate << 15) + 1500) / 3000; | 755 | freq = DIV_ROUND_CLOSEST(rate << 15, 3000); |
| 756 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 756 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
| 757 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | | 757 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | |
| 758 | ES_1371_DIS_P1; | 758 | ES_1371_DIS_P1; |
| @@ -773,7 +773,7 @@ static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) · 14 unmodified lines | |||
| 773 | unsigned int freq, r; | 773 | unsigned int freq, r; |
| 774 | 774 | ||
| 775 | mutex_lock(&ensoniq->src_mutex); | 775 | mutex_lock(&ensoniq->src_mutex); |
| 776 | freq = ((rate << 15) + 1500) / 3000; | 776 | freq = DIV_ROUND_CLOSEST(rate << 15, 3000); |
| 777 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 777 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
| 778 | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | | 778 | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | |
| 779 | ES_1371_DIS_P2; | 779 | ES_1371_DIS_P2; |
| @@ -1560,8 +1560,7 @@ static int snd_es1938_create(struct snd_card *card, · 1559 unmodified lines | |||
| 1560 | if ((err = pci_enable_device(pci)) < 0) | 1560 | if ((err = pci_enable_device(pci)) < 0) |
| 1561 | return err; | 1561 | return err; |
| 1562 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 1562 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 1563 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | 1563 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { |
| 1564 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | ||
| 1565 | dev_err(card->dev, | 1564 | dev_err(card->dev, |
| 1566 | "architecture does not support 24bit PCI busmaster DMA\n"); | 1565 | "architecture does not support 24bit PCI busmaster DMA\n"); |
| 1567 | pci_disable_device(pci); | 1566 | pci_disable_device(pci); |
| @@ -2668,8 +2668,7 @@ static int snd_es1968_create(struct snd_card *card, · 2667 unmodified lines | |||
| 2668 | if ((err = pci_enable_device(pci)) < 0) | 2668 | if ((err = pci_enable_device(pci)) < 0) |
| 2669 | return err; | 2669 | return err; |
| 2670 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2670 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2671 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | 2671 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { |
| 2672 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | ||
| 2673 | dev_err(card->dev, | 2672 | dev_err(card->dev, |
| 2674 | "architecture does not support 28bit PCI busmaster DMA\n"); | 2673 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2675 | pci_disable_device(pci); | 2674 | pci_disable_device(pci); |
| @@ -2768,7 +2767,7 @@ static int snd_es1968_create(struct snd_card *card, · 92 unmodified lines | |||
| 2768 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { | 2767 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
| 2769 | dev_info(card->dev, "detected TEA575x radio type %s\n", | 2768 | dev_info(card->dev, "detected TEA575x radio type %s\n", |
| 2770 | get_tea575x_gpio(chip)->name); | 2769 | get_tea575x_gpio(chip)->name); |
| 2771 | strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, | 2770 | strscpy(chip->tea.card, get_tea575x_gpio(chip)->name, |
| 2772 | sizeof(chip->tea.card)); | 2771 | sizeof(chip->tea.card)); |
| 2773 | break; | 2772 | break; |
| 2774 | } | 2773 | } |
| @@ -1300,7 +1300,7 @@ static int snd_fm801_create(struct snd_card *card, · 1299 unmodified lines | |||
| 1300 | chip->tea575x_tuner |= tuner_only; | 1300 | chip->tea575x_tuner |= tuner_only; |
| 1301 | } | 1301 | } |
| 1302 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) { | 1302 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) { |
| 1303 | strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, | 1303 | strscpy(chip->tea.card, get_tea575x_gpio(chip)->name, |
| 1304 | sizeof(chip->tea.card)); | 1304 | sizeof(chip->tea.card)); |
| 1305 | } | 1305 | } |
| 1306 | #endif | 1306 | #endif |
| @@ -764,7 +764,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, · 763 unmodified lines | |||
| 764 | } | 764 | } |
| 765 | if (!name) | 765 | if (!name) |
| 766 | return 0; | 766 | return 0; |
| 767 | strlcpy(label, name, maxlen); | 767 | strscpy(label, name, maxlen); |
| 768 | return 1; | 768 | return 1; |
| 769 | } | 769 | } |
| 770 | EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); | 770 | EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); |
| @@ -3999,7 +3999,7 @@ int snd_hda_add_imux_item(struct hda_codec *codec, · 3998 unmodified lines | |||
| 3999 | sizeof(imux->items[imux->num_items].label), | 3999 | sizeof(imux->items[imux->num_items].label), |
| 4000 | "%s %d", label, label_idx); | 4000 | "%s %d", label, label_idx); |
| 4001 | else | 4001 | else |
| 4002 | strlcpy(imux->items[imux->num_items].label, label, | 4002 | strscpy(imux->items[imux->num_items].label, label, |
| 4003 | sizeof(imux->items[imux->num_items].label)); | 4003 | sizeof(imux->items[imux->num_items].label)); |
| 4004 | imux->items[imux->num_items].index = index; | 4004 | imux->items[imux->num_items].index = index; |
| 4005 | imux->num_items++; | 4005 | imux->num_items++; |
| @@ -735,7 +735,7 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec, · 734 unmodified lines | |||
| 735 | &pcm); | 735 | &pcm); |
| 736 | if (err < 0) | 736 | if (err < 0) |
| 737 | return err; | 737 | return err; |
| 738 | strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); | 738 | strscpy(pcm->name, cpcm->name, sizeof(pcm->name)); |
| 739 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); | 739 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); |
| 740 | if (apcm == NULL) { | 740 | if (apcm == NULL) { |
| 741 | snd_device_free(chip->card, pcm); | 741 | snd_device_free(chip->card, pcm); |
| @@ -260,7 +260,7 @@ int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, · 259 unmodified lines | |||
| 260 | codec_info(codec, "HDMI: out of range MNL %d\n", mnl); | 260 | codec_info(codec, "HDMI: out of range MNL %d\n", mnl); |
| 261 | goto out_fail; | 261 | goto out_fail; |
| 262 | } else | 262 | } else |
| 263 | strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); | 263 | strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); |
| 264 | 264 | ||
| 265 | for (i = 0; i < e->sad_count; i++) { | 265 | for (i = 0; i < e->sad_count; i++) { |
| 266 | if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { | 266 | if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { |
| @@ -5721,7 +5721,7 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, · 5720 unmodified lines | |||
| 5721 | 5721 | ||
| 5722 | if (*str) | 5722 | if (*str) |
| 5723 | return; | 5723 | return; |
| 5724 | strlcpy(str, chip_name, len); | 5724 | strscpy(str, chip_name, len); |
| 5725 | 5725 | ||
| 5726 | /* drop non-alnum chars after a space */ | 5726 | /* drop non-alnum chars after a space */ |
| 5727 | for (p = strchr(str, ' '); p; p = strchr(p + 1, ' ')) { | 5727 | for (p = strchr(str, ' '); p; p = strchr(p + 1, ' ')) { |
| @@ -1967,12 +1967,8 @@ static int azx_first_init(struct azx *chip) · 1966 unmodified lines | |||
| 1967 | /* allow 64bit DMA address if supported by H/W */ | 1967 | /* allow 64bit DMA address if supported by H/W */ |
| 1968 | if (!(gcap & AZX_GCAP_64OK)) | 1968 | if (!(gcap & AZX_GCAP_64OK)) |
| 1969 | dma_bits = 32; | 1969 | dma_bits = 32; |
| 1970 | if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | 1970 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) |
| 1971 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | 1971 | dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); |
| 1972 | } else { | ||
| 1973 | dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 1974 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | ||
| 1975 | } | ||
| 1976 | 1972 | ||
| 1977 | /* read number of streams from GCAP register instead of using | 1973 | /* read number of streams from GCAP register instead of using |
| 1978 | * hardcoded value | 1974 | * hardcoded value |
| @@ -2037,7 +2033,7 @@ static int azx_first_init(struct azx *chip) · 58 unmodified lines | |||
| 2037 | return -EBUSY; | 2033 | return -EBUSY; |
| 2038 | 2034 | ||
| 2039 | strcpy(card->driver, "HDA-Intel"); | 2035 | strcpy(card->driver, "HDA-Intel"); |
| 2040 | strlcpy(card->shortname, driver_short_names[chip->driver_type], | 2036 | strscpy(card->shortname, driver_short_names[chip->driver_type], |
| 2041 | sizeof(card->shortname)); | 2037 | sizeof(card->shortname)); |
| 2042 | snprintf(card->longname, sizeof(card->longname), | 2038 | snprintf(card->longname, sizeof(card->longname), |
| 2043 | "%s at 0x%lx irq %i", | 2039 | "%s at 0x%lx irq %i", |
| @@ -2221,8 +2217,6 @@ static const struct snd_pci_quirk power_save_denylist[] = { · 177 unmodified lines | |||
| 2221 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ | 2217 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2222 | SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), | 2218 | SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), |
| 2223 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ | 2219 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2224 | SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0), | ||
| 2225 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ | ||
| 2226 | SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0), | 2220 | SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0), |
| 2227 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ | 2221 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2228 | /* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */ | 2222 | /* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */ |
| @@ -2304,7 +2298,7 @@ static int azx_probe_continue(struct azx *chip) · 75 unmodified lines | |||
| 2304 | 2298 | ||
| 2305 | /* HSW/BDW controllers need this power */ | 2299 | /* HSW/BDW controllers need this power */ |
| 2306 | if (CONTROLLER_IN_GPU(pci)) | 2300 | if (CONTROLLER_IN_GPU(pci)) |
| 2307 | hda->need_i915_power = 1; | 2301 | hda->need_i915_power = true; |
| 2308 | } | 2302 | } |
| 2309 | 2303 | ||
| 2310 | /* Request display power well for the HDA controller or codec. For | 2304 | /* Request display power well for the HDA controller or codec. For |
| @@ -2481,6 +2475,8 @@ static const struct pci_device_id azx_ids[] = { · 170 unmodified lines | |||
| 2481 | /* CometLake-H */ | 2475 | /* CometLake-H */ |
| 2482 | { PCI_DEVICE(0x8086, 0x06C8), | 2476 | { PCI_DEVICE(0x8086, 0x06C8), |
| 2483 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2477 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| 2478 | { PCI_DEVICE(0x8086, 0xf1c8), | ||
| 2479 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
| 2484 | /* CometLake-S */ | 2480 | /* CometLake-S */ |
| 2485 | { PCI_DEVICE(0x8086, 0xa3f0), | 2481 | { PCI_DEVICE(0x8086, 0xa3f0), |
| 2486 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2482 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
| @@ -530,7 +530,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, · 529 unmodified lines | |||
| 530 | !is_jack_detectable(codec, nid); | 530 | !is_jack_detectable(codec, nid); |
| 531 | 531 | ||
| 532 | if (base_name) | 532 | if (base_name) |
| 533 | strlcpy(name, base_name, sizeof(name)); | 533 | strscpy(name, base_name, sizeof(name)); |
| 534 | else | 534 | else |
| 535 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL); | 535 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL); |
| 536 | if (phantom_jack) | 536 | if (phantom_jack) |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
| 18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
| 19 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
| 20 | #include <linux/reset.h> | ||
| 20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 21 | #include <linux/time.h> | 22 | #include <linux/time.h> |
| 22 | #include <linux/string.h> | 23 | #include <linux/string.h> |
| @@ -70,9 +71,9 @@ · 47 unmodified lines | |||
| 70 | struct hda_tegra { | 71 | struct hda_tegra { |
| 71 | struct azx chip; | 72 | struct azx chip; |
| 72 | struct device *dev; | 73 | struct device *dev; |
| 73 | struct clk *hda_clk; | 74 | struct reset_control *reset; |
| 74 | struct clk *hda2codec_2x_clk; | 75 | struct clk_bulk_data clocks[3]; |
| 75 | struct clk *hda2hdmi_clk; | 76 | unsigned int nclocks; |
| 76 | void __iomem *regs; | 77 | void __iomem *regs; |
| 77 | struct work_struct probe_work; | 78 | struct work_struct probe_work; |
| 78 | }; | 79 | }; |
| @@ -113,36 +114,6 @@ static void hda_tegra_init(struct hda_tegra *hda) · 34 unmodified lines | |||
| 113 | writel(v, hda->regs + HDA_IPFS_INTR_MASK); | 114 | writel(v, hda->regs + HDA_IPFS_INTR_MASK); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | static int hda_tegra_enable_clocks(struct hda_tegra *data) | ||
| 117 | { | ||
| 118 | int rc; | ||
| 119 | |||
| 120 | rc = clk_prepare_enable(data->hda_clk); | ||
| 121 | if (rc) | ||
| 122 | return rc; | ||
| 123 | rc = clk_prepare_enable(data->hda2codec_2x_clk); | ||
| 124 | if (rc) | ||
| 125 | goto disable_hda; | ||
| 126 | rc = clk_prepare_enable(data->hda2hdmi_clk); | ||
| 127 | if (rc) | ||
| 128 | goto disable_codec_2x; | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | |||
| 132 | disable_codec_2x: | ||
| 133 | clk_disable_unprepare(data->hda2codec_2x_clk); | ||
| 134 | disable_hda: | ||
| 135 | clk_disable_unprepare(data->hda_clk); | ||
| 136 | return rc; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void hda_tegra_disable_clocks(struct hda_tegra *data) | ||
| 140 | { | ||
| 141 | clk_disable_unprepare(data->hda2hdmi_clk); | ||
| 142 | clk_disable_unprepare(data->hda2codec_2x_clk); | ||
| 143 | clk_disable_unprepare(data->hda_clk); | ||
| 144 | } | ||
| 145 | |||
| 146 | /* | 117 | /* |
| 147 | * power management | 118 | * power management |
| 148 | */ | 119 | */ |
| @@ -186,7 +157,7 @@ static int __maybe_unused hda_tegra_runtime_suspend(struct device *dev) · 37 unmodified lines | |||
| 186 | azx_stop_chip(chip); | 157 | azx_stop_chip(chip); |
| 187 | azx_enter_link_reset(chip); | 158 | azx_enter_link_reset(chip); |
| 188 | } | 159 | } |
| 189 | hda_tegra_disable_clocks(hda); | 160 | clk_bulk_disable_unprepare(hda->nclocks, hda->clocks); |
| 190 | 161 | ||
| 191 | return 0; | 162 | return 0; |
| 192 | } | 163 | } |
| @@ -198,15 +169,27 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) · 5 unmodified lines | |||
| 198 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | 169 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); |
| 199 | int rc; | 170 | int rc; |
| 200 | 171 | ||
| 201 | rc = hda_tegra_enable_clocks(hda); | 172 | if (!chip->running) { |
| 173 | rc = reset_control_assert(hda->reset); | ||
| 174 | if (rc) | ||
| 175 | return rc; | ||
| 176 | } | ||
| 177 | |||
| 178 | rc = clk_bulk_prepare_enable(hda->nclocks, hda->clocks); | ||
| 202 | if (rc != 0) | 179 | if (rc != 0) |
| 203 | return rc; | 180 | return rc; |
| 204 | if (chip && chip->running) { | 181 | if (chip->running) { |
| 205 | hda_tegra_init(hda); | 182 | hda_tegra_init(hda); |
| 206 | azx_init_chip(chip, 1); | 183 | azx_init_chip(chip, 1); |
| 207 | /* disable controller wake up event*/ | 184 | /* disable controller wake up event*/ |
| 208 | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & | 185 | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & |
| 209 | ~STATESTS_INT_MASK); | 186 | ~STATESTS_INT_MASK); |
| 187 | } else { | ||
| 188 | usleep_range(10, 100); | ||
| 189 | |||
| 190 | rc = reset_control_deassert(hda->reset); | ||
| 191 | if (rc) | ||
| 192 | return rc; | ||
| 210 | } | 193 | } |
| 211 | 194 | ||
| 212 | return 0; | 195 | return 0; |
| @@ -268,29 +251,6 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) · 55 unmodified lines | |||
| 268 | return 0; | 251 | return 0; |
| 269 | } | 252 | } |
| 270 | 253 | ||
| 271 | static int hda_tegra_init_clk(struct hda_tegra *hda) | ||
| 272 | { | ||
| 273 | struct device *dev = hda->dev; | ||
| 274 | |||
| 275 | hda->hda_clk = devm_clk_get(dev, "hda"); | ||
| 276 | if (IS_ERR(hda->hda_clk)) { | ||
| 277 | dev_err(dev, "failed to get hda clock\n"); | ||
| 278 | return PTR_ERR(hda->hda_clk); | ||
| 279 | } | ||
| 280 | hda->hda2codec_2x_clk = devm_clk_get(dev, "hda2codec_2x"); | ||
| 281 | if (IS_ERR(hda->hda2codec_2x_clk)) { | ||
| 282 | dev_err(dev, "failed to get hda2codec_2x clock\n"); | ||
| 283 | return PTR_ERR(hda->hda2codec_2x_clk); | ||
| 284 | } | ||
| 285 | hda->hda2hdmi_clk = devm_clk_get(dev, "hda2hdmi"); | ||
| 286 | if (IS_ERR(hda->hda2hdmi_clk)) { | ||
| 287 | dev_err(dev, "failed to get hda2hdmi clock\n"); | ||
| 288 | return PTR_ERR(hda->hda2hdmi_clk); | ||
| 289 | } | ||
| 290 | |||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | |||
| 294 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) | 254 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) |
| 295 | { | 255 | { |
| 296 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | 256 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); |
| @@ -495,7 +455,17 @@ static int hda_tegra_probe(struct platform_device *pdev) · 198 unmodified lines | |||
| 495 | return err; | 455 | return err; |
| 496 | } | 456 | } |
| 497 | 457 | ||
| 498 | err = hda_tegra_init_clk(hda); | 458 | hda->reset = devm_reset_control_array_get_exclusive(&pdev->dev); |
| 459 | if (IS_ERR(hda->reset)) { | ||
| 460 | err = PTR_ERR(hda->reset); | ||
| 461 | goto out_free; | ||
| 462 | } | ||
| 463 | |||
| 464 | hda->clocks[hda->nclocks++].id = "hda"; | ||
| 465 | hda->clocks[hda->nclocks++].id = "hda2hdmi"; | ||
| 466 | hda->clocks[hda->nclocks++].id = "hda2codec_2x"; | ||
| 467 | |||
| 468 | err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); | ||
| 499 | if (err < 0) | 469 | if (err < 0) |
| 500 | goto out_free; | 470 | goto out_free; |
| 501 | 471 | ||
| @@ -567,7 +567,7 @@ static void cxt_fixup_mute_led_eapd(struct hda_codec *codec, · 566 unmodified lines | |||
| 567 | 567 | ||
| 568 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 568 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
| 569 | spec->mute_led_eapd = 0x1b; | 569 | spec->mute_led_eapd = 0x1b; |
| 570 | spec->dynamic_eapd = 1; | 570 | spec->dynamic_eapd = true; |
| 571 | snd_hda_gen_add_mute_led_cdev(codec, cx_auto_vmaster_mute_led); | 571 | snd_hda_gen_add_mute_led_cdev(codec, cx_auto_vmaster_mute_led); |
| 572 | } | 572 | } |
| 573 | } | 573 | } |
| @@ -2130,7 +2130,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 2129 unmodified lines | |||
| 2130 | goto unlock; | 2130 | goto unlock; |
| 2131 | } | 2131 | } |
| 2132 | per_cvt = get_cvt(spec, cvt_idx); | 2132 | per_cvt = get_cvt(spec, cvt_idx); |
| 2133 | snd_BUG_ON(!per_cvt->assigned); | ||
| 2134 | per_cvt->assigned = 0; | 2133 | per_cvt->assigned = 0; |
| 2135 | hinfo->nid = 0; | 2134 | hinfo->nid = 0; |
| 2136 | 2135 | ||
| @@ -1905,6 +1905,7 @@ enum { · 1904 unmodified lines | |||
| 1905 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, | 1905 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, |
| 1906 | ALC889_FIXUP_VAIO_TT, | 1906 | ALC889_FIXUP_VAIO_TT, |
| 1907 | ALC888_FIXUP_EEE1601, | 1907 | ALC888_FIXUP_EEE1601, |
| 1908 | ALC886_FIXUP_EAPD, | ||
| 1908 | ALC882_FIXUP_EAPD, | 1909 | ALC882_FIXUP_EAPD, |
| 1909 | ALC883_FIXUP_EAPD, | 1910 | ALC883_FIXUP_EAPD, |
| 1910 | ALC883_FIXUP_ACER_EAPD, | 1911 | ALC883_FIXUP_ACER_EAPD, |
| @@ -2238,6 +2239,15 @@ static const struct hda_fixup alc882_fixups[] = { · 327 unmodified lines | |||
| 2238 | { } | 2239 | { } |
| 2239 | } | 2240 | } |
| 2240 | }, | 2241 | }, |
| 2242 | [ALC886_FIXUP_EAPD] = { | ||
| 2243 | .type = HDA_FIXUP_VERBS, | ||
| 2244 | .v.verbs = (const struct hda_verb[]) { | ||
| 2245 | /* change to EAPD mode */ | ||
| 2246 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
| 2247 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0068 }, | ||
| 2248 | { } | ||
| 2249 | } | ||
| 2250 | }, | ||
| 2241 | [ALC882_FIXUP_EAPD] = { | 2251 | [ALC882_FIXUP_EAPD] = { |
| 2242 | .type = HDA_FIXUP_VERBS, | 2252 | .type = HDA_FIXUP_VERBS, |
| 2243 | .v.verbs = (const struct hda_verb[]) { | 2253 | .v.verbs = (const struct hda_verb[]) { |
| @@ -2510,6 +2520,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 266 unmodified lines | |||
| 2510 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), | 2520 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), |
| 2511 | 2521 | ||
| 2512 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | 2522 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
| 2523 | SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD), | ||
| 2513 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), | 2524 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
| 2514 | SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), | 2525 | SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), |
| 2515 | SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), | 2526 | SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), |
| @@ -4280,6 +4291,28 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, · 1764 unmodified lines | |||
| 4280 | } | 4291 | } |
| 4281 | } | 4292 | } |
| 4282 | 4293 | ||
| 4294 | /* HP Spectre x360 14 model needs a unique workaround for enabling the amp; | ||
| 4295 | * it needs to toggle the GPIO0 once on and off at each time (bko#210633) | ||
| 4296 | */ | ||
| 4297 | static void alc245_fixup_hp_x360_amp(struct hda_codec *codec, | ||
| 4298 | const struct hda_fixup *fix, int action) | ||
| 4299 | { | ||
| 4300 | struct alc_spec *spec = codec->spec; | ||
| 4301 | |||
| 4302 | switch (action) { | ||
| 4303 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
| 4304 | spec->gpio_mask |= 0x01; | ||
| 4305 | spec->gpio_dir |= 0x01; | ||
| 4306 | break; | ||
| 4307 | case HDA_FIXUP_ACT_INIT: | ||
| 4308 | /* need to toggle GPIO to enable the amp */ | ||
| 4309 | alc_update_gpio_data(codec, 0x01, true); | ||
| 4310 | msleep(100); | ||
| 4311 | alc_update_gpio_data(codec, 0x01, false); | ||
| 4312 | break; | ||
| 4313 | } | ||
| 4314 | } | ||
| 4315 | |||
| 4283 | static void alc_update_coef_led(struct hda_codec *codec, | 4316 | static void alc_update_coef_led(struct hda_codec *codec, |
| 4284 | struct alc_coef_led *led, | 4317 | struct alc_coef_led *led, |
| 4285 | bool polarity, bool on) | 4318 | bool polarity, bool on) |
| @@ -6266,6 +6299,7 @@ enum { · 1980 unmodified lines | |||
| 6266 | ALC280_FIXUP_HP_DOCK_PINS, | 6299 | ALC280_FIXUP_HP_DOCK_PINS, |
| 6267 | ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, | 6300 | ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, |
| 6268 | ALC280_FIXUP_HP_9480M, | 6301 | ALC280_FIXUP_HP_9480M, |
| 6302 | ALC245_FIXUP_HP_X360_AMP, | ||
| 6269 | ALC288_FIXUP_DELL_HEADSET_MODE, | 6303 | ALC288_FIXUP_DELL_HEADSET_MODE, |
| 6270 | ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, | 6304 | ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, |
| 6271 | ALC288_FIXUP_DELL_XPS_13, | 6305 | ALC288_FIXUP_DELL_XPS_13, |
| @@ -6971,6 +7005,10 @@ static const struct hda_fixup alc269_fixups[] = { · 699 unmodified lines | |||
| 6971 | .type = HDA_FIXUP_FUNC, | 7005 | .type = HDA_FIXUP_FUNC, |
| 6972 | .v.func = alc280_fixup_hp_9480m, | 7006 | .v.func = alc280_fixup_hp_9480m, |
| 6973 | }, | 7007 | }, |
| 7008 | [ALC245_FIXUP_HP_X360_AMP] = { | ||
| 7009 | .type = HDA_FIXUP_FUNC, | ||
| 7010 | .v.func = alc245_fixup_hp_x360_amp, | ||
| 7011 | }, | ||
| 6974 | [ALC288_FIXUP_DELL_HEADSET_MODE] = { | 7012 | [ALC288_FIXUP_DELL_HEADSET_MODE] = { |
| 6975 | .type = HDA_FIXUP_FUNC, | 7013 | .type = HDA_FIXUP_FUNC, |
| 6976 | .v.func = alc_fixup_headset_mode_dell_alc288, | 7014 | .v.func = alc_fixup_headset_mode_dell_alc288, |
| @@ -7985,6 +8023,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 1008 unmodified lines | |||
| 7985 | SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), | 8023 | SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 7986 | SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), | 8024 | SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 7987 | SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), | 8025 | SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 8026 | SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), | ||
| 7988 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), | 8027 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
| 7989 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 8028 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
| 7990 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 8029 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| @@ -8357,6 +8396,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { · 366 unmodified lines | |||
| 8357 | {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"}, | 8396 | {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"}, |
| 8358 | {.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"}, | 8397 | {.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"}, |
| 8359 | {.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"}, | 8398 | {.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"}, |
| 8399 | {.id = ALC245_FIXUP_HP_X360_AMP, .name = "alc245-hp-x360-amp"}, | ||
| 8360 | {} | 8400 | {} |
| 8361 | }; | 8401 | }; |
| 8362 | #define ALC225_STANDARD_PINS \ | 8402 | #define ALC225_STANDARD_PINS \ |
| @@ -2486,8 +2486,7 @@ static int snd_ice1712_create(struct snd_card *card, · 2485 unmodified lines | |||
| 2486 | if (err < 0) | 2486 | if (err < 0) |
| 2487 | return err; | 2487 | return err; |
| 2488 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2488 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2489 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | 2489 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { |
| 2490 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | ||
| 2491 | dev_err(card->dev, | 2490 | dev_err(card->dev, |
| 2492 | "architecture does not support 28bit PCI busmaster DMA\n"); | 2491 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2493 | pci_disable_device(pci); | 2492 | pci_disable_device(pci); |
| @@ -413,7 +413,7 @@ static struct snd_kcontrol *ctl_find(struct snd_card *card, · 412 unmodified lines | |||
| 413 | { | 413 | { |
| 414 | struct snd_ctl_elem_id sid = {0}; | 414 | struct snd_ctl_elem_id sid = {0}; |
| 415 | 415 | ||
| 416 | strlcpy(sid.name, name, sizeof(sid.name)); | 416 | strscpy(sid.name, name, sizeof(sid.name)); |
| 417 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 417 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 418 | return snd_ctl_find_id(card, &sid); | 418 | return snd_ctl_find_id(card, &sid); |
| 419 | } | 419 | } |
| @@ -189,12 +189,12 @@ static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected) · 188 unmodified lines | |||
| 189 | /* notify about master speaker mute change */ | 189 | /* notify about master speaker mute change */ |
| 190 | memset(&elem_id, 0, sizeof(elem_id)); | 190 | memset(&elem_id, 0, sizeof(elem_id)); |
| 191 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 191 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 192 | strlcpy(elem_id.name, "Master Speakers Playback Switch", | 192 | strscpy(elem_id.name, "Master Speakers Playback Switch", |
| 193 | sizeof(elem_id.name)); | 193 | sizeof(elem_id.name)); |
| 194 | kctl = snd_ctl_find_id(ice->card, &elem_id); | 194 | kctl = snd_ctl_find_id(ice->card, &elem_id); |
| 195 | snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); | 195 | snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
| 196 | /* and headphone mute change */ | 196 | /* and headphone mute change */ |
| 197 | strlcpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name, | 197 | strscpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name, |
| 198 | sizeof(elem_id.name)); | 198 | sizeof(elem_id.name)); |
| 199 | kctl = snd_ctl_find_id(ice->card, &elem_id); | 199 | kctl = snd_ctl_find_id(ice->card, &elem_id); |
| 200 | snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); | 200 | snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
| @@ -771,7 +771,7 @@ static struct snd_kcontrol *ctl_find(struct snd_card *card, · 770 unmodified lines | |||
| 771 | { | 771 | { |
| 772 | struct snd_ctl_elem_id sid = {0}; | 772 | struct snd_ctl_elem_id sid = {0}; |
| 773 | 773 | ||
| 774 | strlcpy(sid.name, name, sizeof(sid.name)); | 774 | strscpy(sid.name, name, sizeof(sid.name)); |
| 775 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 775 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 776 | return snd_ctl_find_id(card, &sid); | 776 | return snd_ctl_find_id(card, &sid); |
| 777 | } | 777 | } |
| @@ -38,7 +38,7 @@ static void snd_wm8776_activate_ctl(struct snd_wm8776 *wm, · 37 unmodified lines | |||
| 38 | unsigned int index_offset; | 38 | unsigned int index_offset; |
| 39 | 39 | ||
| 40 | memset(&elem_id, 0, sizeof(elem_id)); | 40 | memset(&elem_id, 0, sizeof(elem_id)); |
| 41 | strlcpy(elem_id.name, ctl_name, sizeof(elem_id.name)); | 41 | strscpy(elem_id.name, ctl_name, sizeof(elem_id.name)); |
| 42 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 42 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 43 | kctl = snd_ctl_find_id(card, &elem_id); | 43 | kctl = snd_ctl_find_id(card, &elem_id); |
| 44 | if (!kctl) | 44 | if (!kctl) |
| @@ -1129,13 +1129,14 @@ static int snd_intel8x0m_create(struct snd_card *card, · 1128 unmodified lines | |||
| 1129 | chip->bmaddr = pci_iomap(pci, 3, 0); | 1129 | chip->bmaddr = pci_iomap(pci, 3, 0); |
| 1130 | else | 1130 | else |
| 1131 | chip->bmaddr = pci_iomap(pci, 1, 0); | 1131 | chip->bmaddr = pci_iomap(pci, 1, 0); |
| 1132 | |||
| 1133 | port_inited: | ||
| 1132 | if (!chip->bmaddr) { | 1134 | if (!chip->bmaddr) { |
| 1133 | dev_err(card->dev, "Controller space ioremap problem\n"); | 1135 | dev_err(card->dev, "Controller space ioremap problem\n"); |
| 1134 | snd_intel8x0m_free(chip); | 1136 | snd_intel8x0m_free(chip); |
| 1135 | return -EIO; | 1137 | return -EIO; |
| 1136 | } | 1138 | } |
| 1137 | 1139 | ||
| 1138 | port_inited: | ||
| 1139 | /* initialize offsets */ | 1140 | /* initialize offsets */ |
| 1140 | chip->bdbars_count = 2; | 1141 | chip->bdbars_count = 2; |
| 1141 | tbl = intel_regs; | 1142 | tbl = intel_regs; |
| @@ -669,7 +669,7 @@ static int lola_create(struct snd_card *card, struct pci_dev *pci, · 668 unmodified lines | |||
| 669 | } | 669 | } |
| 670 | 670 | ||
| 671 | strcpy(card->driver, "Lola"); | 671 | strcpy(card->driver, "Lola"); |
| 672 | strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); | 672 | strscpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); |
| 673 | snprintf(card->longname, sizeof(card->longname), | 673 | snprintf(card->longname, sizeof(card->longname), |
| 674 | "%s at 0x%lx irq %i", | 674 | "%s at 0x%lx irq %i", |
| 675 | card->shortname, chip->bar[0].addr, chip->irq); | 675 | card->shortname, chip->bar[0].addr, chip->irq); |
| @@ -135,7 +135,7 @@ int lola_init_clock_widget(struct lola *chip, int nid) · 134 unmodified lines | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | nitems = chip->clock.items; | 137 | nitems = chip->clock.items; |
| 138 | nb_verbs = (nitems + 3) / 4; | 138 | nb_verbs = DIV_ROUND_UP(nitems, 4); |
| 139 | idx = 0; | 139 | idx = 0; |
| 140 | idx_list = 0; | 140 | idx_list = 0; |
| 141 | for (i = 0; i < nb_verbs; i++) { | 141 | for (i = 0; i < nb_verbs; i++) { |
| @@ -601,7 +601,7 @@ int lola_create_pcm(struct lola *chip) · 600 unmodified lines | |||
| 601 | &pcm); | 601 | &pcm); |
| 602 | if (err < 0) | 602 | if (err < 0) |
| 603 | return err; | 603 | return err; |
| 604 | strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name)); | 604 | strscpy(pcm->name, "Digigram Lola", sizeof(pcm->name)); |
| 605 | pcm->private_data = chip; | 605 | pcm->private_data = chip; |
| 606 | for (i = 0; i < 2; i++) { | 606 | for (i = 0; i < 2; i++) { |
| 607 | if (chip->pcm[i].num_streams) | 607 | if (chip->pcm[i].num_streams) |
| @@ -1245,7 +1245,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s, · 1244 unmodified lines | |||
| 1245 | snd_pcm_format_width(runtime->format) == 16 ? 0 : 1); | 1245 | snd_pcm_format_width(runtime->format) == 16 ? 0 : 1); |
| 1246 | 1246 | ||
| 1247 | /* set up dac/adc rate */ | 1247 | /* set up dac/adc rate */ |
| 1248 | freq = ((runtime->rate << 15) + 24000 ) / 48000; | 1248 | freq = DIV_ROUND_CLOSEST(runtime->rate << 15, 48000); |
| 1249 | if (freq) | 1249 | if (freq) |
| 1250 | freq--; | 1250 | freq--; |
| 1251 | 1251 | ||
| @@ -2532,8 +2532,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, · 1280 unmodified lines | |||
| 2532 | return -EIO; | 2532 | return -EIO; |
| 2533 | 2533 | ||
| 2534 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2534 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2535 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | 2535 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { |
| 2536 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | ||
| 2537 | dev_err(card->dev, | 2536 | dev_err(card->dev, |
| 2538 | "architecture does not support 28bit PCI busmaster DMA\n"); | 2537 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2539 | pci_disable_device(pci); | 2538 | pci_disable_device(pci); |
| @@ -469,6 +469,7 @@ struct hdsp { · 468 unmodified lines | |||
| 469 | unsigned char qs_out_channels; | 469 | unsigned char qs_out_channels; |
| 470 | unsigned char ds_out_channels; | 470 | unsigned char ds_out_channels; |
| 471 | unsigned char ss_out_channels; | 471 | unsigned char ss_out_channels; |
| 472 | u32 io_loopback; /* output loopback channel states*/ | ||
| 472 | 473 | ||
| 473 | struct snd_dma_buffer capture_dma_buf; | 474 | struct snd_dma_buffer capture_dma_buf; |
| 474 | struct snd_dma_buffer playback_dma_buf; | 475 | struct snd_dma_buffer playback_dma_buf; |
| @@ -3253,6 +3254,60 @@ static const struct snd_kcontrol_new snd_hdsp_96xx_aeb = · 2778 unmodified lines | |||
| 3253 | HDSP_AnalogExtensionBoard); | 3254 | HDSP_AnalogExtensionBoard); |
| 3254 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; | 3255 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; |
| 3255 | 3256 | ||
| 3257 | |||
| 3258 | static bool hdsp_loopback_get(struct hdsp *const hdsp, const u8 channel) | ||
| 3259 | { | ||
| 3260 | return hdsp->io_loopback & (1 << channel); | ||
| 3261 | } | ||
| 3262 | |||
| 3263 | static int hdsp_loopback_set(struct hdsp *const hdsp, const u8 channel, const bool enable) | ||
| 3264 | { | ||
| 3265 | if (hdsp_loopback_get(hdsp, channel) == enable) | ||
| 3266 | return 0; | ||
| 3267 | |||
| 3268 | hdsp->io_loopback ^= (1 << channel); | ||
| 3269 | |||
| 3270 | hdsp_write(hdsp, HDSP_inputEnable + (4 * (hdsp->max_channels + channel)), enable); | ||
| 3271 | |||
| 3272 | return 1; | ||
| 3273 | } | ||
| 3274 | |||
| 3275 | static int snd_hdsp_loopback_get(struct snd_kcontrol *const kcontrol, | ||
| 3276 | struct snd_ctl_elem_value *const ucontrol) | ||
| 3277 | { | ||
| 3278 | struct hdsp *const hdsp = snd_kcontrol_chip(kcontrol); | ||
| 3279 | const u8 channel = snd_ctl_get_ioff(kcontrol, &ucontrol->id); | ||
| 3280 | |||
| 3281 | if (channel >= hdsp->max_channels) | ||
| 3282 | return -ENOENT; | ||
| 3283 | |||
| 3284 | ucontrol->value.integer.value[0] = hdsp_loopback_get(hdsp, channel); | ||
| 3285 | |||
| 3286 | return 0; | ||
| 3287 | } | ||
| 3288 | |||
| 3289 | static int snd_hdsp_loopback_put(struct snd_kcontrol *const kcontrol, | ||
| 3290 | struct snd_ctl_elem_value *const ucontrol) | ||
| 3291 | { | ||
| 3292 | struct hdsp *const hdsp = snd_kcontrol_chip(kcontrol); | ||
| 3293 | const u8 channel = snd_ctl_get_ioff(kcontrol, &ucontrol->id); | ||
| 3294 | const bool enable = ucontrol->value.integer.value[0] & 1; | ||
| 3295 | |||
| 3296 | if (channel >= hdsp->max_channels) | ||
| 3297 | return -ENOENT; | ||
| 3298 | |||
| 3299 | return hdsp_loopback_set(hdsp, channel, enable); | ||
| 3300 | } | ||
| 3301 | |||
| 3302 | static struct snd_kcontrol_new snd_hdsp_loopback_control = { | ||
| 3303 | .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, | ||
| 3304 | .name = "Output Loopback", | ||
| 3305 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
| 3306 | .info = snd_ctl_boolean_mono_info, | ||
| 3307 | .get = snd_hdsp_loopback_get, | ||
| 3308 | .put = snd_hdsp_loopback_put | ||
| 3309 | }; | ||
| 3310 | |||
| 3256 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) | 3311 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) |
| 3257 | { | 3312 | { |
| 3258 | unsigned int idx; | 3313 | unsigned int idx; |
| @@ -3297,6 +3352,17 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) · 38 unmodified lines | |||
| 3297 | } | 3352 | } |
| 3298 | } | 3353 | } |
| 3299 | 3354 | ||
| 3355 | /* Output loopback controls for H9632 cards */ | ||
| 3356 | if (hdsp->io_type == H9632) { | ||
| 3357 | snd_hdsp_loopback_control.count = hdsp->max_channels; | ||
| 3358 | kctl = snd_ctl_new1(&snd_hdsp_loopback_control, hdsp); | ||
| 3359 | if (kctl == NULL) | ||
| 3360 | return -ENOMEM; | ||
| 3361 | err = snd_ctl_add(card, kctl); | ||
| 3362 | if (err < 0) | ||
| 3363 | return err; | ||
| 3364 | } | ||
| 3365 | |||
| 3300 | /* AEB control for H96xx card */ | 3366 | /* AEB control for H96xx card */ |
| 3301 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) { | 3367 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) { |
| 3302 | if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) | 3368 | if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) |
| @@ -4956,7 +5022,7 @@ static int snd_hdsp_enable_io (struct hdsp *hdsp) · 1653 unmodified lines | |||
| 4956 | 5022 | ||
| 4957 | static void snd_hdsp_initialize_channels(struct hdsp *hdsp) | 5023 | static void snd_hdsp_initialize_channels(struct hdsp *hdsp) |
| 4958 | { | 5024 | { |
| 4959 | int status, aebi_channels, aebo_channels; | 5025 | int status, aebi_channels, aebo_channels, i; |
| 4960 | 5026 | ||
| 4961 | switch (hdsp->io_type) { | 5027 | switch (hdsp->io_type) { |
| 4962 | case Digiface: | 5028 | case Digiface: |
| @@ -4983,6 +5049,12 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp) · 20 unmodified lines | |||
| 4983 | hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels; | 5049 | hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels; |
| 4984 | hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels; | 5050 | hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels; |
| 4985 | hdsp->qs_out_channels = H9632_QS_CHANNELS+aebo_channels; | 5051 | hdsp->qs_out_channels = H9632_QS_CHANNELS+aebo_channels; |
| 5052 | /* Disable loopback of output channels, as the set function | ||
| 5053 | * only sets on a change we fake all bits (channels) as enabled. | ||
| 5054 | */ | ||
| 5055 | hdsp->io_loopback = 0xffffffff; | ||
| 5056 | for (i = 0; i < hdsp->max_channels; ++i) | ||
| 5057 | hdsp_loopback_set(hdsp, i, false); | ||
| 4986 | break; | 5058 | break; |
| 4987 | 5059 | ||
| 4988 | case Multiface: | 5060 | case Multiface: |
| @@ -6329,7 +6329,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, · 6328 unmodified lines | |||
| 6329 | memset(&hdspm_version, 0, sizeof(hdspm_version)); | 6329 | memset(&hdspm_version, 0, sizeof(hdspm_version)); |
| 6330 | 6330 | ||
| 6331 | hdspm_version.card_type = hdspm->io_type; | 6331 | hdspm_version.card_type = hdspm->io_type; |
| 6332 | strlcpy(hdspm_version.cardname, hdspm->card_name, | 6332 | strscpy(hdspm_version.cardname, hdspm->card_name, |
| 6333 | sizeof(hdspm_version.cardname)); | 6333 | sizeof(hdspm_version.cardname)); |
| 6334 | hdspm_version.serial = hdspm->serial; | 6334 | hdspm_version.serial = hdspm->serial; |
| 6335 | hdspm_version.firmware_rev = hdspm->firmware_rev; | 6335 | hdspm_version.firmware_rev = hdspm->firmware_rev; |
| @@ -363,7 +363,7 @@ static u32 sis_rate_to_delta(unsigned int rate) · 362 unmodified lines | |||
| 363 | else if (rate == 48000) | 363 | else if (rate == 48000) |
| 364 | delta = 0x1000; | 364 | delta = 0x1000; |
| 365 | else | 365 | else |
| 366 | delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; | 366 | delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff; |
| 367 | return delta; | 367 | return delta; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| @@ -570,7 +570,7 @@ static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int · 569 unmodified lines | |||
| 570 | unsigned int div; | 570 | unsigned int div; |
| 571 | unsigned long flags; | 571 | unsigned long flags; |
| 572 | 572 | ||
| 573 | div = (rate * 65536 + SV_FULLRATE / 2) / SV_FULLRATE; | 573 | div = DIV_ROUND_CLOSEST(rate * 65536, SV_FULLRATE); |
| 574 | if (div > 65535) | 574 | if (div > 65535) |
| 575 | div = 65535; | 575 | div = 65535; |
| 576 | spin_lock_irqsave(&sonic->reg_lock, flags); | 576 | spin_lock_irqsave(&sonic->reg_lock, flags); |
| @@ -1230,8 +1230,7 @@ static int snd_sonicvibes_create(struct snd_card *card, · 653 unmodified lines | |||
| 1230 | if ((err = pci_enable_device(pci)) < 0) | 1230 | if ((err = pci_enable_device(pci)) < 0) |
| 1231 | return err; | 1231 | return err; |
| 1232 | /* check, if we can restrict PCI DMA transfers to 24 bits */ | 1232 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 1233 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | 1233 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { |
| 1234 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | ||
| 1235 | dev_err(card->dev, | 1234 | dev_err(card->dev, |
| 1236 | "architecture does not support 24bit PCI busmaster DMA\n"); | 1235 | "architecture does not support 24bit PCI busmaster DMA\n"); |
| 1237 | pci_disable_device(pci); | 1236 | pci_disable_device(pci); |
| @@ -678,7 +678,7 @@ static unsigned int snd_trident_convert_rate(unsigned int rate) · 677 unmodified lines | |||
| 678 | else if (rate == 48000) | 678 | else if (rate == 48000) |
| 679 | delta = 0x1000; | 679 | delta = 0x1000; |
| 680 | else | 680 | else |
| 681 | delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; | 681 | delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff; |
| 682 | return delta; | 682 | return delta; |
| 683 | } | 683 | } |
| 684 | 684 | ||
| @@ -1034,7 +1034,7 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream) · 349 unmodified lines | |||
| 1034 | ESO_bytes++; | 1034 | ESO_bytes++; |
| 1035 | 1035 | ||
| 1036 | // Set channel sample rate, 4.12 format | 1036 | // Set channel sample rate, 4.12 format |
| 1037 | val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate; | 1037 | val = DIV_ROUND_CLOSEST(48000U << 12, runtime->rate); |
| 1038 | outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); | 1038 | outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); |
| 1039 | 1039 | ||
| 1040 | // Set channel interrupt blk length | 1040 | // Set channel interrupt blk length |
| @@ -3497,8 +3497,7 @@ int snd_trident_create(struct snd_card *card, · 2456 unmodified lines | |||
| 3497 | if ((err = pci_enable_device(pci)) < 0) | 3497 | if ((err = pci_enable_device(pci)) < 0) |
| 3498 | return err; | 3498 | return err; |
| 3499 | /* check, if we can restrict PCI DMA transfers to 30 bits */ | 3499 | /* check, if we can restrict PCI DMA transfers to 30 bits */ |
| 3500 | if (dma_set_mask(&pci->dev, DMA_BIT_MASK(30)) < 0 || | 3500 | if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(30))) { |
| 3501 | dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(30)) < 0) { | ||
| 3502 | dev_err(card->dev, | 3501 | dev_err(card->dev, |
| 3503 | "architecture does not support 30bit PCI busmaster DMA\n"); | 3502 | "architecture does not support 30bit PCI busmaster DMA\n"); |
| 3504 | pci_disable_device(pci); | 3503 | pci_disable_device(pci); |
| @@ -49,7 +49,7 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) · 48 unmodified lines | |||
| 49 | return -EINVAL; /* ignored */ | 49 | return -EINVAL; /* ignored */ |
| 50 | 50 | ||
| 51 | memset(&info, 0, sizeof(struct i2c_board_info)); | 51 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 52 | strlcpy(info.type, "keywest", I2C_NAME_SIZE); | 52 | strscpy(info.type, "keywest", I2C_NAME_SIZE); |
| 53 | info.addr = keywest_ctx->addr; | 53 | info.addr = keywest_ctx->addr; |
| 54 | client = i2c_new_client_device(adapter, &info); | 54 | client = i2c_new_client_device(adapter, &info); |
| 55 | if (IS_ERR(client)) | 55 | if (IS_ERR(client)) |
| @@ -37,6 +37,23 @@ config SND_SOC_COMPRESS · 36 unmodified lines | |||
| 37 | config SND_SOC_TOPOLOGY | 37 | config SND_SOC_TOPOLOGY |
| 38 | bool | 38 | bool |
| 39 | 39 | ||
| 40 | config SND_SOC_TOPOLOGY_KUNIT_TESTS | ||
| 41 | tristate "KUnit tests for SoC topology" | ||
| 42 | depends on KUNIT | ||
| 43 | depends on SND_SOC_TOPOLOGY | ||
| 44 | default KUNIT_ALL_TESTS | ||
| 45 | help | ||
| 46 | If you want to perform tests on ALSA SoC topology support say Y here. | ||
| 47 | |||
| 48 | This builds a module which can be later manually loaded to run KUNIT | ||
| 49 | test cases against soc-topology.c API. This should be primarily used | ||
| 50 | by developers to test their changes to ASoC. | ||
| 51 | |||
| 52 | Do note that it creates fake playback devices which do not interact | ||
| 53 | well with userspace. When running tests one may want to disable | ||
| 54 | userspace applications such as pulseaudio, to prevent unnecessary | ||
| 55 | problems. | ||
| 56 | |||
| 40 | config SND_SOC_ACPI | 57 | config SND_SOC_ACPI |
| 41 | tristate | 58 | tristate |
| 42 | 59 | ||
| @@ -62,7 +79,6 @@ source "sound/soc/qcom/Kconfig" · 19 unmodified lines | |||
| 62 | source "sound/soc/rockchip/Kconfig" | 79 | source "sound/soc/rockchip/Kconfig" |
| 63 | source "sound/soc/samsung/Kconfig" | 80 | source "sound/soc/samsung/Kconfig" |
| 64 | source "sound/soc/sh/Kconfig" | 81 | source "sound/soc/sh/Kconfig" |
| 65 | source "sound/soc/sirf/Kconfig" | ||
| 66 | source "sound/soc/sof/Kconfig" | 82 | source "sound/soc/sof/Kconfig" |
| 67 | source "sound/soc/spear/Kconfig" | 83 | source "sound/soc/spear/Kconfig" |
| 68 | source "sound/soc/sprd/Kconfig" | 84 | source "sound/soc/sprd/Kconfig" |
| @@ -71,12 +87,10 @@ source "sound/soc/stm/Kconfig" · 2 unmodified lines | |||
| 71 | source "sound/soc/sunxi/Kconfig" | 87 | source "sound/soc/sunxi/Kconfig" |
| 72 | source "sound/soc/tegra/Kconfig" | 88 | source "sound/soc/tegra/Kconfig" |
| 73 | source "sound/soc/ti/Kconfig" | 89 | source "sound/soc/ti/Kconfig" |
| 74 | source "sound/soc/txx9/Kconfig" | ||
| 75 | source "sound/soc/uniphier/Kconfig" | 90 | source "sound/soc/uniphier/Kconfig" |
| 76 | source "sound/soc/ux500/Kconfig" | 91 | source "sound/soc/ux500/Kconfig" |
| 77 | source "sound/soc/xilinx/Kconfig" | 92 | source "sound/soc/xilinx/Kconfig" |
| 78 | source "sound/soc/xtensa/Kconfig" | 93 | source "sound/soc/xtensa/Kconfig" |
| 79 | source "sound/soc/zte/Kconfig" | ||
| 80 | 94 | ||
| 81 | # Supported codecs | 95 | # Supported codecs |
| 82 | source "sound/soc/codecs/Kconfig" | 96 | source "sound/soc/codecs/Kconfig" |
| @@ -7,6 +7,11 @@ ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) · 6 unmodified lines | |||
| 7 | snd-soc-core-objs += soc-topology.o | 7 | snd-soc-core-objs += soc-topology.o |
| 8 | endif | 8 | endif |
| 9 | 9 | ||
| 10 | ifneq ($(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS),) | ||
| 11 | # snd-soc-test-objs := soc-topology-test.o | ||
| 12 | obj-$(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS) := soc-topology-test.o | ||
| 13 | endif | ||
| 14 | |||
| 10 | ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) | 15 | ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) |
| 11 | snd-soc-core-objs += soc-generic-dmaengine-pcm.o | 16 | snd-soc-core-objs += soc-generic-dmaengine-pcm.o |
| 12 | endif | 17 | endif |
| @@ -45,7 +50,6 @@ obj-$(CONFIG_SND_SOC) += qcom/ · 32 unmodified lines | |||
| 45 | obj-$(CONFIG_SND_SOC) += rockchip/ | 50 | obj-$(CONFIG_SND_SOC) += rockchip/ |
| 46 | obj-$(CONFIG_SND_SOC) += samsung/ | 51 | obj-$(CONFIG_SND_SOC) += samsung/ |
| 47 | obj-$(CONFIG_SND_SOC) += sh/ | 52 | obj-$(CONFIG_SND_SOC) += sh/ |
| 48 | obj-$(CONFIG_SND_SOC) += sirf/ | ||
| 49 | obj-$(CONFIG_SND_SOC) += sof/ | 53 | obj-$(CONFIG_SND_SOC) += sof/ |
| 50 | obj-$(CONFIG_SND_SOC) += spear/ | 54 | obj-$(CONFIG_SND_SOC) += spear/ |
| 51 | obj-$(CONFIG_SND_SOC) += sprd/ | 55 | obj-$(CONFIG_SND_SOC) += sprd/ |
| @@ -54,9 +58,7 @@ obj-$(CONFIG_SND_SOC) += stm/ · 2 unmodified lines | |||
| 54 | obj-$(CONFIG_SND_SOC) += sunxi/ | 58 | obj-$(CONFIG_SND_SOC) += sunxi/ |
| 55 | obj-$(CONFIG_SND_SOC) += tegra/ | 59 | obj-$(CONFIG_SND_SOC) += tegra/ |
| 56 | obj-$(CONFIG_SND_SOC) += ti/ | 60 | obj-$(CONFIG_SND_SOC) += ti/ |
| 57 | obj-$(CONFIG_SND_SOC) += txx9/ | ||
| 58 | obj-$(CONFIG_SND_SOC) += uniphier/ | 61 | obj-$(CONFIG_SND_SOC) += uniphier/ |
| 59 | obj-$(CONFIG_SND_SOC) += ux500/ | 62 | obj-$(CONFIG_SND_SOC) += ux500/ |
| 60 | obj-$(CONFIG_SND_SOC) += xilinx/ | 63 | obj-$(CONFIG_SND_SOC) += xilinx/ |
| 61 | obj-$(CONFIG_SND_SOC) += xtensa/ | 64 | obj-$(CONFIG_SND_SOC) += xtensa/ |
| 62 | obj-$(CONFIG_SND_SOC) += zte/ | ||
| @@ -156,7 +156,7 @@ static const struct snd_soc_dai_ops axi_i2s_dai_ops = { · 155 unmodified lines | |||
| 156 | static struct snd_soc_dai_driver axi_i2s_dai = { | 156 | static struct snd_soc_dai_driver axi_i2s_dai = { |
| 157 | .probe = axi_i2s_dai_probe, | 157 | .probe = axi_i2s_dai_probe, |
| 158 | .ops = &axi_i2s_dai_ops, | 158 | .ops = &axi_i2s_dai_ops, |
| 159 | .symmetric_rates = 1, | 159 | .symmetric_rate = 1, |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static const struct snd_soc_component_driver axi_i2s_component = { | 162 | static const struct snd_soc_component_driver axi_i2s_component = { |
| @@ -140,9 +140,7 @@ static int acp3x_1015_hw_params(struct snd_pcm_substream *substream, · 139 unmodified lines | |||
| 140 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 140 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 141 | if (strcmp(codec_dai->name, "rt1015-aif")) | 141 | if (strcmp(codec_dai->name, "rt1015-aif")) |
| 142 | continue; | 142 | continue; |
| 143 | ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); | 143 | |
| 144 | if (ret < 0) | ||
| 145 | return ret; | ||
| 146 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, | 144 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 147 | 64 * srate, 256 * srate); | 145 | 64 * srate, 256 * srate); |
| 148 | if (ret < 0) | 146 | if (ret < 0) |
| @@ -541,7 +541,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = { · 540 unmodified lines | |||
| 541 | .formats = ATMEL_I2S_FORMATS, | 541 | .formats = ATMEL_I2S_FORMATS, |
| 542 | }, | 542 | }, |
| 543 | .ops = &atmel_i2s_dai_ops, | 543 | .ops = &atmel_i2s_dai_ops, |
| 544 | .symmetric_rates = 1, | 544 | .symmetric_rate = 1, |
| 545 | }; | 545 | }; |
| 546 | 546 | ||
| 547 | static const struct snd_soc_component_driver atmel_i2s_component = { | 547 | static const struct snd_soc_component_driver atmel_i2s_component = { |
| @@ -34,86 +34,21 @@ · 33 unmodified lines | |||
| 34 | #include "atmel-pcm.h" | 34 | #include "atmel-pcm.h" |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, | ||
| 38 | int stream) | ||
| 39 | { | ||
| 40 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
| 41 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
| 42 | size_t size = ATMEL_SSC_DMABUF_SIZE; | ||
| 43 | |||
| 44 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
| 45 | buf->dev.dev = pcm->card->dev; | ||
| 46 | buf->private_data = NULL; | ||
| 47 | buf->area = dma_alloc_coherent(pcm->card->dev, size, | ||
| 48 | &buf->addr, GFP_KERNEL); | ||
| 49 | pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n", | ||
| 50 | (void *)buf->area, (void *)(long)buf->addr, size); | ||
| 51 | |||
| 52 | if (!buf->area) | ||
| 53 | return -ENOMEM; | ||
| 54 | |||
| 55 | buf->bytes = size; | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static int atmel_pcm_mmap(struct snd_soc_component *component, | ||
| 60 | struct snd_pcm_substream *substream, | ||
| 61 | struct vm_area_struct *vma) | ||
| 62 | { | ||
| 63 | return remap_pfn_range(vma, vma->vm_start, | ||
| 64 | substream->dma_buffer.addr >> PAGE_SHIFT, | ||
| 65 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | ||
| 66 | } | ||
| 67 | |||
| 68 | static int atmel_pcm_new(struct snd_soc_component *component, | 37 | static int atmel_pcm_new(struct snd_soc_component *component, |
| 69 | struct snd_soc_pcm_runtime *rtd) | 38 | struct snd_soc_pcm_runtime *rtd) |
| 70 | { | 39 | { |
| 71 | struct snd_card *card = rtd->card->snd_card; | 40 | struct snd_card *card = rtd->card->snd_card; |
| 72 | struct snd_pcm *pcm = rtd->pcm; | ||
| 73 | int ret; | 41 | int ret; |
| 74 | 42 | ||
| 75 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); | 43 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); |
| 76 | if (ret) | 44 | if (ret) |
| 77 | return ret; | 45 | return ret; |
| 78 | 46 | ||
| 79 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 47 | snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, |
| 80 | pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); | 48 | card->dev, ATMEL_SSC_DMABUF_SIZE, |
| 81 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 49 | ATMEL_SSC_DMABUF_SIZE); |
| 82 | SNDRV_PCM_STREAM_PLAYBACK); | ||
| 83 | if (ret) | ||
| 84 | goto out; | ||
| 85 | } | ||
| 86 | 50 | ||
| 87 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 51 | return 0; |
| 88 | pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); | ||
| 89 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | ||
| 90 | SNDRV_PCM_STREAM_CAPTURE); | ||
| 91 | if (ret) | ||
| 92 | goto out; | ||
| 93 | } | ||
| 94 | out: | ||
| 95 | return ret; | ||
| 96 | } | ||
| 97 | |||
| 98 | static void atmel_pcm_free(struct snd_soc_component *component, | ||
| 99 | struct snd_pcm *pcm) | ||
| 100 | { | ||
| 101 | struct snd_pcm_substream *substream; | ||
| 102 | struct snd_dma_buffer *buf; | ||
| 103 | int stream; | ||
| 104 | |||
| 105 | for (stream = 0; stream < 2; stream++) { | ||
| 106 | substream = pcm->streams[stream].substream; | ||
| 107 | if (!substream) | ||
| 108 | continue; | ||
| 109 | |||
| 110 | buf = &substream->dma_buffer; | ||
| 111 | if (!buf->area) | ||
| 112 | continue; | ||
| 113 | dma_free_coherent(pcm->card->dev, buf->bytes, | ||
| 114 | buf->area, buf->addr); | ||
| 115 | buf->area = NULL; | ||
| 116 | } | ||
| 117 | } | 52 | } |
| 118 | 53 | ||
| 119 | /*--------------------------------------------------------------------------*\ | 54 | /*--------------------------------------------------------------------------*\ |
| @@ -210,9 +145,6 @@ static int atmel_pcm_hw_params(struct snd_soc_component *component, · 90 unmodified lines | |||
| 210 | /* this may get called several times by oss emulation | 145 | /* this may get called several times by oss emulation |
| 211 | * with different params */ | 146 | * with different params */ |
| 212 | 147 | ||
| 213 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
| 214 | runtime->dma_bytes = params_buffer_bytes(params); | ||
| 215 | |||
| 216 | prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); | 148 | prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
| 217 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | 149 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; |
| 218 | 150 | ||
| @@ -384,9 +316,7 @@ static const struct snd_soc_component_driver atmel_soc_platform = { · 165 unmodified lines | |||
| 384 | .prepare = atmel_pcm_prepare, | 316 | .prepare = atmel_pcm_prepare, |
| 385 | .trigger = atmel_pcm_trigger, | 317 | .trigger = atmel_pcm_trigger, |
| 386 | .pointer = atmel_pcm_pointer, | 318 | .pointer = atmel_pcm_pointer, |
| 387 | .mmap = atmel_pcm_mmap, | ||
| 388 | .pcm_construct = atmel_pcm_new, | 319 | .pcm_construct = atmel_pcm_new, |
| 389 | .pcm_destruct = atmel_pcm_free, | ||
| 390 | }; | 320 | }; |
| 391 | 321 | ||
| 392 | int atmel_pcm_pdc_platform_register(struct device *dev) | 322 | int atmel_pcm_pdc_platform_register(struct device *dev) |
| @@ -859,8 +859,8 @@ static struct snd_soc_dai_driver mchp_i2s_mcc_dai = { · 858 unmodified lines | |||
| 859 | .formats = MCHP_I2SMCC_FORMATS, | 859 | .formats = MCHP_I2SMCC_FORMATS, |
| 860 | }, | 860 | }, |
| 861 | .ops = &mchp_i2s_mcc_dai_ops, | 861 | .ops = &mchp_i2s_mcc_dai_ops, |
| 862 | .symmetric_rates = 1, | 862 | .symmetric_rate = 1, |
| 863 | .symmetric_samplebits = 1, | 863 | .symmetric_sample_bits = 1, |
| 864 | .symmetric_channels = 1, | 864 | .symmetric_channels = 1, |
| 865 | }; | 865 | }; |
| 866 | 866 | ||
| @@ -210,7 +210,7 @@ static const struct snd_soc_dai_ops au1xi2s_dai_ops = { · 209 unmodified lines | |||
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | static struct snd_soc_dai_driver au1xi2s_dai_driver = { | 212 | static struct snd_soc_dai_driver au1xi2s_dai_driver = { |
| 213 | .symmetric_rates = 1, | 213 | .symmetric_rate = 1, |
| 214 | .playback = { | 214 | .playback = { |
| 215 | .rates = AU1XI2SC_RATES, | 215 | .rates = AU1XI2SC_RATES, |
| 216 | .formats = AU1XI2SC_FMTS, | 216 | .formats = AU1XI2SC_FMTS, |
| @@ -783,8 +783,8 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { · 782 unmodified lines | |||
| 783 | | SNDRV_PCM_FMTBIT_S32_LE | 783 | | SNDRV_PCM_FMTBIT_S32_LE |
| 784 | }, | 784 | }, |
| 785 | .ops = &bcm2835_i2s_dai_ops, | 785 | .ops = &bcm2835_i2s_dai_ops, |
| 786 | .symmetric_rates = 1, | 786 | .symmetric_rate = 1, |
| 787 | .symmetric_samplebits = 1, | 787 | .symmetric_sample_bits = 1, |
| 788 | }; | 788 | }; |
| 789 | 789 | ||
| 790 | static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg) | 790 | static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg) |
| @@ -212,7 +212,7 @@ static struct snd_soc_dai_driver bcm63xx_i2s_dai = { · 211 unmodified lines | |||
| 212 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 212 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 213 | }, | 213 | }, |
| 214 | .ops = &bcm63xx_i2s_dai_ops, | 214 | .ops = &bcm63xx_i2s_dai_ops, |
| 215 | .symmetric_rates = 1, | 215 | .symmetric_rate = 1, |
| 216 | .symmetric_channels = 1, | 216 | .symmetric_channels = 1, |
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| @@ -636,36 +636,6 @@ static int cygnus_pcm_close(struct snd_soc_component *component, · 635 unmodified lines | |||
| 636 | return 0; | 636 | return 0; |
| 637 | } | 637 | } |
| 638 | 638 | ||
| 639 | static int cygnus_pcm_hw_params(struct snd_soc_component *component, | ||
| 640 | struct snd_pcm_substream *substream, | ||
| 641 | struct snd_pcm_hw_params *params) | ||
| 642 | { | ||
| 643 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | ||
| 644 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 645 | struct cygnus_aio_port *aio; | ||
| 646 | |||
| 647 | aio = cygnus_dai_get_dma_data(substream); | ||
| 648 | dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); | ||
| 649 | |||
| 650 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
| 651 | runtime->dma_bytes = params_buffer_bytes(params); | ||
| 652 | |||
| 653 | return 0; | ||
| 654 | } | ||
| 655 | |||
| 656 | static int cygnus_pcm_hw_free(struct snd_soc_component *component, | ||
| 657 | struct snd_pcm_substream *substream) | ||
| 658 | { | ||
| 659 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | ||
| 660 | struct cygnus_aio_port *aio; | ||
| 661 | |||
| 662 | aio = cygnus_dai_get_dma_data(substream); | ||
| 663 | dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); | ||
| 664 | |||
| 665 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
| 666 | return 0; | ||
| 667 | } | ||
| 668 | |||
| 669 | static int cygnus_pcm_prepare(struct snd_soc_component *component, | 639 | static int cygnus_pcm_prepare(struct snd_soc_component *component, |
| 670 | struct snd_pcm_substream *substream) | 640 | struct snd_pcm_substream *substream) |
| 671 | { | 641 | { |
| @@ -730,87 +700,19 @@ static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_soc_component *component, · 58 unmodified lines | |||
| 730 | return bytes_to_frames(substream->runtime, res); | 700 | return bytes_to_frames(substream->runtime, res); |
| 731 | } | 701 | } |
| 732 | 702 | ||
| 733 | static int cygnus_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
| 734 | { | ||
| 735 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
| 736 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | ||
| 737 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
| 738 | size_t size; | ||
| 739 | |||
| 740 | size = cygnus_pcm_hw.buffer_bytes_max; | ||
| 741 | |||
| 742 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
| 743 | buf->dev.dev = pcm->card->dev; | ||
| 744 | buf->private_data = NULL; | ||
| 745 | buf->area = dma_alloc_coherent(pcm->card->dev, size, | ||
| 746 | &buf->addr, GFP_KERNEL); | ||
| 747 | |||
| 748 | dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: size 0x%zx @ %pK\n", | ||
| 749 | __func__, size, buf->area); | ||
| 750 | |||
| 751 | if (!buf->area) { | ||
| 752 | dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: dma_alloc failed\n", __func__); | ||
| 753 | return -ENOMEM; | ||
| 754 | } | ||
| 755 | buf->bytes = size; | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | static void cygnus_dma_free_dma_buffers(struct snd_soc_component *component, | ||
| 761 | struct snd_pcm *pcm) | ||
| 762 | { | ||
| 763 | struct snd_pcm_substream *substream; | ||
| 764 | struct snd_dma_buffer *buf; | ||
| 765 | |||
| 766 | substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | ||
| 767 | if (substream) { | ||
| 768 | buf = &substream->dma_buffer; | ||
| 769 | if (buf->area) { | ||
| 770 | dma_free_coherent(pcm->card->dev, buf->bytes, | ||
| 771 | buf->area, buf->addr); | ||
| 772 | buf->area = NULL; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | |||
| 776 | substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; | ||
| 777 | if (substream) { | ||
| 778 | buf = &substream->dma_buffer; | ||
| 779 | if (buf->area) { | ||
| 780 | dma_free_coherent(pcm->card->dev, buf->bytes, | ||
| 781 | buf->area, buf->addr); | ||
| 782 | buf->area = NULL; | ||
| 783 | } | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | static int cygnus_dma_new(struct snd_soc_component *component, | 703 | static int cygnus_dma_new(struct snd_soc_component *component, |
| 788 | struct snd_soc_pcm_runtime *rtd) | 704 | struct snd_soc_pcm_runtime *rtd) |
| 789 | { | 705 | { |
| 706 | size_t size = cygnus_pcm_hw.buffer_bytes_max; | ||
| 790 | struct snd_card *card = rtd->card->snd_card; | 707 | struct snd_card *card = rtd->card->snd_card; |
| 791 | struct snd_pcm *pcm = rtd->pcm; | ||
| 792 | int ret; | ||
| 793 | 708 | ||
| 794 | if (!card->dev->dma_mask) | 709 | if (!card->dev->dma_mask) |
| 795 | card->dev->dma_mask = &cygnus_dma_dmamask; | 710 | card->dev->dma_mask = &cygnus_dma_dmamask; |
| 796 | if (!card->dev->coherent_dma_mask) | 711 | if (!card->dev->coherent_dma_mask) |
| 797 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | 712 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
| 798 | 713 | ||
| 799 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 714 | snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, |
| 800 | ret = cygnus_pcm_preallocate_dma_buffer(pcm, | 715 | card->dev, size, size); |
| 801 | SNDRV_PCM_STREAM_PLAYBACK); | ||
| 802 | if (ret) | ||
| 803 | return ret; | ||
| 804 | } | ||
| 805 | |||
| 806 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
| 807 | ret = cygnus_pcm_preallocate_dma_buffer(pcm, | ||
| 808 | SNDRV_PCM_STREAM_CAPTURE); | ||
| 809 | if (ret) { | ||
| 810 | cygnus_dma_free_dma_buffers(component, pcm); | ||
| 811 | return ret; | ||
| 812 | } | ||
| 813 | } | ||
| 814 | 716 | ||
| 815 | return 0; | 717 | return 0; |
| 816 | } | 718 | } |
| @@ -818,13 +720,10 @@ static int cygnus_dma_new(struct snd_soc_component *component, · 1 unmodified line | |||
| 818 | static struct snd_soc_component_driver cygnus_soc_platform = { | 720 | static struct snd_soc_component_driver cygnus_soc_platform = { |
| 819 | .open = cygnus_pcm_open, | 721 | .open = cygnus_pcm_open, |
| 820 | .close = cygnus_pcm_close, | 722 | .close = cygnus_pcm_close, |
| 821 | .hw_params = cygnus_pcm_hw_params, | ||
| 822 | .hw_free = cygnus_pcm_hw_free, | ||
| 823 | .prepare = cygnus_pcm_prepare, | 723 | .prepare = cygnus_pcm_prepare, |
| 824 | .trigger = cygnus_pcm_trigger, | 724 | .trigger = cygnus_pcm_trigger, |
| 825 | .pointer = cygnus_pcm_pointer, | 725 | .pointer = cygnus_pcm_pointer, |
| 826 | .pcm_construct = cygnus_dma_new, | 726 | .pcm_construct = cygnus_dma_new, |
| 827 | .pcm_destruct = cygnus_dma_free_dma_buffers, | ||
| 828 | }; | 727 | }; |
| 829 | 728 | ||
| 830 | int cygnus_soc_platform_register(struct device *dev, | 729 | int cygnus_soc_platform_register(struct device *dev, |
| @@ -404,7 +404,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { · 403 unmodified lines | |||
| 404 | #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) | 404 | #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) |
| 405 | 405 | ||
| 406 | static struct snd_soc_dai_driver ep93xx_i2s_dai = { | 406 | static struct snd_soc_dai_driver ep93xx_i2s_dai = { |
| 407 | .symmetric_rates= 1, | 407 | .symmetric_rate = 1, |
| 408 | .probe = ep93xx_i2s_dai_probe, | 408 | .probe = ep93xx_i2s_dai_probe, |
| 409 | .playback = { | 409 | .playback = { |
| 410 | .channels_min = 2, | 410 | .channels_min = 2, |
| @@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS · 103 unmodified lines | |||
| 104 | imply SND_SOC_ISABELLE | 104 | imply SND_SOC_ISABELLE |
| 105 | imply SND_SOC_JZ4740_CODEC | 105 | imply SND_SOC_JZ4740_CODEC |
| 106 | imply SND_SOC_JZ4725B_CODEC | 106 | imply SND_SOC_JZ4725B_CODEC |
| 107 | imply SND_SOC_JZ4760_CODEC | ||
| 107 | imply SND_SOC_JZ4770_CODEC | 108 | imply SND_SOC_JZ4770_CODEC |
| 108 | imply SND_SOC_LM4857 | 109 | imply SND_SOC_LM4857 |
| 109 | imply SND_SOC_LM49453 | 110 | imply SND_SOC_LM49453 |
| @@ -227,6 +228,8 @@ config SND_SOC_ALL_CODECS · 117 unmodified lines | |||
| 227 | imply SND_SOC_UDA1380 | 228 | imply SND_SOC_UDA1380 |
| 228 | imply SND_SOC_WCD9335 | 229 | imply SND_SOC_WCD9335 |
| 229 | imply SND_SOC_WCD934X | 230 | imply SND_SOC_WCD934X |
| 231 | imply SND_SOC_LPASS_RX_MACRO | ||
| 232 | imply SND_SOC_LPASS_TX_MACRO | ||
| 230 | imply SND_SOC_WL1273 | 233 | imply SND_SOC_WL1273 |
| 231 | imply SND_SOC_WM0010 | 234 | imply SND_SOC_WM0010 |
| 232 | imply SND_SOC_WM1250_EV1 | 235 | imply SND_SOC_WM1250_EV1 |
| @@ -712,7 +715,7 @@ config SND_SOC_CX2072X · 479 unmodified lines | |||
| 712 | Enable support for Conexant CX20721 and CX20723 codec chips. | 715 | Enable support for Conexant CX20721 and CX20723 codec chips. |
| 713 | 716 | ||
| 714 | config SND_SOC_JZ4740_CODEC | 717 | config SND_SOC_JZ4740_CODEC |
| 715 | depends on MIPS || COMPILE_TEST | 718 | depends on MACH_INGENIC || COMPILE_TEST |
| 716 | depends on OF | 719 | depends on OF |
| 717 | select REGMAP_MMIO | 720 | select REGMAP_MMIO |
| 718 | tristate "Ingenic JZ4740 internal CODEC" | 721 | tristate "Ingenic JZ4740 internal CODEC" |
| @@ -724,7 +727,7 @@ config SND_SOC_JZ4740_CODEC · 5 unmodified lines | |||
| 724 | will be called snd-soc-jz4740-codec. | 727 | will be called snd-soc-jz4740-codec. |
| 725 | 728 | ||
| 726 | config SND_SOC_JZ4725B_CODEC | 729 | config SND_SOC_JZ4725B_CODEC |
| 727 | depends on MIPS || COMPILE_TEST | 730 | depends on MACH_INGENIC || COMPILE_TEST |
| 728 | depends on OF | 731 | depends on OF |
| 729 | select REGMAP | 732 | select REGMAP |
| 730 | tristate "Ingenic JZ4725B internal CODEC" | 733 | tristate "Ingenic JZ4725B internal CODEC" |
| @@ -735,8 +738,20 @@ config SND_SOC_JZ4725B_CODEC · 4 unmodified lines | |||
| 735 | This driver can also be built as a module. If so, the module | 738 | This driver can also be built as a module. If so, the module |
| 736 | will be called snd-soc-jz4725b-codec. | 739 | will be called snd-soc-jz4725b-codec. |
| 737 | 740 | ||
| 741 | config SND_SOC_JZ4760_CODEC | ||
| 742 | depends on MACH_INGENIC || COMPILE_TEST | ||
| 743 | depends on OF | ||
| 744 | select REGMAP | ||
| 745 | tristate "Ingenic JZ4760 internal CODEC" | ||
| 746 | help | ||
| 747 | Enable support for the internal CODEC found in the JZ4760 SoC | ||
| 748 | from Ingenic. | ||
| 749 | |||
| 750 | This driver can also be built as a module. If so, the module | ||
| 751 | will be called snd-soc-jz4760-codec. | ||
| 752 | |||
| 738 | config SND_SOC_JZ4770_CODEC | 753 | config SND_SOC_JZ4770_CODEC |
| 739 | depends on MIPS || COMPILE_TEST | 754 | depends on MACH_INGENIC || COMPILE_TEST |
| 740 | depends on OF | 755 | depends on OF |
| 741 | select REGMAP | 756 | select REGMAP |
| 742 | tristate "Ingenic JZ4770 internal CODEC" | 757 | tristate "Ingenic JZ4770 internal CODEC" |
| @@ -1162,7 +1177,7 @@ config SND_SOC_RT5651 · 419 unmodified lines | |||
| 1162 | depends on I2C | 1177 | depends on I2C |
| 1163 | 1178 | ||
| 1164 | config SND_SOC_RT5659 | 1179 | config SND_SOC_RT5659 |
| 1165 | tristate | 1180 | tristate "Realtek RT5658/RT5659 Codec" |
| 1166 | depends on I2C | 1181 | depends on I2C |
| 1167 | 1182 | ||
| 1168 | config SND_SOC_RT5660 | 1183 | config SND_SOC_RT5660 |
| @@ -1820,4 +1835,12 @@ config SND_SOC_LPASS_VA_MACRO · 651 unmodified lines | |||
| 1820 | depends on COMMON_CLK | 1835 | depends on COMMON_CLK |
| 1821 | tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)" | 1836 | tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)" |
| 1822 | 1837 | ||
| 1838 | config SND_SOC_LPASS_RX_MACRO | ||
| 1839 | depends on COMMON_CLK | ||
| 1840 | tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" | ||
| 1841 | |||
| 1842 | config SND_SOC_LPASS_TX_MACRO | ||
| 1843 | depends on COMMON_CLK | ||
| 1844 | tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)" | ||
| 1845 | |||
| 1823 | endmenu | 1846 | endmenu |
| @@ -101,11 +101,14 @@ snd-soc-inno-rk3036-objs := inno_rk3036.o · 100 unmodified lines | |||
| 101 | snd-soc-isabelle-objs := isabelle.o | 101 | snd-soc-isabelle-objs := isabelle.o |
| 102 | snd-soc-jz4740-codec-objs := jz4740.o | 102 | snd-soc-jz4740-codec-objs := jz4740.o |
| 103 | snd-soc-jz4725b-codec-objs := jz4725b.o | 103 | snd-soc-jz4725b-codec-objs := jz4725b.o |
| 104 | snd-soc-jz4760-codec-objs := jz4760.o | ||
| 104 | snd-soc-jz4770-codec-objs := jz4770.o | 105 | snd-soc-jz4770-codec-objs := jz4770.o |
| 105 | snd-soc-l3-objs := l3.o | 106 | snd-soc-l3-objs := l3.o |
| 106 | snd-soc-lm4857-objs := lm4857.o | 107 | snd-soc-lm4857-objs := lm4857.o |
| 107 | snd-soc-lm49453-objs := lm49453.o | 108 | snd-soc-lm49453-objs := lm49453.o |
| 108 | snd-soc-lochnagar-sc-objs := lochnagar-sc.o | 109 | snd-soc-lochnagar-sc-objs := lochnagar-sc.o |
| 110 | snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o | ||
| 111 | snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o | ||
| 109 | snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o | 112 | snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o |
| 110 | snd-soc-lpass-va-macro-objs := lpass-va-macro.o | 113 | snd-soc-lpass-va-macro-objs := lpass-va-macro.o |
| 111 | snd-soc-madera-objs := madera.o | 114 | snd-soc-madera-objs := madera.o |
| @@ -201,7 +204,6 @@ snd-soc-sigmadsp-objs := sigmadsp.o · 89 unmodified lines | |||
| 201 | snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o | 204 | snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o |
| 202 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o | 205 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o |
| 203 | snd-soc-si476x-objs := si476x.o | 206 | snd-soc-si476x-objs := si476x.o |
| 204 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o | ||
| 205 | snd-soc-spdif-tx-objs := spdif_transmitter.o | 207 | snd-soc-spdif-tx-objs := spdif_transmitter.o |
| 206 | snd-soc-spdif-rx-objs := spdif_receiver.o | 208 | snd-soc-spdif-rx-objs := spdif_receiver.o |
| 207 | snd-soc-ssm2305-objs := ssm2305.o | 209 | snd-soc-ssm2305-objs := ssm2305.o |
| @@ -302,7 +304,6 @@ snd-soc-wm9713-objs := wm9713.o · 94 unmodified lines | |||
| 302 | snd-soc-wm-hubs-objs := wm_hubs.o | 304 | snd-soc-wm-hubs-objs := wm_hubs.o |
| 303 | snd-soc-wsa881x-objs := wsa881x.o | 305 | snd-soc-wsa881x-objs := wsa881x.o |
| 304 | snd-soc-zl38060-objs := zl38060.o | 306 | snd-soc-zl38060-objs := zl38060.o |
| 305 | snd-soc-zx-aud96p22-objs := zx_aud96p22.o | ||
| 306 | # Amp | 307 | # Amp |
| 307 | snd-soc-max9877-objs := max9877.o | 308 | snd-soc-max9877-objs := max9877.o |
| 308 | snd-soc-max98504-objs := max98504.o | 309 | snd-soc-max98504-objs := max98504.o |
| @@ -418,6 +419,7 @@ obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o · 109 unmodified lines | |||
| 418 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o | 419 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o |
| 419 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o | 420 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o |
| 420 | obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o | 421 | obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o |
| 422 | obj-$(CONFIG_SND_SOC_JZ4760_CODEC) += snd-soc-jz4760-codec.o | ||
| 421 | obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o | 423 | obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o |
| 422 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o | 424 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o |
| 423 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o | 425 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o |
| @@ -516,7 +518,6 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o · 92 unmodified lines | |||
| 516 | obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o | 518 | obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o |
| 517 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o | 519 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o |
| 518 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o | 520 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o |
| 519 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o | ||
| 520 | obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o | 521 | obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o |
| 521 | obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o | 522 | obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o |
| 522 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | 523 | obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o |
| @@ -618,7 +619,6 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o · 95 unmodified lines | |||
| 618 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o | 619 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o |
| 619 | obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o | 620 | obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o |
| 620 | obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o | 621 | obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o |
| 621 | obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o | ||
| 622 | 622 | ||
| 623 | # Amp | 623 | # Amp |
| 624 | obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o | 624 | obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o |
| @@ -627,6 +627,8 @@ obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o · 2 unmodified lines | |||
| 627 | obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o | 627 | obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o |
| 628 | obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o | 628 | obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o |
| 629 | obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o | 629 | obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o |
| 630 | obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o | ||
| 631 | obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o | ||
| 630 | 632 | ||
| 631 | # Mux | 633 | # Mux |
| 632 | obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o | 634 | obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o |
| @@ -2384,7 +2384,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { · 2383 unmodified lines | |||
| 2384 | .formats = AB8500_SUPPORTED_FMT, | 2384 | .formats = AB8500_SUPPORTED_FMT, |
| 2385 | }, | 2385 | }, |
| 2386 | .ops = &ab8500_codec_ops, | 2386 | .ops = &ab8500_codec_ops, |
| 2387 | .symmetric_rates = 1 | 2387 | .symmetric_rate = 1 |
| 2388 | }, | 2388 | }, |
| 2389 | { | 2389 | { |
| 2390 | .name = "ab8500-codec-dai.1", | 2390 | .name = "ab8500-codec-dai.1", |
| @@ -2397,7 +2397,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { · 6 unmodified lines | |||
| 2397 | .formats = AB8500_SUPPORTED_FMT, | 2397 | .formats = AB8500_SUPPORTED_FMT, |
| 2398 | }, | 2398 | }, |
| 2399 | .ops = &ab8500_codec_ops, | 2399 | .ops = &ab8500_codec_ops, |
| 2400 | .symmetric_rates = 1 | 2400 | .symmetric_rate = 1 |
| 2401 | } | 2401 | } |
| 2402 | }; | 2402 | }; |
| 2403 | 2403 | ||
| @@ -890,7 +890,7 @@ static struct snd_soc_dai_driver adau1372_dai_driver = { · 889 unmodified lines | |||
| 890 | .sig_bits = 24, | 890 | .sig_bits = 24, |
| 891 | }, | 891 | }, |
| 892 | .ops = &adau1372_dai_ops, | 892 | .ops = &adau1372_dai_ops, |
| 893 | .symmetric_rates = 1, | 893 | .symmetric_rate = 1, |
| 894 | }; | 894 | }; |
| 895 | 895 | ||
| 896 | static int adau1372_setup_pll(struct adau1372 *adau1372, unsigned int rate) | 896 | static int adau1372_setup_pll(struct adau1372 *adau1372, unsigned int rate) |
| @@ -1205,7 +1205,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { · 1204 unmodified lines | |||
| 1205 | .formats = ADAU1373_FORMATS, | 1205 | .formats = ADAU1373_FORMATS, |
| 1206 | }, | 1206 | }, |
| 1207 | .ops = &adau1373_dai_ops, | 1207 | .ops = &adau1373_dai_ops, |
| 1208 | .symmetric_rates = 1, | 1208 | .symmetric_rate = 1, |
| 1209 | }, | 1209 | }, |
| 1210 | { | 1210 | { |
| 1211 | .id = 1, | 1211 | .id = 1, |
| @@ -1225,7 +1225,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { · 13 unmodified lines | |||
| 1225 | .formats = ADAU1373_FORMATS, | 1225 | .formats = ADAU1373_FORMATS, |
| 1226 | }, | 1226 | }, |
| 1227 | .ops = &adau1373_dai_ops, | 1227 | .ops = &adau1373_dai_ops, |
| 1228 | .symmetric_rates = 1, | 1228 | .symmetric_rate = 1, |
| 1229 | }, | 1229 | }, |
| 1230 | { | 1230 | { |
| 1231 | .id = 2, | 1231 | .id = 2, |
| @@ -1245,7 +1245,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { · 13 unmodified lines | |||
| 1245 | .formats = ADAU1373_FORMATS, | 1245 | .formats = ADAU1373_FORMATS, |
| 1246 | }, | 1246 | }, |
| 1247 | .ops = &adau1373_dai_ops, | 1247 | .ops = &adau1373_dai_ops, |
| 1248 | .symmetric_rates = 1, | 1248 | .symmetric_rate = 1, |
| 1249 | }, | 1249 | }, |
| 1250 | }; | 1250 | }; |
| 1251 | 1251 | ||
| @@ -653,7 +653,7 @@ static struct snd_soc_dai_driver adau1701_dai = { · 652 unmodified lines | |||
| 653 | .formats = ADAU1701_FORMATS, | 653 | .formats = ADAU1701_FORMATS, |
| 654 | }, | 654 | }, |
| 655 | .ops = &adau1701_dai_ops, | 655 | .ops = &adau1701_dai_ops, |
| 656 | .symmetric_rates = 1, | 656 | .symmetric_rate = 1, |
| 657 | }; | 657 | }; |
| 658 | 658 | ||
| 659 | #ifdef CONFIG_OF | 659 | #ifdef CONFIG_OF |
| @@ -1095,8 +1095,7 @@ void adau17x1_remove(struct device *dev) · 1094 unmodified lines | |||
| 1095 | { | 1095 | { |
| 1096 | struct adau *adau = dev_get_drvdata(dev); | 1096 | struct adau *adau = dev_get_drvdata(dev); |
| 1097 | 1097 | ||
| 1098 | if (adau->mclk) | 1098 | clk_disable_unprepare(adau->mclk); |
| 1099 | clk_disable_unprepare(adau->mclk); | ||
| 1100 | } | 1099 | } |
| 1101 | EXPORT_SYMBOL_GPL(adau17x1_remove); | 1100 | EXPORT_SYMBOL_GPL(adau17x1_remove); |
| 1102 | 1101 | ||
| @@ -56,7 +56,7 @@ static struct snd_soc_dai_driver ak4554_dai = { · 55 unmodified lines | |||
| 56 | .rates = SNDRV_PCM_RATE_8000_48000, | 56 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 57 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 57 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 58 | }, | 58 | }, |
| 59 | .symmetric_rates = 1, | 59 | .symmetric_rate = 1, |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | static const struct snd_soc_component_driver soc_component_dev_ak4554 = { | 62 | static const struct snd_soc_component_driver soc_component_dev_ak4554 = { |
| @@ -575,7 +575,7 @@ static struct snd_soc_dai_driver ak4613_dai = { · 574 unmodified lines | |||
| 575 | .formats = AK4613_PCM_FMTBIT, | 575 | .formats = AK4613_PCM_FMTBIT, |
| 576 | }, | 576 | }, |
| 577 | .ops = &ak4613_dai_ops, | 577 | .ops = &ak4613_dai_ops, |
| 578 | .symmetric_rates = 1, | 578 | .symmetric_rate = 1, |
| 579 | }; | 579 | }; |
| 580 | 580 | ||
| 581 | static int ak4613_suspend(struct snd_soc_component *component) | 581 | static int ak4613_suspend(struct snd_soc_component *component) |
| @@ -499,7 +499,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { · 498 unmodified lines | |||
| 499 | .formats = AK4641_FORMATS, | 499 | .formats = AK4641_FORMATS, |
| 500 | }, | 500 | }, |
| 501 | .ops = &ak4641_i2s_dai_ops, | 501 | .ops = &ak4641_i2s_dai_ops, |
| 502 | .symmetric_rates = 1, | 502 | .symmetric_rate = 1, |
| 503 | }, | 503 | }, |
| 504 | { | 504 | { |
| 505 | .name = "ak4641-voice", | 505 | .name = "ak4641-voice", |
| @@ -519,7 +519,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { · 13 unmodified lines | |||
| 519 | .formats = AK4641_FORMATS, | 519 | .formats = AK4641_FORMATS, |
| 520 | }, | 520 | }, |
| 521 | .ops = &ak4641_pcm_dai_ops, | 521 | .ops = &ak4641_pcm_dai_ops, |
| 522 | .symmetric_rates = 1, | 522 | .symmetric_rate = 1, |
| 523 | }, | 523 | }, |
| 524 | }; | 524 | }; |
| 525 | 525 | ||
| @@ -516,7 +516,7 @@ static struct snd_soc_dai_driver ak4642_dai = { · 515 unmodified lines | |||
| 516 | .rates = SNDRV_PCM_RATE_8000_48000, | 516 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 517 | .formats = SNDRV_PCM_FMTBIT_S16_LE }, | 517 | .formats = SNDRV_PCM_FMTBIT_S16_LE }, |
| 518 | .ops = &ak4642_dai_ops, | 518 | .ops = &ak4642_dai_ops, |
| 519 | .symmetric_rates = 1, | 519 | .symmetric_rate = 1, |
| 520 | }; | 520 | }; |
| 521 | 521 | ||
| 522 | static int ak4642_suspend(struct snd_soc_component *component) | 522 | static int ak4642_suspend(struct snd_soc_component *component) |
| @@ -1032,7 +1032,7 @@ static struct snd_soc_dai_driver alc5632_dai = { · 1031 unmodified lines | |||
| 1032 | .formats = ALC5632_FORMATS,}, | 1032 | .formats = ALC5632_FORMATS,}, |
| 1033 | 1033 | ||
| 1034 | .ops = &alc5632_dai_ops, | 1034 | .ops = &alc5632_dai_ops, |
| 1035 | .symmetric_rates = 1, | 1035 | .symmetric_rate = 1, |
| 1036 | }; | 1036 | }; |
| 1037 | 1037 | ||
| 1038 | #ifdef CONFIG_PM | 1038 | #ifdef CONFIG_PM |
| @@ -16,6 +16,14 @@ · 15 unmodified lines | |||
| 16 | #include <sound/soc.h> | 16 | #include <sound/soc.h> |
| 17 | #include <sound/tlv.h> | 17 | #include <sound/tlv.h> |
| 18 | 18 | ||
| 19 | /* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */ | ||
| 20 | #define CPCAP_BIT_AUDIO_LOW_PWR 6 | ||
| 21 | #define CPCAP_BIT_AUD_LOWPWR_SPEED 5 | ||
| 22 | #define CPCAP_BIT_VAUDIOPRISTBY 4 | ||
| 23 | #define CPCAP_BIT_VAUDIO_MODE1 2 | ||
| 24 | #define CPCAP_BIT_VAUDIO_MODE0 1 | ||
| 25 | #define CPCAP_BIT_V_AUDIO_EN 0 | ||
| 26 | |||
| 19 | /* Register 513 CPCAP_REG_CC --- CODEC */ | 27 | /* Register 513 CPCAP_REG_CC --- CODEC */ |
| 20 | #define CPCAP_BIT_CDC_CLK2 15 | 28 | #define CPCAP_BIT_CDC_CLK2 15 |
| 21 | #define CPCAP_BIT_CDC_CLK1 14 | 29 | #define CPCAP_BIT_CDC_CLK1 14 |
| @@ -221,6 +229,7 @@ struct cpcap_reg_info { · 199 unmodified lines | |||
| 221 | }; | 229 | }; |
| 222 | 230 | ||
| 223 | static const struct cpcap_reg_info cpcap_default_regs[] = { | 231 | static const struct cpcap_reg_info cpcap_default_regs[] = { |
| 232 | { CPCAP_REG_VAUDIOC, 0x003F, 0x0000 }, | ||
| 224 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, | 233 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, |
| 225 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, | 234 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, |
| 226 | { CPCAP_REG_CDI, 0xBFFF, 0x0000 }, | 235 | { CPCAP_REG_CDI, 0xBFFF, 0x0000 }, |
| @@ -1264,12 +1273,12 @@ static int cpcap_voice_hw_params(struct snd_pcm_substream *substream, · 1037 unmodified lines | |||
| 1264 | 1273 | ||
| 1265 | if (direction == SNDRV_PCM_STREAM_CAPTURE) { | 1274 | if (direction == SNDRV_PCM_STREAM_CAPTURE) { |
| 1266 | mask = 0x0000; | 1275 | mask = 0x0000; |
| 1267 | mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0; | 1276 | mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); |
| 1268 | mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1; | 1277 | mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1); |
| 1269 | mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2; | 1278 | mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2); |
| 1270 | mask |= CPCAP_BIT_MIC2_TIMESLOT0; | 1279 | mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0); |
| 1271 | mask |= CPCAP_BIT_MIC2_TIMESLOT1; | 1280 | mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1); |
| 1272 | mask |= CPCAP_BIT_MIC2_TIMESLOT2; | 1281 | mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2); |
| 1273 | val = 0x0000; | 1282 | val = 0x0000; |
| 1274 | if (channels >= 2) | 1283 | if (channels >= 2) |
| 1275 | val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); | 1284 | val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); |
| @@ -1371,8 +1380,121 @@ static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, · 95 unmodified lines | |||
| 1371 | return 0; | 1380 | return 0; |
| 1372 | } | 1381 | } |
| 1373 | 1382 | ||
| 1374 | static int cpcap_voice_set_mute(struct snd_soc_dai *dai, | 1383 | |
| 1375 | int mute, int direction) | 1384 | /* |
| 1385 | * Configure codec for voice call if requested. | ||
| 1386 | * | ||
| 1387 | * We can configure most with snd_soc_dai_set_sysclk(), snd_soc_dai_set_fmt() | ||
| 1388 | * and snd_soc_dai_set_tdm_slot(). This function configures the rest of the | ||
| 1389 | * cpcap related hardware as CPU is not involved in the voice call. | ||
| 1390 | */ | ||
| 1391 | static int cpcap_voice_call(struct cpcap_audio *cpcap, struct snd_soc_dai *dai, | ||
| 1392 | bool voice_call) | ||
| 1393 | { | ||
| 1394 | int mask, err; | ||
| 1395 | |||
| 1396 | /* Modem to codec VAUDIO_MODE1 */ | ||
| 1397 | mask = BIT(CPCAP_BIT_VAUDIO_MODE1); | ||
| 1398 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, | ||
| 1399 | mask, voice_call ? mask : 0); | ||
| 1400 | if (err) | ||
| 1401 | return err; | ||
| 1402 | |||
| 1403 | /* Clear MIC1_MUX for call */ | ||
| 1404 | mask = BIT(CPCAP_BIT_MIC1_MUX); | ||
| 1405 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, | ||
| 1406 | mask, voice_call ? 0 : mask); | ||
| 1407 | if (err) | ||
| 1408 | return err; | ||
| 1409 | |||
| 1410 | /* Set MIC2_MUX for call */ | ||
| 1411 | mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) | | ||
| 1412 | BIT(CPCAP_BIT_MIC2_MUX) | BIT(CPCAP_BIT_MIC2_PGA_EN); | ||
| 1413 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, | ||
| 1414 | mask, voice_call ? mask : 0); | ||
| 1415 | if (err) | ||
| 1416 | return err; | ||
| 1417 | |||
| 1418 | /* Enable LDSP for call */ | ||
| 1419 | mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN); | ||
| 1420 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, | ||
| 1421 | mask, voice_call ? mask : 0); | ||
| 1422 | if (err) | ||
| 1423 | return err; | ||
| 1424 | |||
| 1425 | /* Enable CPCAP_BIT_PGA_CDC_EN for call */ | ||
| 1426 | mask = BIT(CPCAP_BIT_PGA_CDC_EN); | ||
| 1427 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, | ||
| 1428 | mask, voice_call ? mask : 0); | ||
| 1429 | if (err) | ||
| 1430 | return err; | ||
| 1431 | |||
| 1432 | /* Unmute voice for call */ | ||
| 1433 | if (dai) { | ||
| 1434 | err = snd_soc_dai_digital_mute(dai, !voice_call, | ||
| 1435 | SNDRV_PCM_STREAM_PLAYBACK); | ||
| 1436 | if (err) | ||
| 1437 | return err; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | /* Set modem to codec mic CDC and HPF for call */ | ||
| 1441 | mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) | | ||
| 1442 | BIT(CPCAP_BIT_AUDOHPF_1) | BIT(CPCAP_BIT_AUDOHPF_0) | | ||
| 1443 | BIT(CPCAP_BIT_AUDIHPF_1) | BIT(CPCAP_BIT_AUDIHPF_0); | ||
| 1444 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, | ||
| 1445 | mask, voice_call ? mask : 0); | ||
| 1446 | if (err) | ||
| 1447 | return err; | ||
| 1448 | |||
| 1449 | /* Enable modem to codec CDC for call*/ | ||
| 1450 | mask = BIT(CPCAP_BIT_CDC_CLK_EN); | ||
| 1451 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, | ||
| 1452 | mask, voice_call ? mask : 0); | ||
| 1453 | |||
| 1454 | return err; | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | static int cpcap_voice_set_tdm_slot(struct snd_soc_dai *dai, | ||
| 1458 | unsigned int tx_mask, unsigned int rx_mask, | ||
| 1459 | int slots, int slot_width) | ||
| 1460 | { | ||
| 1461 | struct snd_soc_component *component = dai->component; | ||
| 1462 | struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); | ||
| 1463 | int err, ts_mask, mask; | ||
| 1464 | bool voice_call; | ||
| 1465 | |||
| 1466 | /* | ||
| 1467 | * Primitive test for voice call, probably needs more checks | ||
| 1468 | * later on for 16-bit calls detected, Bluetooth headset etc. | ||
| 1469 | */ | ||
| 1470 | if (tx_mask == 0 && rx_mask == 1 && slot_width == 8) | ||
| 1471 | voice_call = true; | ||
| 1472 | else | ||
| 1473 | voice_call = false; | ||
| 1474 | |||
| 1475 | ts_mask = 0x7 << CPCAP_BIT_MIC2_TIMESLOT0; | ||
| 1476 | ts_mask |= 0x7 << CPCAP_BIT_MIC1_RX_TIMESLOT0; | ||
| 1477 | |||
| 1478 | mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0; | ||
| 1479 | mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0; | ||
| 1480 | |||
| 1481 | err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, | ||
| 1482 | ts_mask, mask); | ||
| 1483 | if (err) | ||
| 1484 | return err; | ||
| 1485 | |||
| 1486 | err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, slot_width * 1000); | ||
| 1487 | if (err) | ||
| 1488 | return err; | ||
| 1489 | |||
| 1490 | err = cpcap_voice_call(cpcap, dai, voice_call); | ||
| 1491 | if (err) | ||
| 1492 | return err; | ||
| 1493 | |||
| 1494 | return 0; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute, int direction) | ||
| 1376 | { | 1498 | { |
| 1377 | struct snd_soc_component *component = dai->component; | 1499 | struct snd_soc_component *component = dai->component; |
| 1378 | struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); | 1500 | struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); |
| @@ -1393,6 +1515,7 @@ static const struct snd_soc_dai_ops cpcap_dai_voice_ops = { · 14 unmodified lines | |||
| 1393 | .hw_params = cpcap_voice_hw_params, | 1515 | .hw_params = cpcap_voice_hw_params, |
| 1394 | .set_sysclk = cpcap_voice_set_dai_sysclk, | 1516 | .set_sysclk = cpcap_voice_set_dai_sysclk, |
| 1395 | .set_fmt = cpcap_voice_set_dai_fmt, | 1517 | .set_fmt = cpcap_voice_set_dai_fmt, |
| 1518 | .set_tdm_slot = cpcap_voice_set_tdm_slot, | ||
| 1396 | .mute_stream = cpcap_voice_set_mute, | 1519 | .mute_stream = cpcap_voice_set_mute, |
| 1397 | .no_capture_mute = 1, | 1520 | .no_capture_mute = 1, |
| 1398 | }; | 1521 | }; |
| @@ -1011,6 +1011,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) · 1010 unmodified lines | |||
| 1011 | } | 1011 | } |
| 1012 | priv->ec_capabilities = r.capabilities; | 1012 | priv->ec_capabilities = r.capabilities; |
| 1013 | 1013 | ||
| 1014 | /* Reset EC codec i2s rx. */ | ||
| 1015 | p.cmd = EC_CODEC_I2S_RX_RESET; | ||
| 1016 | ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, | ||
| 1017 | (uint8_t *)&p, sizeof(p), NULL, 0); | ||
| 1018 | if (ret == -ENOPROTOOPT) { | ||
| 1019 | dev_info(dev, | ||
| 1020 | "Missing reset command. Please update EC firmware.\n"); | ||
| 1021 | } else if (ret) { | ||
| 1022 | dev_err(dev, "failed to EC_CODEC_I2S_RESET: %d\n", ret); | ||
| 1023 | return ret; | ||
| 1024 | } | ||
| 1025 | |||
| 1014 | platform_set_drvdata(pdev, priv); | 1026 | platform_set_drvdata(pdev, priv); |
| 1015 | 1027 | ||
| 1016 | ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver, | 1028 | ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver, |
| @@ -194,7 +194,7 @@ static struct snd_soc_dai_driver cs35l32_dai[] = { · 193 unmodified lines | |||
| 194 | .formats = CS35L32_FORMATS, | 194 | .formats = CS35L32_FORMATS, |
| 195 | }, | 195 | }, |
| 196 | .ops = &cs35l32_ops, | 196 | .ops = &cs35l32_ops, |
| 197 | .symmetric_rates = 1, | 197 | .symmetric_rate = 1, |
| 198 | } | 198 | } |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| @@ -691,7 +691,7 @@ static struct snd_soc_dai_driver cs35l33_dai = { · 690 unmodified lines | |||
| 691 | .formats = CS35L33_FORMATS, | 691 | .formats = CS35L33_FORMATS, |
| 692 | }, | 692 | }, |
| 693 | .ops = &cs35l33_ops, | 693 | .ops = &cs35l33_ops, |
| 694 | .symmetric_rates = 1, | 694 | .symmetric_rate = 1, |
| 695 | }; | 695 | }; |
| 696 | 696 | ||
| 697 | static int cs35l33_set_hg_data(struct snd_soc_component *component, | 697 | static int cs35l33_set_hg_data(struct snd_soc_component *component, |
| @@ -666,7 +666,7 @@ static struct snd_soc_dai_driver cs35l34_dai = { · 665 unmodified lines | |||
| 666 | .formats = CS35L34_FORMATS, | 666 | .formats = CS35L34_FORMATS, |
| 667 | }, | 667 | }, |
| 668 | .ops = &cs35l34_ops, | 668 | .ops = &cs35l34_ops, |
| 669 | .symmetric_rates = 1, | 669 | .symmetric_rate = 1, |
| 670 | }; | 670 | }; |
| 671 | 671 | ||
| 672 | static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34, | 672 | static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34, |
| @@ -692,7 +692,7 @@ static struct snd_soc_dai_driver cs35l35_dai[] = { · 691 unmodified lines | |||
| 692 | .formats = CS35L35_FORMATS, | 692 | .formats = CS35L35_FORMATS, |
| 693 | }, | 693 | }, |
| 694 | .ops = &cs35l35_ops, | 694 | .ops = &cs35l35_ops, |
| 695 | .symmetric_rates = 1, | 695 | .symmetric_rate = 1, |
| 696 | }, | 696 | }, |
| 697 | { | 697 | { |
| 698 | .name = "cs35l35-pdm", | 698 | .name = "cs35l35-pdm", |
| @@ -995,7 +995,7 @@ static struct snd_soc_dai_driver cs35l36_dai[] = { · 994 unmodified lines | |||
| 995 | .formats = CS35L36_TX_FORMATS, | 995 | .formats = CS35L36_TX_FORMATS, |
| 996 | }, | 996 | }, |
| 997 | .ops = &cs35l36_ops, | 997 | .ops = &cs35l36_ops, |
| 998 | .symmetric_rates = 1, | 998 | .symmetric_rate = 1, |
| 999 | }, | 999 | }, |
| 1000 | }; | 1000 | }; |
| 1001 | 1001 | ||
| @@ -585,7 +585,7 @@ static struct snd_soc_dai_driver cs4234_dai[] = { · 584 unmodified lines | |||
| 585 | .formats = CS4234_FORMATS, | 585 | .formats = CS4234_FORMATS, |
| 586 | }, | 586 | }, |
| 587 | .ops = &cs4234_dai_ops, | 587 | .ops = &cs4234_dai_ops, |
| 588 | .symmetric_rates = 1, | 588 | .symmetric_rate = 1, |
| 589 | }, | 589 | }, |
| 590 | }; | 590 | }; |
| 591 | 591 | ||
| @@ -481,7 +481,7 @@ static struct snd_soc_dai_driver cs4271_dai = { · 480 unmodified lines | |||
| 481 | .formats = CS4271_PCM_FORMATS, | 481 | .formats = CS4271_PCM_FORMATS, |
| 482 | }, | 482 | }, |
| 483 | .ops = &cs4271_dai_ops, | 483 | .ops = &cs4271_dai_ops, |
| 484 | .symmetric_rates = 1, | 484 | .symmetric_rate = 1, |
| 485 | }; | 485 | }; |
| 486 | 486 | ||
| 487 | static int cs4271_reset(struct snd_soc_component *component) | 487 | static int cs4271_reset(struct snd_soc_component *component) |
| @@ -1250,6 +1250,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, · 1249 unmodified lines | |||
| 1250 | dev_err(&i2c_client->dev, | 1250 | dev_err(&i2c_client->dev, |
| 1251 | "CS42L56 Device ID (%X). Expected %X\n", | 1251 | "CS42L56 Device ID (%X). Expected %X\n", |
| 1252 | devid, CS42L56_DEVID); | 1252 | devid, CS42L56_DEVID); |
| 1253 | ret = -EINVAL; | ||
| 1253 | goto err_enable; | 1254 | goto err_enable; |
| 1254 | } | 1255 | } |
| 1255 | alpha_rev = reg & CS42L56_AREV_MASK; | 1256 | alpha_rev = reg & CS42L56_AREV_MASK; |
| @@ -1307,7 +1308,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, · 51 unmodified lines | |||
| 1307 | ret = devm_snd_soc_register_component(&i2c_client->dev, | 1308 | ret = devm_snd_soc_register_component(&i2c_client->dev, |
| 1308 | &soc_component_dev_cs42l56, &cs42l56_dai, 1); | 1309 | &soc_component_dev_cs42l56, &cs42l56_dai, 1); |
| 1309 | if (ret < 0) | 1310 | if (ret < 0) |
| 1310 | return ret; | 1311 | goto err_enable; |
| 1311 | 1312 | ||
| 1312 | return 0; | 1313 | return 0; |
| 1313 | 1314 | ||
| @@ -1181,7 +1181,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 1180 unmodified lines | |||
| 1181 | .formats = CS42L73_FORMATS, | 1181 | .formats = CS42L73_FORMATS, |
| 1182 | }, | 1182 | }, |
| 1183 | .ops = &cs42l73_ops, | 1183 | .ops = &cs42l73_ops, |
| 1184 | .symmetric_rates = 1, | 1184 | .symmetric_rate = 1, |
| 1185 | }, | 1185 | }, |
| 1186 | { | 1186 | { |
| 1187 | .name = "cs42l73-asp", | 1187 | .name = "cs42l73-asp", |
| @@ -1201,7 +1201,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 13 unmodified lines | |||
| 1201 | .formats = CS42L73_FORMATS, | 1201 | .formats = CS42L73_FORMATS, |
| 1202 | }, | 1202 | }, |
| 1203 | .ops = &cs42l73_ops, | 1203 | .ops = &cs42l73_ops, |
| 1204 | .symmetric_rates = 1, | 1204 | .symmetric_rate = 1, |
| 1205 | }, | 1205 | }, |
| 1206 | { | 1206 | { |
| 1207 | .name = "cs42l73-vsp", | 1207 | .name = "cs42l73-vsp", |
| @@ -1221,7 +1221,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 13 unmodified lines | |||
| 1221 | .formats = CS42L73_FORMATS, | 1221 | .formats = CS42L73_FORMATS, |
| 1222 | }, | 1222 | }, |
| 1223 | .ops = &cs42l73_ops, | 1223 | .ops = &cs42l73_ops, |
| 1224 | .symmetric_rates = 1, | 1224 | .symmetric_rate = 1, |
| 1225 | } | 1225 | } |
| 1226 | }; | 1226 | }; |
| 1227 | 1227 | ||
| @@ -1581,7 +1581,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { · 1580 unmodified lines | |||
| 1581 | .formats = CS43130_PCM_FORMATS, | 1581 | .formats = CS43130_PCM_FORMATS, |
| 1582 | }, | 1582 | }, |
| 1583 | .ops = &cs43130_pcm_ops, | 1583 | .ops = &cs43130_pcm_ops, |
| 1584 | .symmetric_rates = 1, | 1584 | .symmetric_rate = 1, |
| 1585 | }, | 1585 | }, |
| 1586 | { | 1586 | { |
| 1587 | .name = "cs43130-asp-dop", | 1587 | .name = "cs43130-asp-dop", |
| @@ -1594,7 +1594,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { · 6 unmodified lines | |||
| 1594 | .formats = CS43130_DOP_FORMATS, | 1594 | .formats = CS43130_DOP_FORMATS, |
| 1595 | }, | 1595 | }, |
| 1596 | .ops = &cs43130_dop_ops, | 1596 | .ops = &cs43130_dop_ops, |
| 1597 | .symmetric_rates = 1, | 1597 | .symmetric_rate = 1, |
| 1598 | }, | 1598 | }, |
| 1599 | { | 1599 | { |
| 1600 | .name = "cs43130-xsp-dop", | 1600 | .name = "cs43130-xsp-dop", |
| @@ -1607,7 +1607,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { · 6 unmodified lines | |||
| 1607 | .formats = CS43130_DOP_FORMATS, | 1607 | .formats = CS43130_DOP_FORMATS, |
| 1608 | }, | 1608 | }, |
| 1609 | .ops = &cs43130_dop_ops, | 1609 | .ops = &cs43130_dop_ops, |
| 1610 | .symmetric_rates = 1, | 1610 | .symmetric_rate = 1, |
| 1611 | }, | 1611 | }, |
| 1612 | { | 1612 | { |
| 1613 | .name = "cs43130-xsp-dsd", | 1613 | .name = "cs43130-xsp-dsd", |
| @@ -189,7 +189,7 @@ static struct snd_soc_dai_driver cs4341_dai = { · 188 unmodified lines | |||
| 189 | SNDRV_PCM_FMTBIT_S24_LE, | 189 | SNDRV_PCM_FMTBIT_S24_LE, |
| 190 | }, | 190 | }, |
| 191 | .ops = &cs4341_dai_ops, | 191 | .ops = &cs4341_dai_ops, |
| 192 | .symmetric_rates = 1, | 192 | .symmetric_rate = 1, |
| 193 | }; | 193 | }; |
| 194 | 194 | ||
| 195 | static const struct snd_soc_component_driver soc_component_cs4341 = { | 195 | static const struct snd_soc_component_driver soc_component_cs4341 = { |
| @@ -250,7 +250,7 @@ static struct snd_soc_dai_driver cs4349_dai = { · 249 unmodified lines | |||
| 250 | .formats = CS4349_PCM_FORMATS, | 250 | .formats = CS4349_PCM_FORMATS, |
| 251 | }, | 251 | }, |
| 252 | .ops = &cs4349_dai_ops, | 252 | .ops = &cs4349_dai_ops, |
| 253 | .symmetric_rates = 1, | 253 | .symmetric_rate = 1, |
| 254 | }; | 254 | }; |
| 255 | 255 | ||
| 256 | static const struct snd_soc_component_driver soc_component_dev_cs4349 = { | 256 | static const struct snd_soc_component_driver soc_component_dev_cs4349 = { |
| @@ -1160,8 +1160,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { · 1159 unmodified lines | |||
| 1160 | .formats = MADERA_FORMATS, | 1160 | .formats = MADERA_FORMATS, |
| 1161 | }, | 1161 | }, |
| 1162 | .ops = &madera_dai_ops, | 1162 | .ops = &madera_dai_ops, |
| 1163 | .symmetric_rates = 1, | 1163 | .symmetric_rate = 1, |
| 1164 | .symmetric_samplebits = 1, | 1164 | .symmetric_sample_bits = 1, |
| 1165 | }, | 1165 | }, |
| 1166 | { | 1166 | { |
| 1167 | .name = "cs47l15-aif2", | 1167 | .name = "cs47l15-aif2", |
| @@ -1182,8 +1182,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { · 14 unmodified lines | |||
| 1182 | .formats = MADERA_FORMATS, | 1182 | .formats = MADERA_FORMATS, |
| 1183 | }, | 1183 | }, |
| 1184 | .ops = &madera_dai_ops, | 1184 | .ops = &madera_dai_ops, |
| 1185 | .symmetric_rates = 1, | 1185 | .symmetric_rate = 1, |
| 1186 | .symmetric_samplebits = 1, | 1186 | .symmetric_sample_bits = 1, |
| 1187 | }, | 1187 | }, |
| 1188 | { | 1188 | { |
| 1189 | .name = "cs47l15-aif3", | 1189 | .name = "cs47l15-aif3", |
| @@ -1204,8 +1204,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { · 14 unmodified lines | |||
| 1204 | .formats = MADERA_FORMATS, | 1204 | .formats = MADERA_FORMATS, |
| 1205 | }, | 1205 | }, |
| 1206 | .ops = &madera_dai_ops, | 1206 | .ops = &madera_dai_ops, |
| 1207 | .symmetric_rates = 1, | 1207 | .symmetric_rate = 1, |
| 1208 | .symmetric_samplebits = 1, | 1208 | .symmetric_sample_bits = 1, |
| 1209 | }, | 1209 | }, |
| 1210 | { | 1210 | { |
| 1211 | .name = "cs47l15-cpu-trace", | 1211 | .name = "cs47l15-cpu-trace", |
| @@ -977,8 +977,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 976 unmodified lines | |||
| 977 | .formats = CS47L24_FORMATS, | 977 | .formats = CS47L24_FORMATS, |
| 978 | }, | 978 | }, |
| 979 | .ops = &arizona_dai_ops, | 979 | .ops = &arizona_dai_ops, |
| 980 | .symmetric_rates = 1, | 980 | .symmetric_rate = 1, |
| 981 | .symmetric_samplebits = 1, | 981 | .symmetric_sample_bits = 1, |
| 982 | }, | 982 | }, |
| 983 | { | 983 | { |
| 984 | .name = "cs47l24-aif2", | 984 | .name = "cs47l24-aif2", |
| @@ -999,8 +999,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 14 unmodified lines | |||
| 999 | .formats = CS47L24_FORMATS, | 999 | .formats = CS47L24_FORMATS, |
| 1000 | }, | 1000 | }, |
| 1001 | .ops = &arizona_dai_ops, | 1001 | .ops = &arizona_dai_ops, |
| 1002 | .symmetric_rates = 1, | 1002 | .symmetric_rate = 1, |
| 1003 | .symmetric_samplebits = 1, | 1003 | .symmetric_sample_bits = 1, |
| 1004 | }, | 1004 | }, |
| 1005 | { | 1005 | { |
| 1006 | .name = "cs47l24-aif3", | 1006 | .name = "cs47l24-aif3", |
| @@ -1021,8 +1021,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 14 unmodified lines | |||
| 1021 | .formats = CS47L24_FORMATS, | 1021 | .formats = CS47L24_FORMATS, |
| 1022 | }, | 1022 | }, |
| 1023 | .ops = &arizona_dai_ops, | 1023 | .ops = &arizona_dai_ops, |
| 1024 | .symmetric_rates = 1, | 1024 | .symmetric_rate = 1, |
| 1025 | .symmetric_samplebits = 1, | 1025 | .symmetric_sample_bits = 1, |
| 1026 | }, | 1026 | }, |
| 1027 | { | 1027 | { |
| 1028 | .name = "cs47l24-cpu-voicectrl", | 1028 | .name = "cs47l24-cpu-voicectrl", |
| @@ -1368,8 +1368,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 1367 unmodified lines | |||
| 1368 | .formats = MADERA_FORMATS, | 1368 | .formats = MADERA_FORMATS, |
| 1369 | }, | 1369 | }, |
| 1370 | .ops = &madera_dai_ops, | 1370 | .ops = &madera_dai_ops, |
| 1371 | .symmetric_rates = 1, | 1371 | .symmetric_rate = 1, |
| 1372 | .symmetric_samplebits = 1, | 1372 | .symmetric_sample_bits = 1, |
| 1373 | }, | 1373 | }, |
| 1374 | { | 1374 | { |
| 1375 | .name = "cs47l35-aif2", | 1375 | .name = "cs47l35-aif2", |
| @@ -1390,8 +1390,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 14 unmodified lines | |||
| 1390 | .formats = MADERA_FORMATS, | 1390 | .formats = MADERA_FORMATS, |
| 1391 | }, | 1391 | }, |
| 1392 | .ops = &madera_dai_ops, | 1392 | .ops = &madera_dai_ops, |
| 1393 | .symmetric_rates = 1, | 1393 | .symmetric_rate = 1, |
| 1394 | .symmetric_samplebits = 1, | 1394 | .symmetric_sample_bits = 1, |
| 1395 | }, | 1395 | }, |
| 1396 | { | 1396 | { |
| 1397 | .name = "cs47l35-aif3", | 1397 | .name = "cs47l35-aif3", |
| @@ -1412,8 +1412,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 14 unmodified lines | |||
| 1412 | .formats = MADERA_FORMATS, | 1412 | .formats = MADERA_FORMATS, |
| 1413 | }, | 1413 | }, |
| 1414 | .ops = &madera_dai_ops, | 1414 | .ops = &madera_dai_ops, |
| 1415 | .symmetric_rates = 1, | 1415 | .symmetric_rate = 1, |
| 1416 | .symmetric_samplebits = 1, | 1416 | .symmetric_sample_bits = 1, |
| 1417 | }, | 1417 | }, |
| 1418 | { | 1418 | { |
| 1419 | .name = "cs47l35-slim1", | 1419 | .name = "cs47l35-slim1", |
| @@ -2269,8 +2269,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 2268 unmodified lines | |||
| 2269 | .formats = MADERA_FORMATS, | 2269 | .formats = MADERA_FORMATS, |
| 2270 | }, | 2270 | }, |
| 2271 | .ops = &madera_dai_ops, | 2271 | .ops = &madera_dai_ops, |
| 2272 | .symmetric_rates = 1, | 2272 | .symmetric_rate = 1, |
| 2273 | .symmetric_samplebits = 1, | 2273 | .symmetric_sample_bits = 1, |
| 2274 | }, | 2274 | }, |
| 2275 | { | 2275 | { |
| 2276 | .name = "cs47l85-aif2", | 2276 | .name = "cs47l85-aif2", |
| @@ -2291,8 +2291,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | |||
| 2291 | .formats = MADERA_FORMATS, | 2291 | .formats = MADERA_FORMATS, |
| 2292 | }, | 2292 | }, |
| 2293 | .ops = &madera_dai_ops, | 2293 | .ops = &madera_dai_ops, |
| 2294 | .symmetric_rates = 1, | 2294 | .symmetric_rate = 1, |
| 2295 | .symmetric_samplebits = 1, | 2295 | .symmetric_sample_bits = 1, |
| 2296 | }, | 2296 | }, |
| 2297 | { | 2297 | { |
| 2298 | .name = "cs47l85-aif3", | 2298 | .name = "cs47l85-aif3", |
| @@ -2313,8 +2313,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | |||
| 2313 | .formats = MADERA_FORMATS, | 2313 | .formats = MADERA_FORMATS, |
| 2314 | }, | 2314 | }, |
| 2315 | .ops = &madera_dai_ops, | 2315 | .ops = &madera_dai_ops, |
| 2316 | .symmetric_rates = 1, | 2316 | .symmetric_rate = 1, |
| 2317 | .symmetric_samplebits = 1, | 2317 | .symmetric_sample_bits = 1, |
| 2318 | }, | 2318 | }, |
| 2319 | { | 2319 | { |
| 2320 | .name = "cs47l85-aif4", | 2320 | .name = "cs47l85-aif4", |
| @@ -2335,8 +2335,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | |||
| 2335 | .formats = MADERA_FORMATS, | 2335 | .formats = MADERA_FORMATS, |
| 2336 | }, | 2336 | }, |
| 2337 | .ops = &madera_dai_ops, | 2337 | .ops = &madera_dai_ops, |
| 2338 | .symmetric_rates = 1, | 2338 | .symmetric_rate = 1, |
| 2339 | .symmetric_samplebits = 1, | 2339 | .symmetric_sample_bits = 1, |
| 2340 | }, | 2340 | }, |
| 2341 | { | 2341 | { |
| 2342 | .name = "cs47l85-slim1", | 2342 | .name = "cs47l85-slim1", |
| @@ -2188,8 +2188,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 2187 unmodified lines | |||
| 2188 | .formats = MADERA_FORMATS, | 2188 | .formats = MADERA_FORMATS, |
| 2189 | }, | 2189 | }, |
| 2190 | .ops = &madera_dai_ops, | 2190 | .ops = &madera_dai_ops, |
| 2191 | .symmetric_rates = 1, | 2191 | .symmetric_rate = 1, |
| 2192 | .symmetric_samplebits = 1, | 2192 | .symmetric_sample_bits = 1, |
| 2193 | }, | 2193 | }, |
| 2194 | { | 2194 | { |
| 2195 | .name = "cs47l90-aif2", | 2195 | .name = "cs47l90-aif2", |
| @@ -2210,8 +2210,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | |||
| 2210 | .formats = MADERA_FORMATS, | 2210 | .formats = MADERA_FORMATS, |
| 2211 | }, | 2211 | }, |
| 2212 | .ops = &madera_dai_ops, | 2212 | .ops = &madera_dai_ops, |
| 2213 | .symmetric_rates = 1, | 2213 | .symmetric_rate = 1, |
| 2214 | .symmetric_samplebits = 1, | 2214 | .symmetric_sample_bits = 1, |
| 2215 | }, | 2215 | }, |
| 2216 | { | 2216 | { |
| 2217 | .name = "cs47l90-aif3", | 2217 | .name = "cs47l90-aif3", |
| @@ -2232,8 +2232,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | |||
| 2232 | .formats = MADERA_FORMATS, | 2232 | .formats = MADERA_FORMATS, |
| 2233 | }, | 2233 | }, |
| 2234 | .ops = &madera_dai_ops, | 2234 | .ops = &madera_dai_ops, |
| 2235 | .symmetric_rates = 1, | 2235 | .symmetric_rate = 1, |
| 2236 | .symmetric_samplebits = 1, | 2236 | .symmetric_sample_bits = 1, |
| 2237 | }, | 2237 | }, |
| 2238 | { | 2238 | { |
| 2239 | .name = "cs47l90-aif4", | 2239 | .name = "cs47l90-aif4", |
| @@ -2254,8 +2254,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | |||
| 2254 | .formats = MADERA_FORMATS, | 2254 | .formats = MADERA_FORMATS, |
| 2255 | }, | 2255 | }, |
| 2256 | .ops = &madera_dai_ops, | 2256 | .ops = &madera_dai_ops, |
| 2257 | .symmetric_rates = 1, | 2257 | .symmetric_rate = 1, |
| 2258 | .symmetric_samplebits = 1, | 2258 | .symmetric_sample_bits = 1, |
| 2259 | }, | 2259 | }, |
| 2260 | { | 2260 | { |
| 2261 | .name = "cs47l90-slim1", | 2261 | .name = "cs47l90-slim1", |
| @@ -1704,8 +1704,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 1703 unmodified lines | |||
| 1704 | .formats = MADERA_FORMATS, | 1704 | .formats = MADERA_FORMATS, |
| 1705 | }, | 1705 | }, |
| 1706 | .ops = &madera_dai_ops, | 1706 | .ops = &madera_dai_ops, |
| 1707 | .symmetric_rates = 1, | 1707 | .symmetric_rate = 1, |
| 1708 | .symmetric_samplebits = 1, | 1708 | .symmetric_sample_bits = 1, |
| 1709 | }, | 1709 | }, |
| 1710 | { | 1710 | { |
| 1711 | .name = "cs47l92-aif2", | 1711 | .name = "cs47l92-aif2", |
| @@ -1726,8 +1726,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 14 unmodified lines | |||
| 1726 | .formats = MADERA_FORMATS, | 1726 | .formats = MADERA_FORMATS, |
| 1727 | }, | 1727 | }, |
| 1728 | .ops = &madera_dai_ops, | 1728 | .ops = &madera_dai_ops, |
| 1729 | .symmetric_rates = 1, | 1729 | .symmetric_rate = 1, |
| 1730 | .symmetric_samplebits = 1, | 1730 | .symmetric_sample_bits = 1, |
| 1731 | }, | 1731 | }, |
| 1732 | { | 1732 | { |
| 1733 | .name = "cs47l92-aif3", | 1733 | .name = "cs47l92-aif3", |
| @@ -1748,8 +1748,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 14 unmodified lines | |||
| 1748 | .formats = MADERA_FORMATS, | 1748 | .formats = MADERA_FORMATS, |
| 1749 | }, | 1749 | }, |
| 1750 | .ops = &madera_dai_ops, | 1750 | .ops = &madera_dai_ops, |
| 1751 | .symmetric_rates = 1, | 1751 | .symmetric_rate = 1, |
| 1752 | .symmetric_samplebits = 1, | 1752 | .symmetric_sample_bits = 1, |
| 1753 | }, | 1753 | }, |
| 1754 | { | 1754 | { |
| 1755 | .name = "cs47l92-slim1", | 1755 | .name = "cs47l92-slim1", |
| @@ -869,7 +869,7 @@ static struct snd_soc_dai_driver cs53l30_dai = { · 868 unmodified lines | |||
| 869 | .formats = CS53L30_FORMATS, | 869 | .formats = CS53L30_FORMATS, |
| 870 | }, | 870 | }, |
| 871 | .ops = &cs53l30_ops, | 871 | .ops = &cs53l30_ops, |
| 872 | .symmetric_rates = 1, | 872 | .symmetric_rate = 1, |
| 873 | }; | 873 | }; |
| 874 | 874 | ||
| 875 | static int cs53l30_component_probe(struct snd_soc_component *component) | 875 | static int cs53l30_component_probe(struct snd_soc_component *component) |
| @@ -1572,7 +1572,7 @@ static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = { · 1571 unmodified lines | |||
| 1572 | .formats = CX2072X_FORMATS, | 1572 | .formats = CX2072X_FORMATS, |
| 1573 | }, | 1573 | }, |
| 1574 | .ops = &cx2072x_dai_ops, | 1574 | .ops = &cx2072x_dai_ops, |
| 1575 | .symmetric_rates = 1, | 1575 | .symmetric_rate = 1, |
| 1576 | }, | 1576 | }, |
| 1577 | { /* plabayck only, return echo reference to Conexant DSP chip */ | 1577 | { /* plabayck only, return echo reference to Conexant DSP chip */ |
| 1578 | .name = "cx2072x-dsp", | 1578 | .name = "cx2072x-dsp", |
| @@ -1059,7 +1059,7 @@ static struct snd_soc_dai_driver da7210_dai = { · 1058 unmodified lines | |||
| 1059 | .formats = DA7210_FORMATS, | 1059 | .formats = DA7210_FORMATS, |
| 1060 | }, | 1060 | }, |
| 1061 | .ops = &da7210_dai_ops, | 1061 | .ops = &da7210_dai_ops, |
| 1062 | .symmetric_rates = 1, | 1062 | .symmetric_rate = 1, |
| 1063 | }; | 1063 | }; |
| 1064 | 1064 | ||
| 1065 | static int da7210_probe(struct snd_soc_component *component) | 1065 | static int da7210_probe(struct snd_soc_component *component) |
| @@ -1551,7 +1551,7 @@ static struct snd_soc_dai_driver da7213_dai = { · 1550 unmodified lines | |||
| 1551 | .formats = DA7213_FORMATS, | 1551 | .formats = DA7213_FORMATS, |
| 1552 | }, | 1552 | }, |
| 1553 | .ops = &da7213_dai_ops, | 1553 | .ops = &da7213_dai_ops, |
| 1554 | .symmetric_rates = 1, | 1554 | .symmetric_rate = 1, |
| 1555 | }; | 1555 | }; |
| 1556 | 1556 | ||
| 1557 | static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable) | 1557 | static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable) |
| @@ -2194,9 +2194,9 @@ static struct snd_soc_dai_driver da7218_dai = { · 2193 unmodified lines | |||
| 2194 | .formats = DA7218_FORMATS, | 2194 | .formats = DA7218_FORMATS, |
| 2195 | }, | 2195 | }, |
| 2196 | .ops = &da7218_dai_ops, | 2196 | .ops = &da7218_dai_ops, |
| 2197 | .symmetric_rates = 1, | 2197 | .symmetric_rate = 1, |
| 2198 | .symmetric_channels = 1, | 2198 | .symmetric_channels = 1, |
| 2199 | .symmetric_samplebits = 1, | 2199 | .symmetric_sample_bits = 1, |
| 2200 | }; | 2200 | }; |
| 2201 | 2201 | ||
| 2202 | 2202 | ||
| @@ -2278,14 +2278,12 @@ static irqreturn_t da7218_irq_thread(int irq, void *data) · 75 unmodified lines | |||
| 2278 | * DT | 2278 | * DT |
| 2279 | */ | 2279 | */ |
| 2280 | 2280 | ||
| 2281 | #ifdef CONFIG_OF | ||
| 2282 | static const struct of_device_id da7218_of_match[] = { | 2281 | static const struct of_device_id da7218_of_match[] = { |
| 2283 | { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID }, | 2282 | { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID }, |
| 2284 | { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID }, | 2283 | { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID }, |
| 2285 | { } | 2284 | { } |
| 2286 | }; | 2285 | }; |
| 2287 | MODULE_DEVICE_TABLE(of, da7218_of_match); | 2286 | MODULE_DEVICE_TABLE(of, da7218_of_match); |
| 2288 | #endif | ||
| 2289 | 2287 | ||
| 2290 | static inline int da7218_of_get_id(struct device *dev) | 2288 | static inline int da7218_of_get_id(struct device *dev) |
| 2291 | { | 2289 | { |
| @@ -3311,7 +3309,7 @@ MODULE_DEVICE_TABLE(i2c, da7218_i2c_id); · 1019 unmodified lines | |||
| 3311 | static struct i2c_driver da7218_i2c_driver = { | 3309 | static struct i2c_driver da7218_i2c_driver = { |
| 3312 | .driver = { | 3310 | .driver = { |
| 3313 | .name = "da7218", | 3311 | .name = "da7218", |
| 3314 | .of_match_table = of_match_ptr(da7218_of_match), | 3312 | .of_match_table = da7218_of_match, |
| 3315 | }, | 3313 | }, |
| 3316 | .probe = da7218_i2c_probe, | 3314 | .probe = da7218_i2c_probe, |
| 3317 | .id_table = da7218_i2c_id, | 3315 | .id_table = da7218_i2c_id, |
| @@ -1692,9 +1692,9 @@ static struct snd_soc_dai_driver da7219_dai = { · 1691 unmodified lines | |||
| 1692 | .formats = DA7219_FORMATS, | 1692 | .formats = DA7219_FORMATS, |
| 1693 | }, | 1693 | }, |
| 1694 | .ops = &da7219_dai_ops, | 1694 | .ops = &da7219_dai_ops, |
| 1695 | .symmetric_rates = 1, | 1695 | .symmetric_rate = 1, |
| 1696 | .symmetric_channels = 1, | 1696 | .symmetric_channels = 1, |
| 1697 | .symmetric_samplebits = 1, | 1697 | .symmetric_sample_bits = 1, |
| 1698 | }; | 1698 | }; |
| 1699 | 1699 | ||
| 1700 | 1700 | ||
| @@ -1347,7 +1347,7 @@ static struct snd_soc_dai_driver da9055_dai = { · 1346 unmodified lines | |||
| 1347 | .formats = DA9055_FORMATS, | 1347 | .formats = DA9055_FORMATS, |
| 1348 | }, | 1348 | }, |
| 1349 | .ops = &da9055_dai_ops, | 1349 | .ops = &da9055_dai_ops, |
| 1350 | .symmetric_rates = 1, | 1350 | .symmetric_rate = 1, |
| 1351 | }; | 1351 | }; |
| 1352 | 1352 | ||
| 1353 | static int da9055_set_bias_level(struct snd_soc_component *component, | 1353 | static int da9055_set_bias_level(struct snd_soc_component *component, |
| @@ -543,7 +543,7 @@ static struct snd_soc_dai_driver es8316_dai = { · 542 unmodified lines | |||
| 543 | .formats = ES8316_FORMATS, | 543 | .formats = ES8316_FORMATS, |
| 544 | }, | 544 | }, |
| 545 | .ops = &es8316_ops, | 545 | .ops = &es8316_ops, |
| 546 | .symmetric_rates = 1, | 546 | .symmetric_rate = 1, |
| 547 | }; | 547 | }; |
| 548 | 548 | ||
| 549 | static void es8316_enable_micbias_for_mic_gnd_short_detect( | 549 | static void es8316_enable_micbias_for_mic_gnd_short_detect( |
| @@ -681,6 +681,9 @@ static void es8316_disable_jack_detect(struct snd_soc_component *component) · 131 unmodified lines | |||
| 681 | { | 681 | { |
| 682 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); | 682 | struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); |
| 683 | 683 | ||
| 684 | if (!es8316->jack) | ||
| 685 | return; /* Already disabled (or never enabled) */ | ||
| 686 | |||
| 684 | disable_irq(es8316->irq); | 687 | disable_irq(es8316->irq); |
| 685 | 688 | ||
| 686 | mutex_lock(&es8316->lock); | 689 | mutex_lock(&es8316->lock); |
| @@ -715,7 +715,7 @@ static struct snd_soc_dai_driver es8328_dai = { · 714 unmodified lines | |||
| 715 | .formats = ES8328_FORMATS, | 715 | .formats = ES8328_FORMATS, |
| 716 | }, | 716 | }, |
| 717 | .ops = &es8328_dai_ops, | 717 | .ops = &es8328_dai_ops, |
| 718 | .symmetric_rates = 1, | 718 | .symmetric_rate = 1, |
| 719 | }; | 719 | }; |
| 720 | 720 | ||
| 721 | static int es8328_suspend(struct snd_soc_component *component) | 721 | static int es8328_suspend(struct snd_soc_component *component) |
| @@ -809,8 +809,7 @@ static void es8328_remove(struct snd_soc_component *component) · 87 unmodified lines | |||
| 809 | 809 | ||
| 810 | es8328 = snd_soc_component_get_drvdata(component); | 810 | es8328 = snd_soc_component_get_drvdata(component); |
| 811 | 811 | ||
| 812 | if (es8328->clk) | 812 | clk_disable_unprepare(es8328->clk); |
| 813 | clk_disable_unprepare(es8328->clk); | ||
| 814 | 813 | ||
| 815 | regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), | 814 | regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), |
| 816 | es8328->supplies); | 815 | es8328->supplies); |
| @@ -489,6 +489,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, · 488 unmodified lines | |||
| 489 | hp.sample_rate = params_rate(params); | 489 | hp.sample_rate = params_rate(params); |
| 490 | hp.channels = params_channels(params); | 490 | hp.channels = params_channels(params); |
| 491 | 491 | ||
| 492 | cf->bit_fmt = params_format(params); | ||
| 492 | return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, | 493 | return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, |
| 493 | cf, &hp); | 494 | cf, &hp); |
| 494 | } | 495 | } |
| @@ -617,7 +618,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { · 122 unmodified lines | |||
| 617 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ | 618 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ |
| 618 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ | 619 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ |
| 619 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ | 620 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ |
| 620 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | 621 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ |
| 622 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) | ||
| 621 | 623 | ||
| 622 | static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, | 624 | static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 623 | struct snd_soc_dai *dai) | 625 | struct snd_soc_dai *dai) |
| @@ -325,7 +325,7 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = { · 324 unmodified lines | |||
| 325 | .formats = RK3036_CODEC_FMTS, | 325 | .formats = RK3036_CODEC_FMTS, |
| 326 | }, | 326 | }, |
| 327 | .ops = &rk3036_codec_dai_ops, | 327 | .ops = &rk3036_codec_dai_ops, |
| 328 | .symmetric_rates = 1, | 328 | .symmetric_rate = 1, |
| 329 | }, | 329 | }, |
| 330 | }; | 330 | }; |
| 331 | 331 | ||
| @@ -214,7 +214,7 @@ static struct snd_soc_dai_driver jz4740_codec_dai = { · 213 unmodified lines | |||
| 214 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, | 214 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, |
| 215 | }, | 215 | }, |
| 216 | .ops = &jz4740_codec_dai_ops, | 216 | .ops = &jz4740_codec_dai_ops, |
| 217 | .symmetric_rates = 1, | 217 | .symmetric_rate = 1, |
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | static void jz4740_codec_wakeup(struct regmap *regmap) | 220 | static void jz4740_codec_wakeup(struct regmap *regmap) |
| @@ -0,0 +1,889 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // | ||
| 3 | // Ingenic JZ4760 CODEC driver | ||
| 4 | // | ||
| 5 | // Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com> | ||
| 6 | // Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net> | ||
| 7 | |||
| 8 | #include <linux/bitfield.h> | ||
| 9 | #include <linux/clk.h> | ||
| 10 | #include <linux/delay.h> | ||
| 11 | #include <linux/iopoll.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/regmap.h> | ||
| 14 | #include <linux/time64.h> | ||
| 15 | |||
| 16 | #include <sound/pcm_params.h> | ||
| 17 | #include <sound/soc.h> | ||
| 18 | #include <sound/soc-dai.h> | ||
| 19 | #include <sound/soc-dapm.h> | ||
| 20 | #include <sound/tlv.h> | ||
| 21 | |||
| 22 | #define ICDC_RGADW_OFFSET 0x00 | ||
| 23 | #define ICDC_RGDATA_OFFSET 0x04 | ||
| 24 | |||
| 25 | /* ICDC internal register access control register(RGADW) */ | ||
| 26 | #define ICDC_RGADW_RGWR BIT(16) | ||
| 27 | #define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8) | ||
| 28 | #define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0) | ||
| 29 | |||
| 30 | /* ICDC internal register data output register (RGDATA)*/ | ||
| 31 | #define ICDC_RGDATA_IRQ BIT(8) | ||
| 32 | #define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0) | ||
| 33 | |||
| 34 | /* Internal register space, accessed through regmap */ | ||
| 35 | enum { | ||
| 36 | JZ4760_CODEC_REG_SR, | ||
| 37 | JZ4760_CODEC_REG_AICR, | ||
| 38 | JZ4760_CODEC_REG_CR1, | ||
| 39 | JZ4760_CODEC_REG_CR2, | ||
| 40 | JZ4760_CODEC_REG_CR3, | ||
| 41 | JZ4760_CODEC_REG_CR4, | ||
| 42 | JZ4760_CODEC_REG_CCR1, | ||
| 43 | JZ4760_CODEC_REG_CCR2, | ||
| 44 | JZ4760_CODEC_REG_PMR1, | ||
| 45 | JZ4760_CODEC_REG_PMR2, | ||
| 46 | JZ4760_CODEC_REG_ICR, | ||
| 47 | JZ4760_CODEC_REG_IFR, | ||
| 48 | JZ4760_CODEC_REG_GCR1, | ||
| 49 | JZ4760_CODEC_REG_GCR2, | ||
| 50 | JZ4760_CODEC_REG_GCR3, | ||
| 51 | JZ4760_CODEC_REG_GCR4, | ||
| 52 | JZ4760_CODEC_REG_GCR5, | ||
| 53 | JZ4760_CODEC_REG_GCR6, | ||
| 54 | JZ4760_CODEC_REG_GCR7, | ||
| 55 | JZ4760_CODEC_REG_GCR8, | ||
| 56 | JZ4760_CODEC_REG_GCR9, | ||
| 57 | JZ4760_CODEC_REG_AGC1, | ||
| 58 | JZ4760_CODEC_REG_AGC2, | ||
| 59 | JZ4760_CODEC_REG_AGC3, | ||
| 60 | JZ4760_CODEC_REG_AGC4, | ||
| 61 | JZ4760_CODEC_REG_AGC5, | ||
| 62 | JZ4760_CODEC_REG_MIX1, | ||
| 63 | JZ4760_CODEC_REG_MIX2, | ||
| 64 | }; | ||
| 65 | |||
| 66 | #define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6) | ||
| 67 | #define REG_AICR_DAC_SERIAL BIT(3) | ||
| 68 | #define REG_AICR_DAC_I2S BIT(1) | ||
| 69 | |||
| 70 | #define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4) | ||
| 71 | |||
| 72 | #define REG_AICR_ADC_SERIAL BIT(2) | ||
| 73 | #define REG_AICR_ADC_I2S BIT(0) | ||
| 74 | |||
| 75 | #define REG_CR1_HP_LOAD BIT(7) | ||
| 76 | #define REG_CR1_HP_MUTE BIT(5) | ||
| 77 | #define REG_CR1_LO_MUTE_OFFSET 4 | ||
| 78 | #define REG_CR1_BTL_MUTE_OFFSET 3 | ||
| 79 | #define REG_CR1_OUTSEL_OFFSET 0 | ||
| 80 | #define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET) | ||
| 81 | |||
| 82 | #define REG_CR2_DAC_MONO BIT(7) | ||
| 83 | #define REG_CR2_DAC_MUTE BIT(5) | ||
| 84 | #define REG_CR2_DAC_NOMAD BIT(1) | ||
| 85 | #define REG_CR2_DAC_RIGHT_ONLY BIT(0) | ||
| 86 | |||
| 87 | #define REG_CR3_ADC_INSEL_OFFSET 2 | ||
| 88 | #define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET) | ||
| 89 | #define REG_CR3_MICSTEREO_OFFSET 1 | ||
| 90 | #define REG_CR3_MICDIFF_OFFSET 0 | ||
| 91 | |||
| 92 | #define REG_CR4_ADC_HPF_OFFSET 7 | ||
| 93 | #define REG_CR4_ADC_RIGHT_ONLY BIT(0) | ||
| 94 | |||
| 95 | #define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0) | ||
| 96 | |||
| 97 | #define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4) | ||
| 98 | #define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0) | ||
| 99 | |||
| 100 | #define REG_PMR1_SB BIT(7) | ||
| 101 | #define REG_PMR1_SB_SLEEP BIT(6) | ||
| 102 | #define REG_PMR1_SB_AIP_OFFSET 5 | ||
| 103 | #define REG_PMR1_SB_LINE_OFFSET 4 | ||
| 104 | #define REG_PMR1_SB_MIC1_OFFSET 3 | ||
| 105 | #define REG_PMR1_SB_MIC2_OFFSET 2 | ||
| 106 | #define REG_PMR1_SB_BYPASS_OFFSET 1 | ||
| 107 | #define REG_PMR1_SB_MICBIAS_OFFSET 0 | ||
| 108 | |||
| 109 | #define REG_PMR2_SB_ADC_OFFSET 4 | ||
| 110 | #define REG_PMR2_SB_HP_OFFSET 3 | ||
| 111 | #define REG_PMR2_SB_BTL_OFFSET 2 | ||
| 112 | #define REG_PMR2_SB_LOUT_OFFSET 1 | ||
| 113 | #define REG_PMR2_SB_DAC_OFFSET 0 | ||
| 114 | |||
| 115 | #define REG_ICR_INT_FORM_MASK GENMASK(7, 6) | ||
| 116 | #define REG_ICR_ALL_MASK GENMASK(5, 0) | ||
| 117 | #define REG_ICR_JACK_MASK BIT(5) | ||
| 118 | #define REG_ICR_SCMC_MASK BIT(4) | ||
| 119 | #define REG_ICR_RUP_MASK BIT(3) | ||
| 120 | #define REG_ICR_RDO_MASK BIT(2) | ||
| 121 | #define REG_ICR_GUP_MASK BIT(1) | ||
| 122 | #define REG_ICR_GDO_MASK BIT(0) | ||
| 123 | |||
| 124 | #define REG_IFR_ALL_MASK GENMASK(5, 0) | ||
| 125 | #define REG_IFR_JACK BIT(6) | ||
| 126 | #define REG_IFR_JACK_EVENT BIT(5) | ||
| 127 | #define REG_IFR_SCMC BIT(4) | ||
| 128 | #define REG_IFR_RUP BIT(3) | ||
| 129 | #define REG_IFR_RDO BIT(2) | ||
| 130 | #define REG_IFR_GUP BIT(1) | ||
| 131 | #define REG_IFR_GDO BIT(0) | ||
| 132 | |||
| 133 | #define REG_GCR_GAIN_OFFSET 0 | ||
| 134 | #define REG_GCR_GAIN_MAX 0x1f | ||
| 135 | |||
| 136 | #define REG_GCR_RL BIT(7) | ||
| 137 | |||
| 138 | #define REG_GCR_GIM1_MASK GENMASK(5, 3) | ||
| 139 | #define REG_GCR_GIM2_MASK GENMASK(2, 0) | ||
| 140 | #define REG_GCR_GIM_GAIN_MAX 7 | ||
| 141 | |||
| 142 | #define REG_AGC1_EN BIT(7) | ||
| 143 | #define REG_AGC1_TARGET_MASK GENMASK(5, 2) | ||
| 144 | |||
| 145 | #define REG_AGC2_NG_THR_MASK GENMASK(6, 4) | ||
| 146 | #define REG_AGC2_HOLD_MASK GENMASK(3, 0) | ||
| 147 | |||
| 148 | #define REG_AGC3_ATK_MASK GENMASK(7, 4) | ||
| 149 | #define REG_AGC3_DCY_MASK GENMASK(3, 0) | ||
| 150 | |||
| 151 | #define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0) | ||
| 152 | |||
| 153 | #define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0) | ||
| 154 | |||
| 155 | #define REG_MIX1_MIX_REC_MASK GENMASK(7, 6) | ||
| 156 | #define REG_MIX1_GIMIX_MASK GENMASK(4, 0) | ||
| 157 | |||
| 158 | #define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6) | ||
| 159 | #define REG_MIX2_GOMIX_MASK GENMASK(4, 0) | ||
| 160 | |||
| 161 | /* codec private data */ | ||
| 162 | struct jz_codec { | ||
| 163 | struct device *dev; | ||
| 164 | struct regmap *regmap; | ||
| 165 | void __iomem *base; | ||
| 166 | struct clk *clk; | ||
| 167 | }; | ||
| 168 | |||
| 169 | static int jz4760_codec_set_bias_level(struct snd_soc_component *codec, | ||
| 170 | enum snd_soc_bias_level level) | ||
| 171 | { | ||
| 172 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 173 | struct regmap *regmap = jz_codec->regmap; | ||
| 174 | |||
| 175 | switch (level) { | ||
| 176 | case SND_SOC_BIAS_PREPARE: | ||
| 177 | /* Reset all interrupt flags. */ | ||
| 178 | regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK); | ||
| 179 | |||
| 180 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); | ||
| 181 | msleep(250); | ||
| 182 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); | ||
| 183 | msleep(400); | ||
| 184 | break; | ||
| 185 | case SND_SOC_BIAS_STANDBY: | ||
| 186 | regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP); | ||
| 187 | regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB); | ||
| 188 | break; | ||
| 189 | default: | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int jz4760_codec_startup(struct snd_pcm_substream *substream, | ||
| 197 | struct snd_soc_dai *dai) | ||
| 198 | { | ||
| 199 | struct snd_soc_component *codec = dai->component; | ||
| 200 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); | ||
| 201 | int ret; | ||
| 202 | |||
| 203 | /* | ||
| 204 | * SYSCLK output from the codec to the AIC is required to keep the | ||
| 205 | * DMA transfer going during playback when all audible outputs have | ||
| 206 | * been disabled. | ||
| 207 | */ | ||
| 208 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 209 | ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK"); | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | static void jz4760_codec_shutdown(struct snd_pcm_substream *substream, | ||
| 214 | struct snd_soc_dai *dai) | ||
| 215 | { | ||
| 216 | struct snd_soc_component *codec = dai->component; | ||
| 217 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); | ||
| 218 | |||
| 219 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 220 | snd_soc_dapm_disable_pin(dapm, "SYSCLK"); | ||
| 221 | } | ||
| 222 | |||
| 223 | |||
| 224 | static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream, | ||
| 225 | int cmd, struct snd_soc_dai *dai) | ||
| 226 | { | ||
| 227 | struct snd_soc_component *codec = dai->component; | ||
| 228 | int ret = 0; | ||
| 229 | |||
| 230 | switch (cmd) { | ||
| 231 | case SNDRV_PCM_TRIGGER_START: | ||
| 232 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 233 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 234 | if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) | ||
| 235 | snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON); | ||
| 236 | break; | ||
| 237 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 238 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 239 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 240 | /* do nothing */ | ||
| 241 | break; | ||
| 242 | default: | ||
| 243 | ret = -EINVAL; | ||
| 244 | } | ||
| 245 | |||
| 246 | return ret; | ||
| 247 | } | ||
| 248 | |||
| 249 | static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction) | ||
| 250 | { | ||
| 251 | struct snd_soc_component *codec = dai->component; | ||
| 252 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 253 | unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP; | ||
| 254 | unsigned int val, reg; | ||
| 255 | int change, err; | ||
| 256 | |||
| 257 | change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2, | ||
| 258 | REG_CR2_DAC_MUTE, | ||
| 259 | mute ? REG_CR2_DAC_MUTE : 0); | ||
| 260 | if (change == 1) { | ||
| 261 | regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val); | ||
| 262 | |||
| 263 | if (val & BIT(REG_PMR2_SB_DAC_OFFSET)) | ||
| 264 | return 1; | ||
| 265 | |||
| 266 | err = regmap_read_poll_timeout(jz_codec->regmap, | ||
| 267 | JZ4760_CODEC_REG_IFR, | ||
| 268 | val, val & gain_bit, | ||
| 269 | 1000, 1 * USEC_PER_SEC); | ||
| 270 | if (err) { | ||
| 271 | dev_err(jz_codec->dev, | ||
| 272 | "Timeout while setting digital mute: %d", err); | ||
| 273 | return err; | ||
| 274 | } | ||
| 275 | |||
| 276 | /* clear GUP/GDO flag */ | ||
| 277 | regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit); | ||
| 278 | } | ||
| 279 | |||
| 280 | regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, ®); | ||
| 281 | |||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | /* unit: 0.01dB */ | ||
| 286 | static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100); | ||
| 287 | static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); | ||
| 288 | static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100); | ||
| 289 | static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0); | ||
| 290 | |||
| 291 | /* Unconditional controls. */ | ||
| 292 | static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = { | ||
| 293 | /* record gain control */ | ||
| 294 | SOC_DOUBLE_R_TLV("PCM Capture Volume", | ||
| 295 | JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8, | ||
| 296 | REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv), | ||
| 297 | |||
| 298 | SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume", | ||
| 299 | JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3, | ||
| 300 | REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv), | ||
| 301 | |||
| 302 | SOC_SINGLE("High-Pass Filter Capture Switch", | ||
| 303 | JZ4760_CODEC_REG_CR4, | ||
| 304 | REG_CR4_ADC_HPF_OFFSET, 1, 0), | ||
| 305 | }; | ||
| 306 | |||
| 307 | static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = { | ||
| 308 | { | ||
| 309 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 310 | .name = "Volume", | ||
| 311 | .info = snd_soc_info_volsw, | ||
| 312 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | ||
| 313 | | SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
| 314 | .tlv.p = dac_tlv, | ||
| 315 | .get = snd_soc_dapm_get_volsw, | ||
| 316 | .put = snd_soc_dapm_put_volsw, | ||
| 317 | .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6, | ||
| 318 | JZ4760_CODEC_REG_GCR5, | ||
| 319 | REG_GCR_GAIN_OFFSET, | ||
| 320 | REG_GCR_GAIN_MAX, 1), | ||
| 321 | }, | ||
| 322 | }; | ||
| 323 | |||
| 324 | static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = { | ||
| 325 | { | ||
| 326 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 327 | .name = "Volume", | ||
| 328 | .info = snd_soc_info_volsw, | ||
| 329 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | ||
| 330 | | SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
| 331 | .tlv.p = out_tlv, | ||
| 332 | .get = snd_soc_dapm_get_volsw, | ||
| 333 | .put = snd_soc_dapm_put_volsw, | ||
| 334 | .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2, | ||
| 335 | JZ4760_CODEC_REG_GCR1, | ||
| 336 | REG_GCR_GAIN_OFFSET, | ||
| 337 | REG_GCR_GAIN_MAX, 1), | ||
| 338 | }, | ||
| 339 | }; | ||
| 340 | |||
| 341 | static int hpout_event(struct snd_soc_dapm_widget *w, | ||
| 342 | struct snd_kcontrol *kcontrol, int event) | ||
| 343 | { | ||
| 344 | struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); | ||
| 345 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 346 | unsigned int val; | ||
| 347 | int err; | ||
| 348 | |||
| 349 | switch (event) { | ||
| 350 | case SND_SOC_DAPM_PRE_PMU: | ||
| 351 | /* unmute HP */ | ||
| 352 | regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, | ||
| 353 | REG_CR1_HP_MUTE); | ||
| 354 | break; | ||
| 355 | |||
| 356 | case SND_SOC_DAPM_POST_PMU: | ||
| 357 | /* wait for ramp-up complete (RUP) */ | ||
| 358 | err = regmap_read_poll_timeout(jz_codec->regmap, | ||
| 359 | JZ4760_CODEC_REG_IFR, | ||
| 360 | val, val & REG_IFR_RUP, | ||
| 361 | 1000, 1 * USEC_PER_SEC); | ||
| 362 | if (err) { | ||
| 363 | dev_err(jz_codec->dev, "RUP timeout: %d", err); | ||
| 364 | return err; | ||
| 365 | } | ||
| 366 | |||
| 367 | /* clear RUP flag */ | ||
| 368 | regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, | ||
| 369 | REG_IFR_RUP); | ||
| 370 | |||
| 371 | break; | ||
| 372 | |||
| 373 | case SND_SOC_DAPM_POST_PMD: | ||
| 374 | /* mute HP */ | ||
| 375 | regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, | ||
| 376 | REG_CR1_HP_MUTE); | ||
| 377 | |||
| 378 | err = regmap_read_poll_timeout(jz_codec->regmap, | ||
| 379 | JZ4760_CODEC_REG_IFR, | ||
| 380 | val, val & REG_IFR_RDO, | ||
| 381 | 1000, 1 * USEC_PER_SEC); | ||
| 382 | if (err) { | ||
| 383 | dev_err(jz_codec->dev, "RDO timeout: %d", err); | ||
| 384 | return err; | ||
| 385 | } | ||
| 386 | |||
| 387 | /* clear RDO flag */ | ||
| 388 | regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, | ||
| 389 | REG_IFR_RDO); | ||
| 390 | |||
| 391 | break; | ||
| 392 | } | ||
| 393 | |||
| 394 | return 0; | ||
| 395 | } | ||
| 396 | |||
| 397 | static const char * const jz4760_codec_hp_texts[] = { | ||
| 398 | "PCM", "Line In", "Mic 1", "Mic 2" | ||
| 399 | }; | ||
| 400 | |||
| 401 | static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 }; | ||
| 402 | |||
| 403 | static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum, | ||
| 404 | JZ4760_CODEC_REG_CR1, | ||
| 405 | REG_CR1_OUTSEL_OFFSET, | ||
| 406 | REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET, | ||
| 407 | jz4760_codec_hp_texts, | ||
| 408 | jz4760_codec_hp_values); | ||
| 409 | static const struct snd_kcontrol_new jz4760_codec_hp_source = | ||
| 410 | SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum); | ||
| 411 | |||
| 412 | static const char * const jz4760_codec_cap_texts[] = { | ||
| 413 | "Line In", "Mic 1", "Mic 2" | ||
| 414 | }; | ||
| 415 | |||
| 416 | static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 }; | ||
| 417 | |||
| 418 | static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum, | ||
| 419 | JZ4760_CODEC_REG_CR3, | ||
| 420 | REG_CR3_ADC_INSEL_OFFSET, | ||
| 421 | REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET, | ||
| 422 | jz4760_codec_cap_texts, | ||
| 423 | jz4760_codec_cap_values); | ||
| 424 | static const struct snd_kcontrol_new jz4760_codec_cap_source = | ||
| 425 | SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum); | ||
| 426 | |||
| 427 | static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = { | ||
| 428 | SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3, | ||
| 429 | REG_CR3_MICSTEREO_OFFSET, 1, 0), | ||
| 430 | }; | ||
| 431 | |||
| 432 | static const struct snd_kcontrol_new jz4760_codec_line_out_switch = | ||
| 433 | SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, | ||
| 434 | REG_CR1_LO_MUTE_OFFSET, 0, 0); | ||
| 435 | static const struct snd_kcontrol_new jz4760_codec_btl_out_switch = | ||
| 436 | SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1, | ||
| 437 | REG_CR1_BTL_MUTE_OFFSET, 0, 0); | ||
| 438 | |||
| 439 | static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = { | ||
| 440 | SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2, | ||
| 441 | REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event, | ||
| 442 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 443 | SND_SOC_DAPM_POST_PMD), | ||
| 444 | |||
| 445 | SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2, | ||
| 446 | REG_PMR2_SB_LOUT_OFFSET, 1, | ||
| 447 | &jz4760_codec_line_out_switch), | ||
| 448 | |||
| 449 | SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2, | ||
| 450 | REG_PMR2_SB_BTL_OFFSET, 1, | ||
| 451 | &jz4760_codec_btl_out_switch), | ||
| 452 | |||
| 453 | SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1, | ||
| 454 | REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0), | ||
| 455 | |||
| 456 | SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0, | ||
| 457 | &jz4760_codec_hp_source), | ||
| 458 | |||
| 459 | SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, | ||
| 460 | &jz4760_codec_cap_source), | ||
| 461 | |||
| 462 | SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1, | ||
| 463 | REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0), | ||
| 464 | |||
| 465 | SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1, | ||
| 466 | REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0), | ||
| 467 | |||
| 468 | SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3, | ||
| 469 | REG_CR3_MICDIFF_OFFSET, 0, NULL, 0), | ||
| 470 | |||
| 471 | SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0, | ||
| 472 | jz4760_codec_mic_controls, | ||
| 473 | ARRAY_SIZE(jz4760_codec_mic_controls)), | ||
| 474 | |||
| 475 | SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1, | ||
| 476 | REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0), | ||
| 477 | |||
| 478 | SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2, | ||
| 479 | REG_PMR2_SB_ADC_OFFSET, 1), | ||
| 480 | |||
| 481 | SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2, | ||
| 482 | REG_PMR2_SB_DAC_OFFSET, 1), | ||
| 483 | |||
| 484 | SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0, | ||
| 485 | jz4760_codec_pcm_playback_controls, | ||
| 486 | ARRAY_SIZE(jz4760_codec_pcm_playback_controls)), | ||
| 487 | |||
| 488 | SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0, | ||
| 489 | jz4760_codec_hp_playback_controls, | ||
| 490 | ARRAY_SIZE(jz4760_codec_hp_playback_controls)), | ||
| 491 | |||
| 492 | SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1, | ||
| 493 | REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0), | ||
| 494 | |||
| 495 | SND_SOC_DAPM_INPUT("MIC1P"), | ||
| 496 | SND_SOC_DAPM_INPUT("MIC1N"), | ||
| 497 | SND_SOC_DAPM_INPUT("MIC2P"), | ||
| 498 | SND_SOC_DAPM_INPUT("MIC2N"), | ||
| 499 | |||
| 500 | SND_SOC_DAPM_INPUT("LLINEIN"), | ||
| 501 | SND_SOC_DAPM_INPUT("RLINEIN"), | ||
| 502 | |||
| 503 | SND_SOC_DAPM_OUTPUT("LHPOUT"), | ||
| 504 | SND_SOC_DAPM_OUTPUT("RHPOUT"), | ||
| 505 | |||
| 506 | SND_SOC_DAPM_OUTPUT("LOUT"), | ||
| 507 | SND_SOC_DAPM_OUTPUT("ROUT"), | ||
| 508 | |||
| 509 | SND_SOC_DAPM_OUTPUT("BTLP"), | ||
| 510 | SND_SOC_DAPM_OUTPUT("BTLN"), | ||
| 511 | |||
| 512 | SND_SOC_DAPM_OUTPUT("SYSCLK"), | ||
| 513 | }; | ||
| 514 | |||
| 515 | /* Unconditional routes. */ | ||
| 516 | static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = { | ||
| 517 | { "Mic 1", NULL, "MIC1P" }, | ||
| 518 | { "Mic Diff", NULL, "MIC1N" }, | ||
| 519 | { "Mic 1", NULL, "Mic Diff" }, | ||
| 520 | { "Mic 2", NULL, "MIC2P" }, | ||
| 521 | { "Mic Diff", NULL, "MIC2N" }, | ||
| 522 | { "Mic 2", NULL, "Mic Diff" }, | ||
| 523 | |||
| 524 | { "Line In", NULL, "LLINEIN" }, | ||
| 525 | { "Line In", NULL, "RLINEIN" }, | ||
| 526 | |||
| 527 | { "Mic", "Stereo Capture Switch", "Mic 1" }, | ||
| 528 | { "Mic", "Stereo Capture Switch", "Mic 2" }, | ||
| 529 | { "Headphones Source", "Mic 1", "Mic" }, | ||
| 530 | { "Headphones Source", "Mic 2", "Mic" }, | ||
| 531 | { "Capture Source", "Mic 1", "Mic" }, | ||
| 532 | { "Capture Source", "Mic 2", "Mic" }, | ||
| 533 | |||
| 534 | { "Capture Source", "Line In", "Line In" }, | ||
| 535 | { "Capture Source", "Mic 1", "Mic 1" }, | ||
| 536 | { "Capture Source", "Mic 2", "Mic 2" }, | ||
| 537 | { "ADC", NULL, "Capture Source" }, | ||
| 538 | |||
| 539 | { "Line In Bypass", NULL, "Line In" }, | ||
| 540 | |||
| 541 | { "Headphones Source", "Mic 1", "Mic 1" }, | ||
| 542 | { "Headphones Source", "Mic 2", "Mic 2" }, | ||
| 543 | { "Headphones Source", "Line In", "Line In Bypass" }, | ||
| 544 | { "Headphones Source", "PCM", "Headphones Playback" }, | ||
| 545 | { "HP Out", NULL, "Headphones Source" }, | ||
| 546 | |||
| 547 | { "LHPOUT", NULL, "HP Out" }, | ||
| 548 | { "RHPOUT", NULL, "HP Out" }, | ||
| 549 | { "Line Out", "Switch", "HP Out" }, | ||
| 550 | |||
| 551 | { "LOUT", NULL, "Line Out" }, | ||
| 552 | { "ROUT", NULL, "Line Out" }, | ||
| 553 | { "BTL Out", "Switch", "Line Out" }, | ||
| 554 | |||
| 555 | { "BTLP", NULL, "BTL Out"}, | ||
| 556 | { "BTLN", NULL, "BTL Out"}, | ||
| 557 | |||
| 558 | { "PCM Playback", "Volume", "DAC" }, | ||
| 559 | { "Headphones Playback", "Volume", "PCM Playback" }, | ||
| 560 | |||
| 561 | { "SYSCLK", NULL, "DAC" }, | ||
| 562 | }; | ||
| 563 | |||
| 564 | static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec) | ||
| 565 | { | ||
| 566 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 567 | struct regmap *regmap = jz_codec->regmap; | ||
| 568 | |||
| 569 | /* Collect updates for later sending. */ | ||
| 570 | regcache_cache_only(regmap, true); | ||
| 571 | |||
| 572 | /* default Amp output to PCM */ | ||
| 573 | regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK); | ||
| 574 | |||
| 575 | /* Disable stereo mic */ | ||
| 576 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, | ||
| 577 | BIT(REG_CR3_MICSTEREO_OFFSET)); | ||
| 578 | |||
| 579 | /* Set mic 1 as default source for ADC */ | ||
| 580 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3, | ||
| 581 | REG_CR3_ADC_INSEL_MASK); | ||
| 582 | |||
| 583 | /* ADC/DAC: serial + i2s */ | ||
| 584 | regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR, | ||
| 585 | REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S | | ||
| 586 | REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S); | ||
| 587 | |||
| 588 | /* The generated IRQ is a high level */ | ||
| 589 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK); | ||
| 590 | regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK, | ||
| 591 | REG_ICR_JACK_MASK | REG_ICR_RUP_MASK | | ||
| 592 | REG_ICR_RDO_MASK | REG_ICR_GUP_MASK | | ||
| 593 | REG_ICR_GDO_MASK); | ||
| 594 | |||
| 595 | /* 12M oscillator */ | ||
| 596 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK); | ||
| 597 | |||
| 598 | /* 0: 16ohm/220uF, 1: 10kohm/1uF */ | ||
| 599 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD); | ||
| 600 | |||
| 601 | /* default to NOMAD */ | ||
| 602 | regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2, | ||
| 603 | REG_CR2_DAC_NOMAD); | ||
| 604 | |||
| 605 | /* disable automatic gain */ | ||
| 606 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN); | ||
| 607 | |||
| 608 | /* Independent L/R DAC gain control */ | ||
| 609 | regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5, | ||
| 610 | REG_GCR_RL); | ||
| 611 | |||
| 612 | /* Send collected updates. */ | ||
| 613 | regcache_cache_only(regmap, false); | ||
| 614 | regcache_sync(regmap); | ||
| 615 | } | ||
| 616 | |||
| 617 | static int jz4760_codec_codec_probe(struct snd_soc_component *codec) | ||
| 618 | { | ||
| 619 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 620 | |||
| 621 | clk_prepare_enable(jz_codec->clk); | ||
| 622 | |||
| 623 | jz4760_codec_codec_init_regs(codec); | ||
| 624 | |||
| 625 | return 0; | ||
| 626 | } | ||
| 627 | |||
| 628 | static void jz4760_codec_codec_remove(struct snd_soc_component *codec) | ||
| 629 | { | ||
| 630 | struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); | ||
| 631 | |||
| 632 | clk_disable_unprepare(jz_codec->clk); | ||
| 633 | } | ||
| 634 | |||
| 635 | static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = { | ||
| 636 | .probe = jz4760_codec_codec_probe, | ||
| 637 | .remove = jz4760_codec_codec_remove, | ||
| 638 | .set_bias_level = jz4760_codec_set_bias_level, | ||
| 639 | .controls = jz4760_codec_snd_controls, | ||
| 640 | .num_controls = ARRAY_SIZE(jz4760_codec_snd_controls), | ||
| 641 | .dapm_widgets = jz4760_codec_dapm_widgets, | ||
| 642 | .num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets), | ||
| 643 | .dapm_routes = jz4760_codec_dapm_routes, | ||
| 644 | .num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes), | ||
| 645 | .suspend_bias_off = 1, | ||
| 646 | .use_pmdown_time = 1, | ||
| 647 | }; | ||
| 648 | |||
| 649 | static const unsigned int jz4760_codec_sample_rates[] = { | ||
| 650 | 96000, 48000, 44100, 32000, | ||
| 651 | 24000, 22050, 16000, 12000, | ||
| 652 | 11025, 9600, 8000, | ||
| 653 | }; | ||
| 654 | |||
| 655 | static int jz4760_codec_hw_params(struct snd_pcm_substream *substream, | ||
| 656 | struct snd_pcm_hw_params *params, | ||
| 657 | struct snd_soc_dai *dai) | ||
| 658 | { | ||
| 659 | struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); | ||
| 660 | unsigned int rate, bit_width; | ||
| 661 | |||
| 662 | switch (params_format(params)) { | ||
| 663 | case SNDRV_PCM_FORMAT_S16_LE: | ||
| 664 | bit_width = 0; | ||
| 665 | break; | ||
| 666 | case SNDRV_PCM_FORMAT_S18_3LE: | ||
| 667 | bit_width = 1; | ||
| 668 | break; | ||
| 669 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
| 670 | bit_width = 2; | ||
| 671 | break; | ||
| 672 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
| 673 | bit_width = 3; | ||
| 674 | break; | ||
| 675 | default: | ||
| 676 | return -EINVAL; | ||
| 677 | } | ||
| 678 | |||
| 679 | for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) { | ||
| 680 | if (jz4760_codec_sample_rates[rate] == params_rate(params)) | ||
| 681 | break; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (rate == ARRAY_SIZE(jz4760_codec_sample_rates)) | ||
| 685 | return -EINVAL; | ||
| 686 | |||
| 687 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 688 | regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, | ||
| 689 | REG_AICR_DAC_ADWL_MASK, | ||
| 690 | FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width)); | ||
| 691 | regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, | ||
| 692 | REG_CCR2_DAC_FREQ_MASK, | ||
| 693 | FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate)); | ||
| 694 | } else { | ||
| 695 | regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, | ||
| 696 | REG_AICR_ADC_ADWL_MASK, | ||
| 697 | FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width)); | ||
| 698 | regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, | ||
| 699 | REG_CCR2_ADC_FREQ_MASK, | ||
| 700 | FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate)); | ||
| 701 | } | ||
| 702 | |||
| 703 | return 0; | ||
| 704 | } | ||
| 705 | |||
| 706 | static const struct snd_soc_dai_ops jz4760_codec_dai_ops = { | ||
| 707 | .startup = jz4760_codec_startup, | ||
| 708 | .shutdown = jz4760_codec_shutdown, | ||
| 709 | .hw_params = jz4760_codec_hw_params, | ||
| 710 | .trigger = jz4760_codec_pcm_trigger, | ||
| 711 | .mute_stream = jz4760_codec_mute_stream, | ||
| 712 | .no_capture_mute = 1, | ||
| 713 | }; | ||
| 714 | |||
| 715 | #define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
| 716 | SNDRV_PCM_FMTBIT_S18_3LE | \ | ||
| 717 | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
| 718 | SNDRV_PCM_FMTBIT_S24_3LE) | ||
| 719 | |||
| 720 | static struct snd_soc_dai_driver jz4760_codec_dai = { | ||
| 721 | .name = "jz4760-hifi", | ||
| 722 | .playback = { | ||
| 723 | .stream_name = "Playback", | ||
| 724 | .channels_min = 2, | ||
| 725 | .channels_max = 2, | ||
| 726 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
| 727 | .formats = JZ_CODEC_FORMATS, | ||
| 728 | }, | ||
| 729 | .capture = { | ||
| 730 | .stream_name = "Capture", | ||
| 731 | .channels_min = 2, | ||
| 732 | .channels_max = 2, | ||
| 733 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
| 734 | .formats = JZ_CODEC_FORMATS, | ||
| 735 | }, | ||
| 736 | .ops = &jz4760_codec_dai_ops, | ||
| 737 | }; | ||
| 738 | |||
| 739 | static bool jz4760_codec_volatile(struct device *dev, unsigned int reg) | ||
| 740 | { | ||
| 741 | return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR; | ||
| 742 | } | ||
| 743 | |||
| 744 | static bool jz4760_codec_writeable(struct device *dev, unsigned int reg) | ||
| 745 | { | ||
| 746 | switch (reg) { | ||
| 747 | case JZ4760_CODEC_REG_SR: | ||
| 748 | return false; | ||
| 749 | default: | ||
| 750 | return true; | ||
| 751 | } | ||
| 752 | } | ||
| 753 | |||
| 754 | static int jz4760_codec_io_wait(struct jz_codec *codec) | ||
| 755 | { | ||
| 756 | u32 reg; | ||
| 757 | |||
| 758 | return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, | ||
| 759 | !(reg & ICDC_RGADW_RGWR), | ||
| 760 | 1000, 1 * USEC_PER_SEC); | ||
| 761 | } | ||
| 762 | |||
| 763 | static int jz4760_codec_reg_read(void *context, unsigned int reg, | ||
| 764 | unsigned int *val) | ||
| 765 | { | ||
| 766 | struct jz_codec *codec = context; | ||
| 767 | unsigned int i; | ||
| 768 | u32 tmp; | ||
| 769 | int ret; | ||
| 770 | |||
| 771 | ret = jz4760_codec_io_wait(codec); | ||
| 772 | if (ret) | ||
| 773 | return ret; | ||
| 774 | |||
| 775 | tmp = readl(codec->base + ICDC_RGADW_OFFSET); | ||
| 776 | tmp &= ~ICDC_RGADW_RGADDR_MASK; | ||
| 777 | tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg); | ||
| 778 | writel(tmp, codec->base + ICDC_RGADW_OFFSET); | ||
| 779 | |||
| 780 | /* wait 6+ cycles */ | ||
| 781 | for (i = 0; i < 6; i++) | ||
| 782 | *val = readl(codec->base + ICDC_RGDATA_OFFSET) & | ||
| 783 | ICDC_RGDATA_RGDOUT_MASK; | ||
| 784 | |||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | |||
| 788 | static int jz4760_codec_reg_write(void *context, unsigned int reg, | ||
| 789 | unsigned int val) | ||
| 790 | { | ||
| 791 | struct jz_codec *codec = context; | ||
| 792 | int ret; | ||
| 793 | |||
| 794 | ret = jz4760_codec_io_wait(codec); | ||
| 795 | if (ret) | ||
| 796 | return ret; | ||
| 797 | |||
| 798 | writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val, | ||
| 799 | codec->base + ICDC_RGADW_OFFSET); | ||
| 800 | |||
| 801 | ret = jz4760_codec_io_wait(codec); | ||
| 802 | if (ret) | ||
| 803 | return ret; | ||
| 804 | |||
| 805 | return 0; | ||
| 806 | } | ||
| 807 | |||
| 808 | static const u8 jz4760_codec_reg_defaults[] = { | ||
| 809 | 0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00, | ||
| 810 | 0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06, | ||
| 811 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44, | ||
| 812 | 0x1F, 0x00, 0x00, 0x00 | ||
| 813 | }; | ||
| 814 | |||
| 815 | static struct regmap_config jz4760_codec_regmap_config = { | ||
| 816 | .reg_bits = 7, | ||
| 817 | .val_bits = 8, | ||
| 818 | |||
| 819 | .max_register = JZ4760_CODEC_REG_MIX2, | ||
| 820 | .volatile_reg = jz4760_codec_volatile, | ||
| 821 | .writeable_reg = jz4760_codec_writeable, | ||
| 822 | |||
| 823 | .reg_read = jz4760_codec_reg_read, | ||
| 824 | .reg_write = jz4760_codec_reg_write, | ||
| 825 | |||
| 826 | .reg_defaults_raw = jz4760_codec_reg_defaults, | ||
| 827 | .num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults), | ||
| 828 | .cache_type = REGCACHE_FLAT, | ||
| 829 | }; | ||
| 830 | |||
| 831 | static int jz4760_codec_probe(struct platform_device *pdev) | ||
| 832 | { | ||
| 833 | struct device *dev = &pdev->dev; | ||
| 834 | struct jz_codec *codec; | ||
| 835 | int ret; | ||
| 836 | |||
| 837 | codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); | ||
| 838 | if (!codec) | ||
| 839 | return -ENOMEM; | ||
| 840 | |||
| 841 | codec->dev = dev; | ||
| 842 | |||
| 843 | codec->base = devm_platform_ioremap_resource(pdev, 0); | ||
| 844 | if (IS_ERR(codec->base)) { | ||
| 845 | ret = PTR_ERR(codec->base); | ||
| 846 | dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret); | ||
| 847 | return ret; | ||
| 848 | } | ||
| 849 | |||
| 850 | codec->regmap = devm_regmap_init(dev, NULL, codec, | ||
| 851 | &jz4760_codec_regmap_config); | ||
| 852 | if (IS_ERR(codec->regmap)) | ||
| 853 | return PTR_ERR(codec->regmap); | ||
| 854 | |||
| 855 | codec->clk = devm_clk_get(dev, "aic"); | ||
| 856 | if (IS_ERR(codec->clk)) | ||
| 857 | return PTR_ERR(codec->clk); | ||
| 858 | |||
| 859 | platform_set_drvdata(pdev, codec); | ||
| 860 | |||
| 861 | ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev, | ||
| 862 | &jz4760_codec_dai, 1); | ||
| 863 | if (ret) { | ||
| 864 | dev_err(dev, "Failed to register codec: %d\n", ret); | ||
| 865 | return ret; | ||
| 866 | } | ||
| 867 | |||
| 868 | return 0; | ||
| 869 | } | ||
| 870 | |||
| 871 | static const struct of_device_id jz4760_codec_of_matches[] = { | ||
| 872 | { .compatible = "ingenic,jz4760-codec", }, | ||
| 873 | { /* sentinel */ } | ||
| 874 | }; | ||
| 875 | MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches); | ||
| 876 | |||
| 877 | static struct platform_driver jz4760_codec_driver = { | ||
| 878 | .probe = jz4760_codec_probe, | ||
| 879 | .driver = { | ||
| 880 | .name = "jz4760-codec", | ||
| 881 | .of_match_table = jz4760_codec_of_matches, | ||
| 882 | }, | ||
| 883 | }; | ||
| 884 | module_platform_driver(jz4760_codec_driver); | ||
| 885 | |||
| 886 | MODULE_DESCRIPTION("JZ4760 SoC internal codec driver"); | ||
| 887 | MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>"); | ||
| 888 | MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); | ||
| 889 | MODULE_LICENSE("GPL v2"); | ||
| @@ -1343,7 +1343,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = { · 1342 unmodified lines | |||
| 1343 | .formats = LM49453_FORMATS, | 1343 | .formats = LM49453_FORMATS, |
| 1344 | }, | 1344 | }, |
| 1345 | .ops = &lm49453_headset_dai_ops, | 1345 | .ops = &lm49453_headset_dai_ops, |
| 1346 | .symmetric_rates = 1, | 1346 | .symmetric_rate = 1, |
| 1347 | }, | 1347 | }, |
| 1348 | { | 1348 | { |
| 1349 | .name = "LM49453 Speaker", | 1349 | .name = "LM49453 Speaker", |
| @@ -166,8 +166,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 165 unmodified lines | |||
| 166 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 166 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 167 | }, | 167 | }, |
| 168 | .ops = &lochnagar_sc_line_ops, | 168 | .ops = &lochnagar_sc_line_ops, |
| 169 | .symmetric_rates = true, | 169 | .symmetric_rate = true, |
| 170 | .symmetric_samplebits = true, | 170 | .symmetric_sample_bits = true, |
| 171 | }, | 171 | }, |
| 172 | { | 172 | { |
| 173 | .name = "lochnagar-usb1", | 173 | .name = "lochnagar-usb1", |
| @@ -186,8 +186,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 12 unmodified lines | |||
| 186 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 186 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 187 | }, | 187 | }, |
| 188 | .ops = &lochnagar_sc_usb_ops, | 188 | .ops = &lochnagar_sc_usb_ops, |
| 189 | .symmetric_rates = true, | 189 | .symmetric_rate = true, |
| 190 | .symmetric_samplebits = true, | 190 | .symmetric_sample_bits = true, |
| 191 | }, | 191 | }, |
| 192 | { | 192 | { |
| 193 | .name = "lochnagar-usb2", | 193 | .name = "lochnagar-usb2", |
| @@ -206,8 +206,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 12 unmodified lines | |||
| 206 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 206 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 207 | }, | 207 | }, |
| 208 | .ops = &lochnagar_sc_usb_ops, | 208 | .ops = &lochnagar_sc_usb_ops, |
| 209 | .symmetric_rates = true, | 209 | .symmetric_rate = true, |
| 210 | .symmetric_samplebits = true, | 210 | .symmetric_sample_bits = true, |
| 211 | }, | 211 | }, |
| 212 | }; | 212 | }; |
| 213 | 213 | ||
| @@ -0,0 +1,3599 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. | ||
| 3 | |||
| 4 | #include <linux/module.h> | ||
| 5 | #include <linux/init.h> | ||
| 6 | #include <linux/io.h> | ||
| 7 | #include <linux/platform_device.h> | ||
| 8 | #include <linux/clk.h> | ||
| 9 | #include <sound/soc.h> | ||
| 10 | #include <sound/pcm.h> | ||
| 11 | #include <sound/pcm_params.h> | ||
| 12 | #include <sound/soc-dapm.h> | ||
| 13 | #include <sound/tlv.h> | ||
| 14 | #include <linux/of_clk.h> | ||
| 15 | #include <linux/clk-provider.h> | ||
| 16 | |||
| 17 | #define CDC_RX_TOP_TOP_CFG0 (0x0000) | ||
| 18 | #define CDC_RX_TOP_SWR_CTRL (0x0008) | ||
| 19 | #define CDC_RX_TOP_DEBUG (0x000C) | ||
| 20 | #define CDC_RX_TOP_DEBUG_BUS (0x0010) | ||
| 21 | #define CDC_RX_TOP_DEBUG_EN0 (0x0014) | ||
| 22 | #define CDC_RX_TOP_DEBUG_EN1 (0x0018) | ||
| 23 | #define CDC_RX_TOP_DEBUG_EN2 (0x001C) | ||
| 24 | #define CDC_RX_TOP_HPHL_COMP_WR_LSB (0x0020) | ||
| 25 | #define CDC_RX_TOP_HPHL_COMP_WR_MSB (0x0024) | ||
| 26 | #define CDC_RX_TOP_HPHL_COMP_LUT (0x0028) | ||
| 27 | #define CDC_RX_TOP_HPH_LUT_BYPASS_MASK BIT(7) | ||
| 28 | #define CDC_RX_TOP_HPHL_COMP_RD_LSB (0x002C) | ||
| 29 | #define CDC_RX_TOP_HPHL_COMP_RD_MSB (0x0030) | ||
| 30 | #define CDC_RX_TOP_HPHR_COMP_WR_LSB (0x0034) | ||
| 31 | #define CDC_RX_TOP_HPHR_COMP_WR_MSB (0x0038) | ||
| 32 | #define CDC_RX_TOP_HPHR_COMP_LUT (0x003C) | ||
| 33 | #define CDC_RX_TOP_HPHR_COMP_RD_LSB (0x0040) | ||
| 34 | #define CDC_RX_TOP_HPHR_COMP_RD_MSB (0x0044) | ||
| 35 | #define CDC_RX_TOP_DSD0_DEBUG_CFG0 (0x0070) | ||
| 36 | #define CDC_RX_TOP_DSD0_DEBUG_CFG1 (0x0074) | ||
| 37 | #define CDC_RX_TOP_DSD0_DEBUG_CFG2 (0x0078) | ||
| 38 | #define CDC_RX_TOP_DSD0_DEBUG_CFG3 (0x007C) | ||
| 39 | #define CDC_RX_TOP_DSD1_DEBUG_CFG0 (0x0080) | ||
| 40 | #define CDC_RX_TOP_DSD1_DEBUG_CFG1 (0x0084) | ||
| 41 | #define CDC_RX_TOP_DSD1_DEBUG_CFG2 (0x0088) | ||
| 42 | #define CDC_RX_TOP_DSD1_DEBUG_CFG3 (0x008C) | ||
| 43 | #define CDC_RX_TOP_RX_I2S_CTL (0x0090) | ||
| 44 | #define CDC_RX_TOP_TX_I2S2_CTL (0x0094) | ||
| 45 | #define CDC_RX_TOP_I2S_CLK (0x0098) | ||
| 46 | #define CDC_RX_TOP_I2S_RESET (0x009C) | ||
| 47 | #define CDC_RX_TOP_I2S_MUX (0x00A0) | ||
| 48 | #define CDC_RX_CLK_RST_CTRL_MCLK_CONTROL (0x0100) | ||
| 49 | #define CDC_RX_CLK_MCLK_EN_MASK BIT(0) | ||
| 50 | #define CDC_RX_CLK_MCLK_ENABLE BIT(0) | ||
| 51 | #define CDC_RX_CLK_MCLK2_EN_MASK BIT(1) | ||
| 52 | #define CDC_RX_CLK_MCLK2_ENABLE BIT(1) | ||
| 53 | #define CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0104) | ||
| 54 | #define CDC_RX_FS_MCLK_CNT_EN_MASK BIT(0) | ||
| 55 | #define CDC_RX_FS_MCLK_CNT_ENABLE BIT(0) | ||
| 56 | #define CDC_RX_FS_MCLK_CNT_CLR_MASK BIT(1) | ||
| 57 | #define CDC_RX_FS_MCLK_CNT_CLR BIT(1) | ||
| 58 | #define CDC_RX_CLK_RST_CTRL_SWR_CONTROL (0x0108) | ||
| 59 | #define CDC_RX_SWR_CLK_EN_MASK BIT(0) | ||
| 60 | #define CDC_RX_SWR_RESET_MASK BIT(1) | ||
| 61 | #define CDC_RX_SWR_RESET BIT(1) | ||
| 62 | #define CDC_RX_CLK_RST_CTRL_DSD_CONTROL (0x010C) | ||
| 63 | #define CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x0110) | ||
| 64 | #define CDC_RX_SOFTCLIP_CRC (0x0140) | ||
| 65 | #define CDC_RX_SOFTCLIP_CLK_EN_MASK BIT(0) | ||
| 66 | #define CDC_RX_SOFTCLIP_SOFTCLIP_CTRL (0x0144) | ||
| 67 | #define CDC_RX_SOFTCLIP_EN_MASK BIT(0) | ||
| 68 | #define CDC_RX_INP_MUX_RX_INT0_CFG0 (0x0180) | ||
| 69 | #define CDC_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(3, 0) | ||
| 70 | #define CDC_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(7, 4) | ||
| 71 | #define CDC_RX_INP_MUX_RX_INT0_CFG1 (0x0184) | ||
| 72 | #define CDC_RX_INTX_2_SEL_MASK GENMASK(3, 0) | ||
| 73 | #define CDC_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(7, 4) | ||
| 74 | #define CDC_RX_INP_MUX_RX_INT1_CFG0 (0x0188) | ||
| 75 | #define CDC_RX_INP_MUX_RX_INT1_CFG1 (0x018C) | ||
| 76 | #define CDC_RX_INP_MUX_RX_INT2_CFG0 (0x0190) | ||
| 77 | #define CDC_RX_INP_MUX_RX_INT2_CFG1 (0x0194) | ||
| 78 | #define CDC_RX_INP_MUX_RX_MIX_CFG4 (0x0198) | ||
| 79 | #define CDC_RX_INP_MUX_RX_MIX_CFG5 (0x019C) | ||
| 80 | #define CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x01A0) | ||
| 81 | #define CDC_RX_CLSH_CRC (0x0200) | ||
| 82 | #define CDC_RX_CLSH_CLK_EN_MASK BIT(0) | ||
| 83 | #define CDC_RX_CLSH_DLY_CTRL (0x0204) | ||
| 84 | #define CDC_RX_CLSH_DECAY_CTRL (0x0208) | ||
| 85 | #define CDC_RX_CLSH_DECAY_RATE_MASK GENMASK(2, 0) | ||
| 86 | #define CDC_RX_CLSH_HPH_V_PA (0x020C) | ||
| 87 | #define CDC_RX_CLSH_HPH_V_PA_MIN_MASK GENMASK(5, 0) | ||
| 88 | #define CDC_RX_CLSH_EAR_V_PA (0x0210) | ||
| 89 | #define CDC_RX_CLSH_HPH_V_HD (0x0214) | ||
| 90 | #define CDC_RX_CLSH_EAR_V_HD (0x0218) | ||
| 91 | #define CDC_RX_CLSH_K1_MSB (0x021C) | ||
| 92 | #define CDC_RX_CLSH_K1_MSB_COEFF_MASK GENMASK(3, 0) | ||
| 93 | #define CDC_RX_CLSH_K1_LSB (0x0220) | ||
| 94 | #define CDC_RX_CLSH_K2_MSB (0x0224) | ||
| 95 | #define CDC_RX_CLSH_K2_LSB (0x0228) | ||
| 96 | #define CDC_RX_CLSH_IDLE_CTRL (0x022C) | ||
| 97 | #define CDC_RX_CLSH_IDLE_HPH (0x0230) | ||
| 98 | #define CDC_RX_CLSH_IDLE_EAR (0x0234) | ||
| 99 | #define CDC_RX_CLSH_TEST0 (0x0238) | ||
| 100 | #define CDC_RX_CLSH_TEST1 (0x023C) | ||
| 101 | #define CDC_RX_CLSH_OVR_VREF (0x0240) | ||
| 102 | #define CDC_RX_CLSH_CLSG_CTL (0x0244) | ||
| 103 | #define CDC_RX_CLSH_CLSG_CFG1 (0x0248) | ||
| 104 | #define CDC_RX_CLSH_CLSG_CFG2 (0x024C) | ||
| 105 | #define CDC_RX_BCL_VBAT_PATH_CTL (0x0280) | ||
| 106 | #define CDC_RX_BCL_VBAT_CFG (0x0284) | ||
| 107 | #define CDC_RX_BCL_VBAT_ADC_CAL1 (0x0288) | ||
| 108 | #define CDC_RX_BCL_VBAT_ADC_CAL2 (0x028C) | ||
| 109 | #define CDC_RX_BCL_VBAT_ADC_CAL3 (0x0290) | ||
| 110 | #define CDC_RX_BCL_VBAT_PK_EST1 (0x0294) | ||
| 111 | #define CDC_RX_BCL_VBAT_PK_EST2 (0x0298) | ||
| 112 | #define CDC_RX_BCL_VBAT_PK_EST3 (0x029C) | ||
| 113 | #define CDC_RX_BCL_VBAT_RF_PROC1 (0x02A0) | ||
| 114 | #define CDC_RX_BCL_VBAT_RF_PROC2 (0x02A4) | ||
| 115 | #define CDC_RX_BCL_VBAT_TAC1 (0x02A8) | ||
| 116 | #define CDC_RX_BCL_VBAT_TAC2 (0x02AC) | ||
| 117 | #define CDC_RX_BCL_VBAT_TAC3 (0x02B0) | ||
| 118 | #define CDC_RX_BCL_VBAT_TAC4 (0x02B4) | ||
| 119 | #define CDC_RX_BCL_VBAT_GAIN_UPD1 (0x02B8) | ||
| 120 | #define CDC_RX_BCL_VBAT_GAIN_UPD2 (0x02BC) | ||
| 121 | #define CDC_RX_BCL_VBAT_GAIN_UPD3 (0x02C0) | ||
| 122 | #define CDC_RX_BCL_VBAT_GAIN_UPD4 (0x02C4) | ||
| 123 | #define CDC_RX_BCL_VBAT_GAIN_UPD5 (0x02C8) | ||
| 124 | #define CDC_RX_BCL_VBAT_DEBUG1 (0x02CC) | ||
| 125 | #define CDC_RX_BCL_VBAT_GAIN_UPD_MON (0x02D0) | ||
| 126 | #define CDC_RX_BCL_VBAT_GAIN_MON_VAL (0x02D4) | ||
| 127 | #define CDC_RX_BCL_VBAT_BAN (0x02D8) | ||
| 128 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD1 (0x02DC) | ||
| 129 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD2 (0x02E0) | ||
| 130 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD3 (0x02E4) | ||
| 131 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD4 (0x02E8) | ||
| 132 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD5 (0x02EC) | ||
| 133 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD6 (0x02F0) | ||
| 134 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD7 (0x02F4) | ||
| 135 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD8 (0x02F8) | ||
| 136 | #define CDC_RX_BCL_VBAT_BCL_GAIN_UPD9 (0x02FC) | ||
| 137 | #define CDC_RX_BCL_VBAT_ATTN1 (0x0300) | ||
| 138 | #define CDC_RX_BCL_VBAT_ATTN2 (0x0304) | ||
| 139 | #define CDC_RX_BCL_VBAT_ATTN3 (0x0308) | ||
| 140 | #define CDC_RX_BCL_VBAT_DECODE_CTL1 (0x030C) | ||
| 141 | #define CDC_RX_BCL_VBAT_DECODE_CTL2 (0x0310) | ||
| 142 | #define CDC_RX_BCL_VBAT_DECODE_CFG1 (0x0314) | ||
| 143 | #define CDC_RX_BCL_VBAT_DECODE_CFG2 (0x0318) | ||
| 144 | #define CDC_RX_BCL_VBAT_DECODE_CFG3 (0x031C) | ||
| 145 | #define CDC_RX_BCL_VBAT_DECODE_CFG4 (0x0320) | ||
| 146 | #define CDC_RX_BCL_VBAT_DECODE_ST (0x0324) | ||
| 147 | #define CDC_RX_INTR_CTRL_CFG (0x0340) | ||
| 148 | #define CDC_RX_INTR_CTRL_CLR_COMMIT (0x0344) | ||
| 149 | #define CDC_RX_INTR_CTRL_PIN1_MASK0 (0x0360) | ||
| 150 | #define CDC_RX_INTR_CTRL_PIN1_STATUS0 (0x0368) | ||
| 151 | #define CDC_RX_INTR_CTRL_PIN1_CLEAR0 (0x0370) | ||
| 152 | #define CDC_RX_INTR_CTRL_PIN2_MASK0 (0x0380) | ||
| 153 | #define CDC_RX_INTR_CTRL_PIN2_STATUS0 (0x0388) | ||
| 154 | #define CDC_RX_INTR_CTRL_PIN2_CLEAR0 (0x0390) | ||
| 155 | #define CDC_RX_INTR_CTRL_LEVEL0 (0x03C0) | ||
| 156 | #define CDC_RX_INTR_CTRL_BYPASS0 (0x03C8) | ||
| 157 | #define CDC_RX_INTR_CTRL_SET0 (0x03D0) | ||
| 158 | #define CDC_RX_RXn_RX_PATH_CTL(n) (0x0400 + 0x80 * n) | ||
| 159 | #define CDC_RX_RX0_RX_PATH_CTL (0x0400) | ||
| 160 | #define CDC_RX_PATH_RESET_EN_MASK BIT(6) | ||
| 161 | #define CDC_RX_PATH_CLK_EN_MASK BIT(5) | ||
| 162 | #define CDC_RX_PATH_CLK_ENABLE BIT(5) | ||
| 163 | #define CDC_RX_PATH_PGA_MUTE_MASK BIT(4) | ||
| 164 | #define CDC_RX_PATH_PGA_MUTE_ENABLE BIT(4) | ||
| 165 | #define CDC_RX_PATH_PCM_RATE_MASK GENMASK(3, 0) | ||
| 166 | #define CDC_RX_RXn_RX_PATH_CFG0(n) (0x0404 + 0x80 * n) | ||
| 167 | #define CDC_RX_RXn_COMP_EN_MASK BIT(1) | ||
| 168 | #define CDC_RX_RX0_RX_PATH_CFG0 (0x0404) | ||
| 169 | #define CDC_RX_RXn_CLSH_EN_MASK BIT(6) | ||
| 170 | #define CDC_RX_DLY_ZN_EN_MASK BIT(3) | ||
| 171 | #define CDC_RX_DLY_ZN_ENABLE BIT(3) | ||
| 172 | #define CDC_RX_RXn_HD2_EN_MASK BIT(2) | ||
| 173 | #define CDC_RX_RXn_RX_PATH_CFG1(n) (0x0408 + 0x80 * n) | ||
| 174 | #define CDC_RX_RXn_SIDETONE_EN_MASK BIT(4) | ||
| 175 | #define CDC_RX_RX0_RX_PATH_CFG1 (0x0408) | ||
| 176 | #define CDC_RX_RX0_HPH_L_EAR_SEL_MASK BIT(1) | ||
| 177 | #define CDC_RX_RXn_RX_PATH_CFG2(n) (0x040C + 0x80 * n) | ||
| 178 | #define CDC_RX_RXn_HPF_CUT_FREQ_MASK GENMASK(1, 0) | ||
| 179 | #define CDC_RX_RX0_RX_PATH_CFG2 (0x040C) | ||
| 180 | #define CDC_RX_RXn_RX_PATH_CFG3(n) (0x0410 + 0x80 * n) | ||
| 181 | #define CDC_RX_RX0_RX_PATH_CFG3 (0x0410) | ||
| 182 | #define CDC_RX_DC_COEFF_SEL_MASK GENMASK(1, 0) | ||
| 183 | #define CDC_RX_DC_COEFF_SEL_TWO 0x2 | ||
| 184 | #define CDC_RX_RXn_RX_VOL_CTL(n) (0x0414 + 0x80 * n) | ||
| 185 | #define CDC_RX_RX0_RX_VOL_CTL (0x0414) | ||
| 186 | #define CDC_RX_RXn_RX_PATH_MIX_CTL(n) (0x0418 + 0x80 * n) | ||
| 187 | #define CDC_RX_RXn_MIX_PCM_RATE_MASK GENMASK(3, 0) | ||
| 188 | #define CDC_RX_RXn_MIX_RESET_MASK BIT(6) | ||
| 189 | #define CDC_RX_RXn_MIX_RESET BIT(6) | ||
| 190 | #define CDC_RX_RXn_MIX_CLK_EN_MASK BIT(5) | ||
| 191 | #define CDC_RX_RX0_RX_PATH_MIX_CTL (0x0418) | ||
| 192 | #define CDC_RX_RX0_RX_PATH_MIX_CFG (0x041C) | ||
| 193 | #define CDC_RX_RXn_RX_VOL_MIX_CTL(n) (0x0420 + 0x80 * n) | ||
| 194 | #define CDC_RX_RX0_RX_VOL_MIX_CTL (0x0420) | ||
| 195 | #define CDC_RX_RX0_RX_PATH_SEC1 (0x0424) | ||
| 196 | #define CDC_RX_RX0_RX_PATH_SEC2 (0x0428) | ||
| 197 | #define CDC_RX_RX0_RX_PATH_SEC3 (0x042C) | ||
| 198 | #define CDC_RX_RX0_RX_PATH_SEC4 (0x0430) | ||
| 199 | #define CDC_RX_RX0_RX_PATH_SEC7 (0x0434) | ||
| 200 | #define CDC_RX_DSM_OUT_DELAY_SEL_MASK GENMASK(2, 0) | ||
| 201 | #define CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE 0x2 | ||
| 202 | #define CDC_RX_RX0_RX_PATH_MIX_SEC0 (0x0438) | ||
| 203 | #define CDC_RX_RX0_RX_PATH_MIX_SEC1 (0x043C) | ||
| 204 | #define CDC_RX_RXn_RX_PATH_DSM_CTL(n) (0x0440 + 0x80 * n) | ||
| 205 | #define CDC_RX_RXn_DSM_CLK_EN_MASK BIT(0) | ||
| 206 | #define CDC_RX_RX0_RX_PATH_DSM_CTL (0x0440) | ||
| 207 | #define CDC_RX_RX0_RX_PATH_DSM_DATA1 (0x0444) | ||
| 208 | #define CDC_RX_RX0_RX_PATH_DSM_DATA2 (0x0448) | ||
| 209 | #define CDC_RX_RX0_RX_PATH_DSM_DATA3 (0x044C) | ||
| 210 | #define CDC_RX_RX0_RX_PATH_DSM_DATA4 (0x0450) | ||
| 211 | #define CDC_RX_RX0_RX_PATH_DSM_DATA5 (0x0454) | ||
| 212 | #define CDC_RX_RX0_RX_PATH_DSM_DATA6 (0x0458) | ||
| 213 | #define CDC_RX_RX1_RX_PATH_CTL (0x0480) | ||
| 214 | #define CDC_RX_RX1_RX_PATH_CFG0 (0x0484) | ||
| 215 | #define CDC_RX_RX1_RX_PATH_CFG1 (0x0488) | ||
| 216 | #define CDC_RX_RX1_RX_PATH_CFG2 (0x048C) | ||
| 217 | #define CDC_RX_RX1_RX_PATH_CFG3 (0x0490) | ||
| 218 | #define CDC_RX_RX1_RX_VOL_CTL (0x0494) | ||
| 219 | #define CDC_RX_RX1_RX_PATH_MIX_CTL (0x0498) | ||
| 220 | #define CDC_RX_RX1_RX_PATH_MIX_CFG (0x049C) | ||
| 221 | #define CDC_RX_RX1_RX_VOL_MIX_CTL (0x04A0) | ||
| 222 | #define CDC_RX_RX1_RX_PATH_SEC1 (0x04A4) | ||
| 223 | #define CDC_RX_RX1_RX_PATH_SEC2 (0x04A8) | ||
| 224 | #define CDC_RX_RX1_RX_PATH_SEC3 (0x04AC) | ||
| 225 | #define CDC_RX_RXn_HD2_ALPHA_MASK GENMASK(5, 2) | ||
| 226 | #define CDC_RX_RX1_RX_PATH_SEC4 (0x04B0) | ||
| 227 | #define CDC_RX_RX1_RX_PATH_SEC7 (0x04B4) | ||
| 228 | #define CDC_RX_RX1_RX_PATH_MIX_SEC0 (0x04B8) | ||
| 229 | #define CDC_RX_RX1_RX_PATH_MIX_SEC1 (0x04BC) | ||
| 230 | #define CDC_RX_RX1_RX_PATH_DSM_CTL (0x04C0) | ||
| 231 | #define CDC_RX_RX1_RX_PATH_DSM_DATA1 (0x04C4) | ||
| 232 | #define CDC_RX_RX1_RX_PATH_DSM_DATA2 (0x04C8) | ||
| 233 | #define CDC_RX_RX1_RX_PATH_DSM_DATA3 (0x04CC) | ||
| 234 | #define CDC_RX_RX1_RX_PATH_DSM_DATA4 (0x04D0) | ||
| 235 | #define CDC_RX_RX1_RX_PATH_DSM_DATA5 (0x04D4) | ||
| 236 | #define CDC_RX_RX1_RX_PATH_DSM_DATA6 (0x04D8) | ||
| 237 | #define CDC_RX_RX2_RX_PATH_CTL (0x0500) | ||
| 238 | #define CDC_RX_RX2_RX_PATH_CFG0 (0x0504) | ||
| 239 | #define CDC_RX_RX2_CLSH_EN_MASK BIT(4) | ||
| 240 | #define CDC_RX_RX2_DLY_Z_EN_MASK BIT(3) | ||
| 241 | #define CDC_RX_RX2_RX_PATH_CFG1 (0x0508) | ||
| 242 | #define CDC_RX_RX2_RX_PATH_CFG2 (0x050C) | ||
| 243 | #define CDC_RX_RX2_RX_PATH_CFG3 (0x0510) | ||
| 244 | #define CDC_RX_RX2_RX_VOL_CTL (0x0514) | ||
| 245 | #define CDC_RX_RX2_RX_PATH_MIX_CTL (0x0518) | ||
| 246 | #define CDC_RX_RX2_RX_PATH_MIX_CFG (0x051C) | ||
| 247 | #define CDC_RX_RX2_RX_VOL_MIX_CTL (0x0520) | ||
| 248 | #define CDC_RX_RX2_RX_PATH_SEC0 (0x0524) | ||
| 249 | #define CDC_RX_RX2_RX_PATH_SEC1 (0x0528) | ||
| 250 | #define CDC_RX_RX2_RX_PATH_SEC2 (0x052C) | ||
| 251 | #define CDC_RX_RX2_RX_PATH_SEC3 (0x0530) | ||
| 252 | #define CDC_RX_RX2_RX_PATH_SEC4 (0x0534) | ||
| 253 | #define CDC_RX_RX2_RX_PATH_SEC5 (0x0538) | ||
| 254 | #define CDC_RX_RX2_RX_PATH_SEC6 (0x053C) | ||
| 255 | #define CDC_RX_RX2_RX_PATH_SEC7 (0x0540) | ||
| 256 | #define CDC_RX_RX2_RX_PATH_MIX_SEC0 (0x0544) | ||
| 257 | #define CDC_RX_RX2_RX_PATH_MIX_SEC1 (0x0548) | ||
| 258 | #define CDC_RX_RX2_RX_PATH_DSM_CTL (0x054C) | ||
| 259 | #define CDC_RX_IDLE_DETECT_PATH_CTL (0x0780) | ||
| 260 | #define CDC_RX_IDLE_DETECT_CFG0 (0x0784) | ||
| 261 | #define CDC_RX_IDLE_DETECT_CFG1 (0x0788) | ||
| 262 | #define CDC_RX_IDLE_DETECT_CFG2 (0x078C) | ||
| 263 | #define CDC_RX_IDLE_DETECT_CFG3 (0x0790) | ||
| 264 | #define CDC_RX_COMPANDERn_CTL0(n) (0x0800 + 0x40 * n) | ||
| 265 | #define CDC_RX_COMPANDERn_CLK_EN_MASK BIT(0) | ||
| 266 | #define CDC_RX_COMPANDERn_SOFT_RST_MASK BIT(1) | ||
| 267 | #define CDC_RX_COMPANDERn_HALT_MASK BIT(2) | ||
| 268 | #define CDC_RX_COMPANDER0_CTL0 (0x0800) | ||
| 269 | #define CDC_RX_COMPANDER0_CTL1 (0x0804) | ||
| 270 | #define CDC_RX_COMPANDER0_CTL2 (0x0808) | ||
| 271 | #define CDC_RX_COMPANDER0_CTL3 (0x080C) | ||
| 272 | #define CDC_RX_COMPANDER0_CTL4 (0x0810) | ||
| 273 | #define CDC_RX_COMPANDER0_CTL5 (0x0814) | ||
| 274 | #define CDC_RX_COMPANDER0_CTL6 (0x0818) | ||
| 275 | #define CDC_RX_COMPANDER0_CTL7 (0x081C) | ||
| 276 | #define CDC_RX_COMPANDER1_CTL0 (0x0840) | ||
| 277 | #define CDC_RX_COMPANDER1_CTL1 (0x0844) | ||
| 278 | #define CDC_RX_COMPANDER1_CTL2 (0x0848) | ||
| 279 | #define CDC_RX_COMPANDER1_CTL3 (0x084C) | ||
| 280 | #define CDC_RX_COMPANDER1_CTL4 (0x0850) | ||
| 281 | #define CDC_RX_COMPANDER1_CTL5 (0x0854) | ||
| 282 | #define CDC_RX_COMPANDER1_CTL6 (0x0858) | ||
| 283 | #define CDC_RX_COMPANDER1_CTL7 (0x085C) | ||
| 284 | #define CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK BIT(5) | ||
| 285 | #define CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL (0x0A00) | ||
| 286 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x0A04) | ||
| 287 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x0A08) | ||
| 288 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x0A0C) | ||
| 289 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x0A10) | ||
| 290 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x0A14) | ||
| 291 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x0A18) | ||
| 292 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x0A1C) | ||
| 293 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x0A20) | ||
| 294 | #define CDC_RX_SIDETONE_IIR0_IIR_CTL (0x0A24) | ||
| 295 | #define CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x0A28) | ||
| 296 | #define CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x0A2C) | ||
| 297 | #define CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x0A30) | ||
| 298 | #define CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL (0x0A80) | ||
| 299 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL (0x0A84) | ||
| 300 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL (0x0A88) | ||
| 301 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL (0x0A8C) | ||
| 302 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL (0x0A90) | ||
| 303 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL (0x0A94) | ||
| 304 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL (0x0A98) | ||
| 305 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL (0x0A9C) | ||
| 306 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL (0x0AA0) | ||
| 307 | #define CDC_RX_SIDETONE_IIR1_IIR_CTL (0x0AA4) | ||
| 308 | #define CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL (0x0AA8) | ||
| 309 | #define CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL (0x0AAC) | ||
| 310 | #define CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL (0x0AB0) | ||
| 311 | #define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0 (0x0B00) | ||
| 312 | #define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1 (0x0B04) | ||
| 313 | #define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2 (0x0B08) | ||
| 314 | #define CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3 (0x0B0C) | ||
| 315 | #define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0 (0x0B10) | ||
| 316 | #define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1 (0x0B14) | ||
| 317 | #define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2 (0x0B18) | ||
| 318 | #define CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3 (0x0B1C) | ||
| 319 | #define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x0B40) | ||
| 320 | #define CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x0B44) | ||
| 321 | #define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL (0x0B50) | ||
| 322 | #define CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 (0x0B54) | ||
| 323 | #define CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x0C00) | ||
| 324 | #define CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x0C04) | ||
| 325 | #define CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x0C40) | ||
| 326 | #define CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x0C44) | ||
| 327 | #define CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL (0x0C80) | ||
| 328 | #define CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0 (0x0C84) | ||
| 329 | #define CDC_RX_EC_ASRC0_CLK_RST_CTL (0x0D00) | ||
| 330 | #define CDC_RX_EC_ASRC0_CTL0 (0x0D04) | ||
| 331 | #define CDC_RX_EC_ASRC0_CTL1 (0x0D08) | ||
| 332 | #define CDC_RX_EC_ASRC0_FIFO_CTL (0x0D0C) | ||
| 333 | #define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x0D10) | ||
| 334 | #define CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x0D14) | ||
| 335 | #define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x0D18) | ||
| 336 | #define CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x0D1C) | ||
| 337 | #define CDC_RX_EC_ASRC0_STATUS_FIFO (0x0D20) | ||
| 338 | #define CDC_RX_EC_ASRC1_CLK_RST_CTL (0x0D40) | ||
| 339 | #define CDC_RX_EC_ASRC1_CTL0 (0x0D44) | ||
| 340 | #define CDC_RX_EC_ASRC1_CTL1 (0x0D48) | ||
| 341 | #define CDC_RX_EC_ASRC1_FIFO_CTL (0x0D4C) | ||
| 342 | #define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x0D50) | ||
| 343 | #define CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x0D54) | ||
| 344 | #define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x0D58) | ||
| 345 | #define CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x0D5C) | ||
| 346 | #define CDC_RX_EC_ASRC1_STATUS_FIFO (0x0D60) | ||
| 347 | #define CDC_RX_EC_ASRC2_CLK_RST_CTL (0x0D80) | ||
| 348 | #define CDC_RX_EC_ASRC2_CTL0 (0x0D84) | ||
| 349 | #define CDC_RX_EC_ASRC2_CTL1 (0x0D88) | ||
| 350 | #define CDC_RX_EC_ASRC2_FIFO_CTL (0x0D8C) | ||
| 351 | #define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB (0x0D90) | ||
| 352 | #define CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB (0x0D94) | ||
| 353 | #define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB (0x0D98) | ||
| 354 | #define CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB (0x0D9C) | ||
| 355 | #define CDC_RX_EC_ASRC2_STATUS_FIFO (0x0DA0) | ||
| 356 | #define CDC_RX_DSD0_PATH_CTL (0x0F00) | ||
| 357 | #define CDC_RX_DSD0_CFG0 (0x0F04) | ||
| 358 | #define CDC_RX_DSD0_CFG1 (0x0F08) | ||
| 359 | #define CDC_RX_DSD0_CFG2 (0x0F0C) | ||
| 360 | #define CDC_RX_DSD1_PATH_CTL (0x0F80) | ||
| 361 | #define CDC_RX_DSD1_CFG0 (0x0F84) | ||
| 362 | #define CDC_RX_DSD1_CFG1 (0x0F88) | ||
| 363 | #define CDC_RX_DSD1_CFG2 (0x0F8C) | ||
| 364 | #define RX_MAX_OFFSET (0x0F8C) | ||
| 365 | |||
| 366 | #define MCLK_FREQ 9600000 | ||
| 367 | |||
| 368 | #define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | ||
| 369 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ | ||
| 370 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ | ||
| 371 | SNDRV_PCM_RATE_384000) | ||
| 372 | /* Fractional Rates */ | ||
| 373 | #define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ | ||
| 374 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) | ||
| 375 | |||
| 376 | #define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | ||
| 377 | SNDRV_PCM_FMTBIT_S24_LE |\ | ||
| 378 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
| 379 | |||
| 380 | #define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | ||
| 381 | SNDRV_PCM_RATE_48000) | ||
| 382 | #define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | ||
| 383 | SNDRV_PCM_FMTBIT_S24_LE |\ | ||
| 384 | SNDRV_PCM_FMTBIT_S24_3LE) | ||
| 385 | |||
| 386 | #define RX_MACRO_MAX_DMA_CH_PER_PORT 2 | ||
| 387 | |||
| 388 | #define RX_MACRO_EC_MIX_TX0_MASK 0xf0 | ||
| 389 | #define RX_MACRO_EC_MIX_TX1_MASK 0x0f | ||
| 390 | #define RX_MACRO_EC_MIX_TX2_MASK 0x0f | ||
| 391 | |||
| 392 | #define COMP_MAX_COEFF 25 | ||
| 393 | #define RX_NUM_CLKS_MAX 5 | ||
| 394 | |||
| 395 | struct comp_coeff_val { | ||
| 396 | u8 lsb; | ||
| 397 | u8 msb; | ||
| 398 | }; | ||
| 399 | |||
| 400 | enum { | ||
| 401 | HPH_ULP, | ||
| 402 | HPH_LOHIFI, | ||
| 403 | HPH_MODE_MAX, | ||
| 404 | }; | ||
| 405 | |||
| 406 | static const struct comp_coeff_val comp_coeff_table[HPH_MODE_MAX][COMP_MAX_COEFF] = { | ||
| 407 | { | ||
| 408 | {0x40, 0x00}, | ||
| 409 | {0x4C, 0x00}, | ||
| 410 | {0x5A, 0x00}, | ||
| 411 | {0x6B, 0x00}, | ||
| 412 | {0x7F, 0x00}, | ||
| 413 | {0x97, 0x00}, | ||
| 414 | {0xB3, 0x00}, | ||
| 415 | {0xD5, 0x00}, | ||
| 416 | {0xFD, 0x00}, | ||
| 417 | {0x2D, 0x01}, | ||
| 418 | {0x66, 0x01}, | ||
| 419 | {0xA7, 0x01}, | ||
| 420 | {0xF8, 0x01}, | ||
| 421 | {0x57, 0x02}, | ||
| 422 | {0xC7, 0x02}, | ||
| 423 | {0x4B, 0x03}, | ||
| 424 | {0xE9, 0x03}, | ||
| 425 | {0xA3, 0x04}, | ||
| 426 | {0x7D, 0x05}, | ||
| 427 | {0x90, 0x06}, | ||
| 428 | {0xD1, 0x07}, | ||
| 429 | {0x49, 0x09}, | ||
| 430 | {0x00, 0x0B}, | ||
| 431 | {0x01, 0x0D}, | ||
| 432 | {0x59, 0x0F}, | ||
| 433 | }, | ||
| 434 | { | ||
| 435 | {0x40, 0x00}, | ||
| 436 | {0x4C, 0x00}, | ||
| 437 | {0x5A, 0x00}, | ||
| 438 | {0x6B, 0x00}, | ||
| 439 | {0x80, 0x00}, | ||
| 440 | {0x98, 0x00}, | ||
| 441 | {0xB4, 0x00}, | ||
| 442 | {0xD5, 0x00}, | ||
| 443 | {0xFE, 0x00}, | ||
| 444 | {0x2E, 0x01}, | ||
| 445 | {0x66, 0x01}, | ||
| 446 | {0xA9, 0x01}, | ||
| 447 | {0xF8, 0x01}, | ||
| 448 | {0x56, 0x02}, | ||
| 449 | {0xC4, 0x02}, | ||
| 450 | {0x4F, 0x03}, | ||
| 451 | {0xF0, 0x03}, | ||
| 452 | {0xAE, 0x04}, | ||
| 453 | {0x8B, 0x05}, | ||
| 454 | {0x8E, 0x06}, | ||
| 455 | {0xBC, 0x07}, | ||
| 456 | {0x56, 0x09}, | ||
| 457 | {0x0F, 0x0B}, | ||
| 458 | {0x13, 0x0D}, | ||
| 459 | {0x6F, 0x0F}, | ||
| 460 | }, | ||
| 461 | }; | ||
| 462 | |||
| 463 | struct rx_macro_reg_mask_val { | ||
| 464 | u16 reg; | ||
| 465 | u8 mask; | ||
| 466 | u8 val; | ||
| 467 | }; | ||
| 468 | |||
| 469 | enum { | ||
| 470 | INTERP_HPHL, | ||
| 471 | INTERP_HPHR, | ||
| 472 | INTERP_AUX, | ||
| 473 | INTERP_MAX | ||
| 474 | }; | ||
| 475 | |||
| 476 | enum { | ||
| 477 | RX_MACRO_RX0, | ||
| 478 | RX_MACRO_RX1, | ||
| 479 | RX_MACRO_RX2, | ||
| 480 | RX_MACRO_RX3, | ||
| 481 | RX_MACRO_RX4, | ||
| 482 | RX_MACRO_RX5, | ||
| 483 | RX_MACRO_PORTS_MAX | ||
| 484 | }; | ||
| 485 | |||
| 486 | enum { | ||
| 487 | RX_MACRO_COMP1, /* HPH_L */ | ||
| 488 | RX_MACRO_COMP2, /* HPH_R */ | ||
| 489 | RX_MACRO_COMP_MAX | ||
| 490 | }; | ||
| 491 | |||
| 492 | enum { | ||
| 493 | RX_MACRO_EC0_MUX = 0, | ||
| 494 | RX_MACRO_EC1_MUX, | ||
| 495 | RX_MACRO_EC2_MUX, | ||
| 496 | RX_MACRO_EC_MUX_MAX, | ||
| 497 | }; | ||
| 498 | |||
| 499 | enum { | ||
| 500 | INTn_1_INP_SEL_ZERO = 0, | ||
| 501 | INTn_1_INP_SEL_DEC0, | ||
| 502 | INTn_1_INP_SEL_DEC1, | ||
| 503 | INTn_1_INP_SEL_IIR0, | ||
| 504 | INTn_1_INP_SEL_IIR1, | ||
| 505 | INTn_1_INP_SEL_RX0, | ||
| 506 | INTn_1_INP_SEL_RX1, | ||
| 507 | INTn_1_INP_SEL_RX2, | ||
| 508 | INTn_1_INP_SEL_RX3, | ||
| 509 | INTn_1_INP_SEL_RX4, | ||
| 510 | INTn_1_INP_SEL_RX5, | ||
| 511 | }; | ||
| 512 | |||
| 513 | enum { | ||
| 514 | INTn_2_INP_SEL_ZERO = 0, | ||
| 515 | INTn_2_INP_SEL_RX0, | ||
| 516 | INTn_2_INP_SEL_RX1, | ||
| 517 | INTn_2_INP_SEL_RX2, | ||
| 518 | INTn_2_INP_SEL_RX3, | ||
| 519 | INTn_2_INP_SEL_RX4, | ||
| 520 | INTn_2_INP_SEL_RX5, | ||
| 521 | }; | ||
| 522 | |||
| 523 | enum { | ||
| 524 | INTERP_MAIN_PATH, | ||
| 525 | INTERP_MIX_PATH, | ||
| 526 | }; | ||
| 527 | |||
| 528 | /* Codec supports 2 IIR filters */ | ||
| 529 | enum { | ||
| 530 | IIR0 = 0, | ||
| 531 | IIR1, | ||
| 532 | IIR_MAX, | ||
| 533 | }; | ||
| 534 | |||
| 535 | /* Each IIR has 5 Filter Stages */ | ||
| 536 | enum { | ||
| 537 | BAND1 = 0, | ||
| 538 | BAND2, | ||
| 539 | BAND3, | ||
| 540 | BAND4, | ||
| 541 | BAND5, | ||
| 542 | BAND_MAX, | ||
| 543 | }; | ||
| 544 | |||
| 545 | #define RX_MACRO_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX) | ||
| 546 | |||
| 547 | #define RX_MACRO_IIR_FILTER_CTL(xname, iidx, bidx) \ | ||
| 548 | { \ | ||
| 549 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
| 550 | .info = rx_macro_iir_filter_info, \ | ||
| 551 | .get = rx_macro_get_iir_band_audio_mixer, \ | ||
| 552 | .put = rx_macro_put_iir_band_audio_mixer, \ | ||
| 553 | .private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \ | ||
| 554 | .iir_idx = iidx, \ | ||
| 555 | .band_idx = bidx, \ | ||
| 556 | .bytes_ext = {.max = RX_MACRO_IIR_FILTER_SIZE, }, \ | ||
| 557 | } \ | ||
| 558 | } | ||
| 559 | |||
| 560 | struct interp_sample_rate { | ||
| 561 | int sample_rate; | ||
| 562 | int rate_val; | ||
| 563 | }; | ||
| 564 | |||
| 565 | static struct interp_sample_rate sr_val_tbl[] = { | ||
| 566 | {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5}, | ||
| 567 | {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA}, | ||
| 568 | {176400, 0xB}, {352800, 0xC}, | ||
| 569 | }; | ||
| 570 | |||
| 571 | enum { | ||
| 572 | RX_MACRO_AIF_INVALID = 0, | ||
| 573 | RX_MACRO_AIF1_PB, | ||
| 574 | RX_MACRO_AIF2_PB, | ||
| 575 | RX_MACRO_AIF3_PB, | ||
| 576 | RX_MACRO_AIF4_PB, | ||
| 577 | RX_MACRO_AIF_ECHO, | ||
| 578 | RX_MACRO_MAX_DAIS, | ||
| 579 | }; | ||
| 580 | |||
| 581 | enum { | ||
| 582 | RX_MACRO_AIF1_CAP = 0, | ||
| 583 | RX_MACRO_AIF2_CAP, | ||
| 584 | RX_MACRO_AIF3_CAP, | ||
| 585 | RX_MACRO_MAX_AIF_CAP_DAIS | ||
| 586 | }; | ||
| 587 | |||
| 588 | struct rx_macro { | ||
| 589 | struct device *dev; | ||
| 590 | int comp_enabled[RX_MACRO_COMP_MAX]; | ||
| 591 | /* Main path clock users count */ | ||
| 592 | int main_clk_users[INTERP_MAX]; | ||
| 593 | int rx_port_value[RX_MACRO_PORTS_MAX]; | ||
| 594 | u16 prim_int_users[INTERP_MAX]; | ||
| 595 | int rx_mclk_users; | ||
| 596 | bool reset_swr; | ||
| 597 | int clsh_users; | ||
| 598 | int rx_mclk_cnt; | ||
| 599 | bool is_ear_mode_on; | ||
| 600 | bool hph_pwr_mode; | ||
| 601 | bool hph_hd2_mode; | ||
| 602 | struct snd_soc_component *component; | ||
| 603 | unsigned long active_ch_mask[RX_MACRO_MAX_DAIS]; | ||
| 604 | unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS]; | ||
| 605 | u16 bit_width[RX_MACRO_MAX_DAIS]; | ||
| 606 | int is_softclip_on; | ||
| 607 | int is_aux_hpf_on; | ||
| 608 | int softclip_clk_users; | ||
| 609 | |||
| 610 | struct regmap *regmap; | ||
| 611 | struct clk_bulk_data clks[RX_NUM_CLKS_MAX]; | ||
| 612 | struct clk_hw hw; | ||
| 613 | }; | ||
| 614 | #define to_rx_macro(_hw) container_of(_hw, struct rx_macro, hw) | ||
| 615 | |||
| 616 | struct wcd_iir_filter_ctl { | ||
| 617 | unsigned int iir_idx; | ||
| 618 | unsigned int band_idx; | ||
| 619 | struct soc_bytes_ext bytes_ext; | ||
| 620 | }; | ||
| 621 | |||
| 622 | static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); | ||
| 623 | |||
| 624 | static const char * const rx_int_mix_mux_text[] = { | ||
| 625 | "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" | ||
| 626 | }; | ||
| 627 | |||
| 628 | static const char * const rx_prim_mix_text[] = { | ||
| 629 | "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", | ||
| 630 | "RX3", "RX4", "RX5" | ||
| 631 | }; | ||
| 632 | |||
| 633 | static const char * const rx_sidetone_mix_text[] = { | ||
| 634 | "ZERO", "SRC0", "SRC1", "SRC_SUM" | ||
| 635 | }; | ||
| 636 | |||
| 637 | static const char * const iir_inp_mux_text[] = { | ||
| 638 | "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", | ||
| 639 | "RX0", "RX1", "RX2", "RX3", "RX4", "RX5" | ||
| 640 | }; | ||
| 641 | |||
| 642 | static const char * const rx_int_dem_inp_mux_text[] = { | ||
| 643 | "NORMAL_DSM_OUT", "CLSH_DSM_OUT", | ||
| 644 | }; | ||
| 645 | |||
| 646 | static const char * const rx_int0_1_interp_mux_text[] = { | ||
| 647 | "ZERO", "RX INT0_1 MIX1", | ||
| 648 | }; | ||
| 649 | |||
| 650 | static const char * const rx_int1_1_interp_mux_text[] = { | ||
| 651 | "ZERO", "RX INT1_1 MIX1", | ||
| 652 | }; | ||
| 653 | |||
| 654 | static const char * const rx_int2_1_interp_mux_text[] = { | ||
| 655 | "ZERO", "RX INT2_1 MIX1", | ||
| 656 | }; | ||
| 657 | |||
| 658 | static const char * const rx_int0_2_interp_mux_text[] = { | ||
| 659 | "ZERO", "RX INT0_2 MUX", | ||
| 660 | }; | ||
| 661 | |||
| 662 | static const char * const rx_int1_2_interp_mux_text[] = { | ||
| 663 | "ZERO", "RX INT1_2 MUX", | ||
| 664 | }; | ||
| 665 | |||
| 666 | static const char * const rx_int2_2_interp_mux_text[] = { | ||
| 667 | "ZERO", "RX INT2_2 MUX", | ||
| 668 | }; | ||
| 669 | |||
| 670 | static const char *const rx_macro_mux_text[] = { | ||
| 671 | "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB" | ||
| 672 | }; | ||
| 673 | |||
| 674 | static const char *const rx_macro_hph_pwr_mode_text[] = { | ||
| 675 | "ULP", "LOHIFI" | ||
| 676 | }; | ||
| 677 | |||
| 678 | static const char * const rx_echo_mux_text[] = { | ||
| 679 | "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2" | ||
| 680 | }; | ||
| 681 | |||
| 682 | static const struct soc_enum rx_macro_hph_pwr_mode_enum = | ||
| 683 | SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text); | ||
| 684 | static const struct soc_enum rx_mix_tx2_mux_enum = | ||
| 685 | SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4, rx_echo_mux_text); | ||
| 686 | static const struct soc_enum rx_mix_tx1_mux_enum = | ||
| 687 | SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4, rx_echo_mux_text); | ||
| 688 | static const struct soc_enum rx_mix_tx0_mux_enum = | ||
| 689 | SOC_ENUM_SINGLE(CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4, rx_echo_mux_text); | ||
| 690 | |||
| 691 | static SOC_ENUM_SINGLE_DECL(rx_int0_2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 0, | ||
| 692 | rx_int_mix_mux_text); | ||
| 693 | static SOC_ENUM_SINGLE_DECL(rx_int1_2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 0, | ||
| 694 | rx_int_mix_mux_text); | ||
| 695 | static SOC_ENUM_SINGLE_DECL(rx_int2_2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 0, | ||
| 696 | rx_int_mix_mux_text); | ||
| 697 | |||
| 698 | static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 0, | ||
| 699 | rx_prim_mix_text); | ||
| 700 | static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT0_CFG0, 4, | ||
| 701 | rx_prim_mix_text); | ||
| 702 | static SOC_ENUM_SINGLE_DECL(rx_int0_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT0_CFG1, 4, | ||
| 703 | rx_prim_mix_text); | ||
| 704 | static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 0, | ||
| 705 | rx_prim_mix_text); | ||
| 706 | static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT1_CFG0, 4, | ||
| 707 | rx_prim_mix_text); | ||
| 708 | static SOC_ENUM_SINGLE_DECL(rx_int1_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT1_CFG1, 4, | ||
| 709 | rx_prim_mix_text); | ||
| 710 | static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp0_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 0, | ||
| 711 | rx_prim_mix_text); | ||
| 712 | static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp1_enum, CDC_RX_INP_MUX_RX_INT2_CFG0, 4, | ||
| 713 | rx_prim_mix_text); | ||
| 714 | static SOC_ENUM_SINGLE_DECL(rx_int2_1_mix_inp2_enum, CDC_RX_INP_MUX_RX_INT2_CFG1, 4, | ||
| 715 | rx_prim_mix_text); | ||
| 716 | |||
| 717 | static SOC_ENUM_SINGLE_DECL(rx_int0_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, | ||
| 718 | rx_sidetone_mix_text); | ||
| 719 | static SOC_ENUM_SINGLE_DECL(rx_int1_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, | ||
| 720 | rx_sidetone_mix_text); | ||
| 721 | static SOC_ENUM_SINGLE_DECL(rx_int2_mix2_inp_enum, CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6, | ||
| 722 | rx_sidetone_mix_text); | ||
| 723 | static SOC_ENUM_SINGLE_DECL(iir0_inp0_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0, | ||
| 724 | iir_inp_mux_text); | ||
| 725 | static SOC_ENUM_SINGLE_DECL(iir0_inp1_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0, | ||
| 726 | iir_inp_mux_text); | ||
| 727 | static SOC_ENUM_SINGLE_DECL(iir0_inp2_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0, | ||
| 728 | iir_inp_mux_text); | ||
| 729 | static SOC_ENUM_SINGLE_DECL(iir0_inp3_enum, CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0, | ||
| 730 | iir_inp_mux_text); | ||
| 731 | static SOC_ENUM_SINGLE_DECL(iir1_inp0_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0, | ||
| 732 | iir_inp_mux_text); | ||
| 733 | static SOC_ENUM_SINGLE_DECL(iir1_inp1_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0, | ||
| 734 | iir_inp_mux_text); | ||
| 735 | static SOC_ENUM_SINGLE_DECL(iir1_inp2_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0, | ||
| 736 | iir_inp_mux_text); | ||
| 737 | static SOC_ENUM_SINGLE_DECL(iir1_inp3_enum, CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0, | ||
| 738 | iir_inp_mux_text); | ||
| 739 | |||
| 740 | static SOC_ENUM_SINGLE_DECL(rx_int0_1_interp_enum, SND_SOC_NOPM, 0, | ||
| 741 | rx_int0_1_interp_mux_text); | ||
| 742 | static SOC_ENUM_SINGLE_DECL(rx_int1_1_interp_enum, SND_SOC_NOPM, 0, | ||
| 743 | rx_int1_1_interp_mux_text); | ||
| 744 | static SOC_ENUM_SINGLE_DECL(rx_int2_1_interp_enum, SND_SOC_NOPM, 0, | ||
| 745 | rx_int2_1_interp_mux_text); | ||
| 746 | static SOC_ENUM_SINGLE_DECL(rx_int0_2_interp_enum, SND_SOC_NOPM, 0, | ||
| 747 | rx_int0_2_interp_mux_text); | ||
| 748 | static SOC_ENUM_SINGLE_DECL(rx_int1_2_interp_enum, SND_SOC_NOPM, 0, | ||
| 749 | rx_int1_2_interp_mux_text); | ||
| 750 | static SOC_ENUM_SINGLE_DECL(rx_int2_2_interp_enum, SND_SOC_NOPM, 0, | ||
| 751 | rx_int2_2_interp_mux_text); | ||
| 752 | static SOC_ENUM_SINGLE_DECL(rx_int0_dem_inp_enum, CDC_RX_RX0_RX_PATH_CFG1, 0, | ||
| 753 | rx_int_dem_inp_mux_text); | ||
| 754 | static SOC_ENUM_SINGLE_DECL(rx_int1_dem_inp_enum, CDC_RX_RX1_RX_PATH_CFG1, 0, | ||
| 755 | rx_int_dem_inp_mux_text); | ||
| 756 | |||
| 757 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx0_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 758 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx1_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 759 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx2_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 760 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx3_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 761 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx4_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 762 | static SOC_ENUM_SINGLE_DECL(rx_macro_rx5_enum, SND_SOC_NOPM, 0, rx_macro_mux_text); | ||
| 763 | |||
| 764 | static const struct snd_kcontrol_new rx_mix_tx1_mux = | ||
| 765 | SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum); | ||
| 766 | static const struct snd_kcontrol_new rx_mix_tx2_mux = | ||
| 767 | SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum); | ||
| 768 | static const struct snd_kcontrol_new rx_int0_2_mux = | ||
| 769 | SOC_DAPM_ENUM("rx_int0_2", rx_int0_2_enum); | ||
| 770 | static const struct snd_kcontrol_new rx_int1_2_mux = | ||
| 771 | SOC_DAPM_ENUM("rx_int1_2", rx_int1_2_enum); | ||
| 772 | static const struct snd_kcontrol_new rx_int2_2_mux = | ||
| 773 | SOC_DAPM_ENUM("rx_int2_2", rx_int2_2_enum); | ||
| 774 | static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = | ||
| 775 | SOC_DAPM_ENUM("rx_int0_1_mix_inp0", rx_int0_1_mix_inp0_enum); | ||
| 776 | static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = | ||
| 777 | SOC_DAPM_ENUM("rx_int0_1_mix_inp1", rx_int0_1_mix_inp1_enum); | ||
| 778 | static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = | ||
| 779 | SOC_DAPM_ENUM("rx_int0_1_mix_inp2", rx_int0_1_mix_inp2_enum); | ||
| 780 | static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = | ||
| 781 | SOC_DAPM_ENUM("rx_int1_1_mix_inp0", rx_int1_1_mix_inp0_enum); | ||
| 782 | static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = | ||
| 783 | SOC_DAPM_ENUM("rx_int1_1_mix_inp1", rx_int1_1_mix_inp1_enum); | ||
| 784 | static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = | ||
| 785 | SOC_DAPM_ENUM("rx_int1_1_mix_inp2", rx_int1_1_mix_inp2_enum); | ||
| 786 | static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = | ||
| 787 | SOC_DAPM_ENUM("rx_int2_1_mix_inp0", rx_int2_1_mix_inp0_enum); | ||
| 788 | static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = | ||
| 789 | SOC_DAPM_ENUM("rx_int2_1_mix_inp1", rx_int2_1_mix_inp1_enum); | ||
| 790 | static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = | ||
| 791 | SOC_DAPM_ENUM("rx_int2_1_mix_inp2", rx_int2_1_mix_inp2_enum); | ||
| 792 | static const struct snd_kcontrol_new rx_int0_mix2_inp_mux = | ||
| 793 | SOC_DAPM_ENUM("rx_int0_mix2_inp", rx_int0_mix2_inp_enum); | ||
| 794 | static const struct snd_kcontrol_new rx_int1_mix2_inp_mux = | ||
| 795 | SOC_DAPM_ENUM("rx_int1_mix2_inp", rx_int1_mix2_inp_enum); | ||
| 796 | static const struct snd_kcontrol_new rx_int2_mix2_inp_mux = | ||
| 797 | SOC_DAPM_ENUM("rx_int2_mix2_inp", rx_int2_mix2_inp_enum); | ||
| 798 | static const struct snd_kcontrol_new iir0_inp0_mux = | ||
| 799 | SOC_DAPM_ENUM("iir0_inp0", iir0_inp0_enum); | ||
| 800 | static const struct snd_kcontrol_new iir0_inp1_mux = | ||
| 801 | SOC_DAPM_ENUM("iir0_inp1", iir0_inp1_enum); | ||
| 802 | static const struct snd_kcontrol_new iir0_inp2_mux = | ||
| 803 | SOC_DAPM_ENUM("iir0_inp2", iir0_inp2_enum); | ||
| 804 | static const struct snd_kcontrol_new iir0_inp3_mux = | ||
| 805 | SOC_DAPM_ENUM("iir0_inp3", iir0_inp3_enum); | ||
| 806 | static const struct snd_kcontrol_new iir1_inp0_mux = | ||
| 807 | SOC_DAPM_ENUM("iir1_inp0", iir1_inp0_enum); | ||
| 808 | static const struct snd_kcontrol_new iir1_inp1_mux = | ||
| 809 | SOC_DAPM_ENUM("iir1_inp1", iir1_inp1_enum); | ||
| 810 | static const struct snd_kcontrol_new iir1_inp2_mux = | ||
| 811 | SOC_DAPM_ENUM("iir1_inp2", iir1_inp2_enum); | ||
| 812 | static const struct snd_kcontrol_new iir1_inp3_mux = | ||
| 813 | SOC_DAPM_ENUM("iir1_inp3", iir1_inp3_enum); | ||
| 814 | static const struct snd_kcontrol_new rx_int0_1_interp_mux = | ||
| 815 | SOC_DAPM_ENUM("rx_int0_1_interp", rx_int0_1_interp_enum); | ||
| 816 | static const struct snd_kcontrol_new rx_int1_1_interp_mux = | ||
| 817 | SOC_DAPM_ENUM("rx_int1_1_interp", rx_int1_1_interp_enum); | ||
| 818 | static const struct snd_kcontrol_new rx_int2_1_interp_mux = | ||
| 819 | SOC_DAPM_ENUM("rx_int2_1_interp", rx_int2_1_interp_enum); | ||
| 820 | static const struct snd_kcontrol_new rx_int0_2_interp_mux = | ||
| 821 | SOC_DAPM_ENUM("rx_int0_2_interp", rx_int0_2_interp_enum); | ||
| 822 | static const struct snd_kcontrol_new rx_int1_2_interp_mux = | ||
| 823 | SOC_DAPM_ENUM("rx_int1_2_interp", rx_int1_2_interp_enum); | ||
| 824 | static const struct snd_kcontrol_new rx_int2_2_interp_mux = | ||
| 825 | SOC_DAPM_ENUM("rx_int2_2_interp", rx_int2_2_interp_enum); | ||
| 826 | static const struct snd_kcontrol_new rx_mix_tx0_mux = | ||
| 827 | SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum); | ||
| 828 | |||
| 829 | static const struct reg_default rx_defaults[] = { | ||
| 830 | /* RX Macro */ | ||
| 831 | { CDC_RX_TOP_TOP_CFG0, 0x00 }, | ||
| 832 | { CDC_RX_TOP_SWR_CTRL, 0x00 }, | ||
| 833 | { CDC_RX_TOP_DEBUG, 0x00 }, | ||
| 834 | { CDC_RX_TOP_DEBUG_BUS, 0x00 }, | ||
| 835 | { CDC_RX_TOP_DEBUG_EN0, 0x00 }, | ||
| 836 | { CDC_RX_TOP_DEBUG_EN1, 0x00 }, | ||
| 837 | { CDC_RX_TOP_DEBUG_EN2, 0x00 }, | ||
| 838 | { CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00 }, | ||
| 839 | { CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00 }, | ||
| 840 | { CDC_RX_TOP_HPHL_COMP_LUT, 0x00 }, | ||
| 841 | { CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00 }, | ||
| 842 | { CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00 }, | ||
| 843 | { CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00 }, | ||
| 844 | { CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00 }, | ||
| 845 | { CDC_RX_TOP_HPHR_COMP_LUT, 0x00 }, | ||
| 846 | { CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00 }, | ||
| 847 | { CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00 }, | ||
| 848 | { CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11 }, | ||
| 849 | { CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20 }, | ||
| 850 | { CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00 }, | ||
| 851 | { CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00 }, | ||
| 852 | { CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11 }, | ||
| 853 | { CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20 }, | ||
| 854 | { CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00 }, | ||
| 855 | { CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00 }, | ||
| 856 | { CDC_RX_TOP_RX_I2S_CTL, 0x0C }, | ||
| 857 | { CDC_RX_TOP_TX_I2S2_CTL, 0x0C }, | ||
| 858 | { CDC_RX_TOP_I2S_CLK, 0x0C }, | ||
| 859 | { CDC_RX_TOP_I2S_RESET, 0x00 }, | ||
| 860 | { CDC_RX_TOP_I2S_MUX, 0x00 }, | ||
| 861 | { CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, | ||
| 862 | { CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, | ||
| 863 | { CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00 }, | ||
| 864 | { CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00 }, | ||
| 865 | { CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08 }, | ||
| 866 | { CDC_RX_SOFTCLIP_CRC, 0x00 }, | ||
| 867 | { CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38 }, | ||
| 868 | { CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00 }, | ||
| 869 | { CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00 }, | ||
| 870 | { CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00 }, | ||
| 871 | { CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00 }, | ||
| 872 | { CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00 }, | ||
| 873 | { CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00 }, | ||
| 874 | { CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00 }, | ||
| 875 | { CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00 }, | ||
| 876 | { CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00 }, | ||
| 877 | { CDC_RX_CLSH_CRC, 0x00 }, | ||
| 878 | { CDC_RX_CLSH_DLY_CTRL, 0x03 }, | ||
| 879 | { CDC_RX_CLSH_DECAY_CTRL, 0x02 }, | ||
| 880 | { CDC_RX_CLSH_HPH_V_PA, 0x1C }, | ||
| 881 | { CDC_RX_CLSH_EAR_V_PA, 0x39 }, | ||
| 882 | { CDC_RX_CLSH_HPH_V_HD, 0x0C }, | ||
| 883 | { CDC_RX_CLSH_EAR_V_HD, 0x0C }, | ||
| 884 | { CDC_RX_CLSH_K1_MSB, 0x01 }, | ||
| 885 | { CDC_RX_CLSH_K1_LSB, 0x00 }, | ||
| 886 | { CDC_RX_CLSH_K2_MSB, 0x00 }, | ||
| 887 | { CDC_RX_CLSH_K2_LSB, 0x80 }, | ||
| 888 | { CDC_RX_CLSH_IDLE_CTRL, 0x00 }, | ||
| 889 | { CDC_RX_CLSH_IDLE_HPH, 0x00 }, | ||
| 890 | { CDC_RX_CLSH_IDLE_EAR, 0x00 }, | ||
| 891 | { CDC_RX_CLSH_TEST0, 0x07 }, | ||
| 892 | { CDC_RX_CLSH_TEST1, 0x00 }, | ||
| 893 | { CDC_RX_CLSH_OVR_VREF, 0x00 }, | ||
| 894 | { CDC_RX_CLSH_CLSG_CTL, 0x02 }, | ||
| 895 | { CDC_RX_CLSH_CLSG_CFG1, 0x9A }, | ||
| 896 | { CDC_RX_CLSH_CLSG_CFG2, 0x10 }, | ||
| 897 | { CDC_RX_BCL_VBAT_PATH_CTL, 0x00 }, | ||
| 898 | { CDC_RX_BCL_VBAT_CFG, 0x10 }, | ||
| 899 | { CDC_RX_BCL_VBAT_ADC_CAL1, 0x00 }, | ||
| 900 | { CDC_RX_BCL_VBAT_ADC_CAL2, 0x00 }, | ||
| 901 | { CDC_RX_BCL_VBAT_ADC_CAL3, 0x04 }, | ||
| 902 | { CDC_RX_BCL_VBAT_PK_EST1, 0xE0 }, | ||
| 903 | { CDC_RX_BCL_VBAT_PK_EST2, 0x01 }, | ||
| 904 | { CDC_RX_BCL_VBAT_PK_EST3, 0x40 }, | ||
| 905 | { CDC_RX_BCL_VBAT_RF_PROC1, 0x2A }, | ||
| 906 | { CDC_RX_BCL_VBAT_RF_PROC1, 0x00 }, | ||
| 907 | { CDC_RX_BCL_VBAT_TAC1, 0x00 }, | ||
| 908 | { CDC_RX_BCL_VBAT_TAC2, 0x18 }, | ||
| 909 | { CDC_RX_BCL_VBAT_TAC3, 0x18 }, | ||
| 910 | { CDC_RX_BCL_VBAT_TAC4, 0x03 }, | ||
| 911 | { CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01 }, | ||
| 912 | { CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00 }, | ||
| 913 | { CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00 }, | ||
| 914 | { CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64 }, | ||
| 915 | { CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01 }, | ||
| 916 | { CDC_RX_BCL_VBAT_DEBUG1, 0x00 }, | ||
| 917 | { CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00 }, | ||
| 918 | { CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00 }, | ||
| 919 | { CDC_RX_BCL_VBAT_BAN, 0x0C }, | ||
| 920 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00 }, | ||
| 921 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77 }, | ||
| 922 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01 }, | ||
| 923 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00 }, | ||
| 924 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B }, | ||
| 925 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00 }, | ||
| 926 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01 }, | ||
| 927 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00 }, | ||
| 928 | { CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00 }, | ||
| 929 | { CDC_RX_BCL_VBAT_ATTN1, 0x04 }, | ||
| 930 | { CDC_RX_BCL_VBAT_ATTN2, 0x08 }, | ||
| 931 | { CDC_RX_BCL_VBAT_ATTN3, 0x0C }, | ||
| 932 | { CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0 }, | ||
| 933 | { CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00 }, | ||
| 934 | { CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00 }, | ||
| 935 | { CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00 }, | ||
| 936 | { CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00 }, | ||
| 937 | { CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00 }, | ||
| 938 | { CDC_RX_BCL_VBAT_DECODE_ST, 0x00 }, | ||
| 939 | { CDC_RX_INTR_CTRL_CFG, 0x00 }, | ||
| 940 | { CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00 }, | ||
| 941 | { CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF }, | ||
| 942 | { CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00 }, | ||
| 943 | { CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00 }, | ||
| 944 | { CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF }, | ||
| 945 | { CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00 }, | ||
| 946 | { CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00 }, | ||
| 947 | { CDC_RX_INTR_CTRL_LEVEL0, 0x00 }, | ||
| 948 | { CDC_RX_INTR_CTRL_BYPASS0, 0x00 }, | ||
| 949 | { CDC_RX_INTR_CTRL_SET0, 0x00 }, | ||
| 950 | { CDC_RX_RX0_RX_PATH_CTL, 0x04 }, | ||
| 951 | { CDC_RX_RX0_RX_PATH_CFG0, 0x00 }, | ||
| 952 | { CDC_RX_RX0_RX_PATH_CFG1, 0x64 }, | ||
| 953 | { CDC_RX_RX0_RX_PATH_CFG2, 0x8F }, | ||
| 954 | { CDC_RX_RX0_RX_PATH_CFG3, 0x00 }, | ||
| 955 | { CDC_RX_RX0_RX_VOL_CTL, 0x00 }, | ||
| 956 | { CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04 }, | ||
| 957 | { CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E }, | ||
| 958 | { CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00 }, | ||
| 959 | { CDC_RX_RX0_RX_PATH_SEC1, 0x08 }, | ||
| 960 | { CDC_RX_RX0_RX_PATH_SEC2, 0x00 }, | ||
| 961 | { CDC_RX_RX0_RX_PATH_SEC3, 0x00 }, | ||
| 962 | { CDC_RX_RX0_RX_PATH_SEC4, 0x00 }, | ||
| 963 | { CDC_RX_RX0_RX_PATH_SEC7, 0x00 }, | ||
| 964 | { CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08 }, | ||
| 965 | { CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00 }, | ||
| 966 | { CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08 }, | ||
| 967 | { CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00 }, | ||
| 968 | { CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00 }, | ||
| 969 | { CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00 }, | ||
| 970 | { CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55 }, | ||
| 971 | { CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55 }, | ||
| 972 | { CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55 }, | ||
| 973 | { CDC_RX_RX1_RX_PATH_CTL, 0x04 }, | ||
| 974 | { CDC_RX_RX1_RX_PATH_CFG0, 0x00 }, | ||
| 975 | { CDC_RX_RX1_RX_PATH_CFG1, 0x64 }, | ||
| 976 | { CDC_RX_RX1_RX_PATH_CFG2, 0x8F }, | ||
| 977 | { CDC_RX_RX1_RX_PATH_CFG3, 0x00 }, | ||
| 978 | { CDC_RX_RX1_RX_VOL_CTL, 0x00 }, | ||
| 979 | { CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04 }, | ||
| 980 | { CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E }, | ||
| 981 | { CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00 }, | ||
| 982 | { CDC_RX_RX1_RX_PATH_SEC1, 0x08 }, | ||
| 983 | { CDC_RX_RX1_RX_PATH_SEC2, 0x00 }, | ||
| 984 | { CDC_RX_RX1_RX_PATH_SEC3, 0x00 }, | ||
| 985 | { CDC_RX_RX1_RX_PATH_SEC4, 0x00 }, | ||
| 986 | { CDC_RX_RX1_RX_PATH_SEC7, 0x00 }, | ||
| 987 | { CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08 }, | ||
| 988 | { CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00 }, | ||
| 989 | { CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08 }, | ||
| 990 | { CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00 }, | ||
| 991 | { CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00 }, | ||
| 992 | { CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00 }, | ||
| 993 | { CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55 }, | ||
| 994 | { CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55 }, | ||
| 995 | { CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55 }, | ||
| 996 | { CDC_RX_RX2_RX_PATH_CTL, 0x04 }, | ||
| 997 | { CDC_RX_RX2_RX_PATH_CFG0, 0x00 }, | ||
| 998 | { CDC_RX_RX2_RX_PATH_CFG1, 0x64 }, | ||
| 999 | { CDC_RX_RX2_RX_PATH_CFG2, 0x8F }, | ||
| 1000 | { CDC_RX_RX2_RX_PATH_CFG3, 0x00 }, | ||
| 1001 | { CDC_RX_RX2_RX_VOL_CTL, 0x00 }, | ||
| 1002 | { CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04 }, | ||
| 1003 | { CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E }, | ||
| 1004 | { CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00 }, | ||
| 1005 | { CDC_RX_RX2_RX_PATH_SEC0, 0x04 }, | ||
| 1006 | { CDC_RX_RX2_RX_PATH_SEC1, 0x08 }, | ||
| 1007 | { CDC_RX_RX2_RX_PATH_SEC2, 0x00 }, | ||
| 1008 | { CDC_RX_RX2_RX_PATH_SEC3, 0x00 }, | ||
| 1009 | { CDC_RX_RX2_RX_PATH_SEC4, 0x00 }, | ||
| 1010 | { CDC_RX_RX2_RX_PATH_SEC5, 0x00 }, | ||
| 1011 | { CDC_RX_RX2_RX_PATH_SEC6, 0x00 }, | ||
| 1012 | { CDC_RX_RX2_RX_PATH_SEC7, 0x00 }, | ||
| 1013 | { CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08 }, | ||
| 1014 | { CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00 }, | ||
| 1015 | { CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00 }, | ||
| 1016 | { CDC_RX_IDLE_DETECT_PATH_CTL, 0x00 }, | ||
| 1017 | { CDC_RX_IDLE_DETECT_CFG0, 0x07 }, | ||
| 1018 | { CDC_RX_IDLE_DETECT_CFG1, 0x3C }, | ||
| 1019 | { CDC_RX_IDLE_DETECT_CFG2, 0x00 }, | ||
| 1020 | { CDC_RX_IDLE_DETECT_CFG3, 0x00 }, | ||
| 1021 | { CDC_RX_COMPANDER0_CTL0, 0x60 }, | ||
| 1022 | { CDC_RX_COMPANDER0_CTL1, 0xDB }, | ||
| 1023 | { CDC_RX_COMPANDER0_CTL2, 0xFF }, | ||
| 1024 | { CDC_RX_COMPANDER0_CTL3, 0x35 }, | ||
| 1025 | { CDC_RX_COMPANDER0_CTL4, 0xFF }, | ||
| 1026 | { CDC_RX_COMPANDER0_CTL5, 0x00 }, | ||
| 1027 | { CDC_RX_COMPANDER0_CTL6, 0x01 }, | ||
| 1028 | { CDC_RX_COMPANDER0_CTL7, 0x28 }, | ||
| 1029 | { CDC_RX_COMPANDER1_CTL0, 0x60 }, | ||
| 1030 | { CDC_RX_COMPANDER1_CTL1, 0xDB }, | ||
| 1031 | { CDC_RX_COMPANDER1_CTL2, 0xFF }, | ||
| 1032 | { CDC_RX_COMPANDER1_CTL3, 0x35 }, | ||
| 1033 | { CDC_RX_COMPANDER1_CTL4, 0xFF }, | ||
| 1034 | { CDC_RX_COMPANDER1_CTL5, 0x00 }, | ||
| 1035 | { CDC_RX_COMPANDER1_CTL6, 0x01 }, | ||
| 1036 | { CDC_RX_COMPANDER1_CTL7, 0x28 }, | ||
| 1037 | { CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00 }, | ||
| 1038 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00 }, | ||
| 1039 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00 }, | ||
| 1040 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00 }, | ||
| 1041 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00 }, | ||
| 1042 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00 }, | ||
| 1043 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00 }, | ||
| 1044 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00 }, | ||
| 1045 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00 }, | ||
| 1046 | { CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40 }, | ||
| 1047 | { CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00 }, | ||
| 1048 | { CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00 }, | ||
| 1049 | { CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00 }, | ||
| 1050 | { CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00 }, | ||
| 1051 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00 }, | ||
| 1052 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00 }, | ||
| 1053 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00 }, | ||
| 1054 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00 }, | ||
| 1055 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00 }, | ||
| 1056 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00 }, | ||
| 1057 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00 }, | ||
| 1058 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00 }, | ||
| 1059 | { CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40 }, | ||
| 1060 | { CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00 }, | ||
| 1061 | { CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00 }, | ||
| 1062 | { CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00 }, | ||
| 1063 | { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00 }, | ||
| 1064 | { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00 }, | ||
| 1065 | { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00 }, | ||
| 1066 | { CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00 }, | ||
| 1067 | { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00 }, | ||
| 1068 | { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00 }, | ||
| 1069 | { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00 }, | ||
| 1070 | { CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00 }, | ||
| 1071 | { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04 }, | ||
| 1072 | { CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00 }, | ||
| 1073 | { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04 }, | ||
| 1074 | { CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00 }, | ||
| 1075 | { CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00 }, | ||
| 1076 | { CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01 }, | ||
| 1077 | { CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00 }, | ||
| 1078 | { CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01 }, | ||
| 1079 | { CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00 }, | ||
| 1080 | { CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01 }, | ||
| 1081 | { CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00 }, | ||
| 1082 | { CDC_RX_EC_ASRC0_CTL0, 0x00 }, | ||
| 1083 | { CDC_RX_EC_ASRC0_CTL1, 0x00 }, | ||
| 1084 | { CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8 }, | ||
| 1085 | { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00 }, | ||
| 1086 | { CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00 }, | ||
| 1087 | { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00 }, | ||
| 1088 | { CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00 }, | ||
| 1089 | { CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00 }, | ||
| 1090 | { CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00 }, | ||
| 1091 | { CDC_RX_EC_ASRC1_CTL0, 0x00 }, | ||
| 1092 | { CDC_RX_EC_ASRC1_CTL1, 0x00 }, | ||
| 1093 | { CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8 }, | ||
| 1094 | { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00 }, | ||
| 1095 | { CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00 }, | ||
| 1096 | { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00 }, | ||
| 1097 | { CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00 }, | ||
| 1098 | { CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00 }, | ||
| 1099 | { CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00 }, | ||
| 1100 | { CDC_RX_EC_ASRC2_CTL0, 0x00 }, | ||
| 1101 | { CDC_RX_EC_ASRC2_CTL1, 0x00 }, | ||
| 1102 | { CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8 }, | ||
| 1103 | { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00 }, | ||
| 1104 | { CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00 }, | ||
| 1105 | { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00 }, | ||
| 1106 | { CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00 }, | ||
| 1107 | { CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00 }, | ||
| 1108 | { CDC_RX_DSD0_PATH_CTL, 0x00 }, | ||
| 1109 | { CDC_RX_DSD0_CFG0, 0x00 }, | ||
| 1110 | { CDC_RX_DSD0_CFG1, 0x62 }, | ||
| 1111 | { CDC_RX_DSD0_CFG2, 0x96 }, | ||
| 1112 | { CDC_RX_DSD1_PATH_CTL, 0x00 }, | ||
| 1113 | { CDC_RX_DSD1_CFG0, 0x00 }, | ||
| 1114 | { CDC_RX_DSD1_CFG1, 0x62 }, | ||
| 1115 | { CDC_RX_DSD1_CFG2, 0x96 }, | ||
| 1116 | }; | ||
| 1117 | |||
| 1118 | static bool rx_is_wronly_register(struct device *dev, | ||
| 1119 | unsigned int reg) | ||
| 1120 | { | ||
| 1121 | switch (reg) { | ||
| 1122 | case CDC_RX_BCL_VBAT_GAIN_UPD_MON: | ||
| 1123 | case CDC_RX_INTR_CTRL_CLR_COMMIT: | ||
| 1124 | case CDC_RX_INTR_CTRL_PIN1_CLEAR0: | ||
| 1125 | case CDC_RX_INTR_CTRL_PIN2_CLEAR0: | ||
| 1126 | return true; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | return false; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | static bool rx_is_volatile_register(struct device *dev, unsigned int reg) | ||
| 1133 | { | ||
| 1134 | /* Update volatile list for rx/tx macros */ | ||
| 1135 | switch (reg) { | ||
| 1136 | case CDC_RX_TOP_HPHL_COMP_RD_LSB: | ||
| 1137 | case CDC_RX_TOP_HPHL_COMP_WR_LSB: | ||
| 1138 | case CDC_RX_TOP_HPHL_COMP_RD_MSB: | ||
| 1139 | case CDC_RX_TOP_HPHL_COMP_WR_MSB: | ||
| 1140 | case CDC_RX_TOP_HPHR_COMP_RD_LSB: | ||
| 1141 | case CDC_RX_TOP_HPHR_COMP_WR_LSB: | ||
| 1142 | case CDC_RX_TOP_HPHR_COMP_RD_MSB: | ||
| 1143 | case CDC_RX_TOP_HPHR_COMP_WR_MSB: | ||
| 1144 | case CDC_RX_TOP_DSD0_DEBUG_CFG2: | ||
| 1145 | case CDC_RX_TOP_DSD1_DEBUG_CFG2: | ||
| 1146 | case CDC_RX_BCL_VBAT_GAIN_MON_VAL: | ||
| 1147 | case CDC_RX_BCL_VBAT_DECODE_ST: | ||
| 1148 | case CDC_RX_INTR_CTRL_PIN1_STATUS0: | ||
| 1149 | case CDC_RX_INTR_CTRL_PIN2_STATUS0: | ||
| 1150 | case CDC_RX_COMPANDER0_CTL6: | ||
| 1151 | case CDC_RX_COMPANDER1_CTL6: | ||
| 1152 | case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: | ||
| 1153 | case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: | ||
| 1154 | case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: | ||
| 1155 | case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: | ||
| 1156 | case CDC_RX_EC_ASRC0_STATUS_FIFO: | ||
| 1157 | case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: | ||
| 1158 | case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: | ||
| 1159 | case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: | ||
| 1160 | case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: | ||
| 1161 | case CDC_RX_EC_ASRC1_STATUS_FIFO: | ||
| 1162 | case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: | ||
| 1163 | case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: | ||
| 1164 | case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: | ||
| 1165 | case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: | ||
| 1166 | case CDC_RX_EC_ASRC2_STATUS_FIFO: | ||
| 1167 | return true; | ||
| 1168 | } | ||
| 1169 | return false; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | static bool rx_is_rw_register(struct device *dev, unsigned int reg) | ||
| 1173 | { | ||
| 1174 | switch (reg) { | ||
| 1175 | case CDC_RX_TOP_TOP_CFG0: | ||
| 1176 | case CDC_RX_TOP_SWR_CTRL: | ||
| 1177 | case CDC_RX_TOP_DEBUG: | ||
| 1178 | case CDC_RX_TOP_DEBUG_BUS: | ||
| 1179 | case CDC_RX_TOP_DEBUG_EN0: | ||
| 1180 | case CDC_RX_TOP_DEBUG_EN1: | ||
| 1181 | case CDC_RX_TOP_DEBUG_EN2: | ||
| 1182 | case CDC_RX_TOP_HPHL_COMP_WR_LSB: | ||
| 1183 | case CDC_RX_TOP_HPHL_COMP_WR_MSB: | ||
| 1184 | case CDC_RX_TOP_HPHL_COMP_LUT: | ||
| 1185 | case CDC_RX_TOP_HPHR_COMP_WR_LSB: | ||
| 1186 | case CDC_RX_TOP_HPHR_COMP_WR_MSB: | ||
| 1187 | case CDC_RX_TOP_HPHR_COMP_LUT: | ||
| 1188 | case CDC_RX_TOP_DSD0_DEBUG_CFG0: | ||
| 1189 | case CDC_RX_TOP_DSD0_DEBUG_CFG1: | ||
| 1190 | case CDC_RX_TOP_DSD0_DEBUG_CFG3: | ||
| 1191 | case CDC_RX_TOP_DSD1_DEBUG_CFG0: | ||
| 1192 | case CDC_RX_TOP_DSD1_DEBUG_CFG1: | ||
| 1193 | case CDC_RX_TOP_DSD1_DEBUG_CFG3: | ||
| 1194 | case CDC_RX_TOP_RX_I2S_CTL: | ||
| 1195 | case CDC_RX_TOP_TX_I2S2_CTL: | ||
| 1196 | case CDC_RX_TOP_I2S_CLK: | ||
| 1197 | case CDC_RX_TOP_I2S_RESET: | ||
| 1198 | case CDC_RX_TOP_I2S_MUX: | ||
| 1199 | case CDC_RX_CLK_RST_CTRL_MCLK_CONTROL: | ||
| 1200 | case CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL: | ||
| 1201 | case CDC_RX_CLK_RST_CTRL_SWR_CONTROL: | ||
| 1202 | case CDC_RX_CLK_RST_CTRL_DSD_CONTROL: | ||
| 1203 | case CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL: | ||
| 1204 | case CDC_RX_SOFTCLIP_CRC: | ||
| 1205 | case CDC_RX_SOFTCLIP_SOFTCLIP_CTRL: | ||
| 1206 | case CDC_RX_INP_MUX_RX_INT0_CFG0: | ||
| 1207 | case CDC_RX_INP_MUX_RX_INT0_CFG1: | ||
| 1208 | case CDC_RX_INP_MUX_RX_INT1_CFG0: | ||
| 1209 | case CDC_RX_INP_MUX_RX_INT1_CFG1: | ||
| 1210 | case CDC_RX_INP_MUX_RX_INT2_CFG0: | ||
| 1211 | case CDC_RX_INP_MUX_RX_INT2_CFG1: | ||
| 1212 | case CDC_RX_INP_MUX_RX_MIX_CFG4: | ||
| 1213 | case CDC_RX_INP_MUX_RX_MIX_CFG5: | ||
| 1214 | case CDC_RX_INP_MUX_SIDETONE_SRC_CFG0: | ||
| 1215 | case CDC_RX_CLSH_CRC: | ||
| 1216 | case CDC_RX_CLSH_DLY_CTRL: | ||
| 1217 | case CDC_RX_CLSH_DECAY_CTRL: | ||
| 1218 | case CDC_RX_CLSH_HPH_V_PA: | ||
| 1219 | case CDC_RX_CLSH_EAR_V_PA: | ||
| 1220 | case CDC_RX_CLSH_HPH_V_HD: | ||
| 1221 | case CDC_RX_CLSH_EAR_V_HD: | ||
| 1222 | case CDC_RX_CLSH_K1_MSB: | ||
| 1223 | case CDC_RX_CLSH_K1_LSB: | ||
| 1224 | case CDC_RX_CLSH_K2_MSB: | ||
| 1225 | case CDC_RX_CLSH_K2_LSB: | ||
| 1226 | case CDC_RX_CLSH_IDLE_CTRL: | ||
| 1227 | case CDC_RX_CLSH_IDLE_HPH: | ||
| 1228 | case CDC_RX_CLSH_IDLE_EAR: | ||
| 1229 | case CDC_RX_CLSH_TEST0: | ||
| 1230 | case CDC_RX_CLSH_TEST1: | ||
| 1231 | case CDC_RX_CLSH_OVR_VREF: | ||
| 1232 | case CDC_RX_CLSH_CLSG_CTL: | ||
| 1233 | case CDC_RX_CLSH_CLSG_CFG1: | ||
| 1234 | case CDC_RX_CLSH_CLSG_CFG2: | ||
| 1235 | case CDC_RX_BCL_VBAT_PATH_CTL: | ||
| 1236 | case CDC_RX_BCL_VBAT_CFG: | ||
| 1237 | case CDC_RX_BCL_VBAT_ADC_CAL1: | ||
| 1238 | case CDC_RX_BCL_VBAT_ADC_CAL2: | ||
| 1239 | case CDC_RX_BCL_VBAT_ADC_CAL3: | ||
| 1240 | case CDC_RX_BCL_VBAT_PK_EST1: | ||
| 1241 | case CDC_RX_BCL_VBAT_PK_EST2: | ||
| 1242 | case CDC_RX_BCL_VBAT_PK_EST3: | ||
| 1243 | case CDC_RX_BCL_VBAT_RF_PROC1: | ||
| 1244 | case CDC_RX_BCL_VBAT_RF_PROC2: | ||
| 1245 | case CDC_RX_BCL_VBAT_TAC1: | ||
| 1246 | case CDC_RX_BCL_VBAT_TAC2: | ||
| 1247 | case CDC_RX_BCL_VBAT_TAC3: | ||
| 1248 | case CDC_RX_BCL_VBAT_TAC4: | ||
| 1249 | case CDC_RX_BCL_VBAT_GAIN_UPD1: | ||
| 1250 | case CDC_RX_BCL_VBAT_GAIN_UPD2: | ||
| 1251 | case CDC_RX_BCL_VBAT_GAIN_UPD3: | ||
| 1252 | case CDC_RX_BCL_VBAT_GAIN_UPD4: | ||
| 1253 | case CDC_RX_BCL_VBAT_GAIN_UPD5: | ||
| 1254 | case CDC_RX_BCL_VBAT_DEBUG1: | ||
| 1255 | case CDC_RX_BCL_VBAT_BAN: | ||
| 1256 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD1: | ||
| 1257 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD2: | ||
| 1258 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD3: | ||
| 1259 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD4: | ||
| 1260 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD5: | ||
| 1261 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD6: | ||
| 1262 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD7: | ||
| 1263 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD8: | ||
| 1264 | case CDC_RX_BCL_VBAT_BCL_GAIN_UPD9: | ||
| 1265 | case CDC_RX_BCL_VBAT_ATTN1: | ||
| 1266 | case CDC_RX_BCL_VBAT_ATTN2: | ||
| 1267 | case CDC_RX_BCL_VBAT_ATTN3: | ||
| 1268 | case CDC_RX_BCL_VBAT_DECODE_CTL1: | ||
| 1269 | case CDC_RX_BCL_VBAT_DECODE_CTL2: | ||
| 1270 | case CDC_RX_BCL_VBAT_DECODE_CFG1: | ||
| 1271 | case CDC_RX_BCL_VBAT_DECODE_CFG2: | ||
| 1272 | case CDC_RX_BCL_VBAT_DECODE_CFG3: | ||
| 1273 | case CDC_RX_BCL_VBAT_DECODE_CFG4: | ||
| 1274 | case CDC_RX_INTR_CTRL_CFG: | ||
| 1275 | case CDC_RX_INTR_CTRL_PIN1_MASK0: | ||
| 1276 | case CDC_RX_INTR_CTRL_PIN2_MASK0: | ||
| 1277 | case CDC_RX_INTR_CTRL_LEVEL0: | ||
| 1278 | case CDC_RX_INTR_CTRL_BYPASS0: | ||
| 1279 | case CDC_RX_INTR_CTRL_SET0: | ||
| 1280 | case CDC_RX_RX0_RX_PATH_CTL: | ||
| 1281 | case CDC_RX_RX0_RX_PATH_CFG0: | ||
| 1282 | case CDC_RX_RX0_RX_PATH_CFG1: | ||
| 1283 | case CDC_RX_RX0_RX_PATH_CFG2: | ||
| 1284 | case CDC_RX_RX0_RX_PATH_CFG3: | ||
| 1285 | case CDC_RX_RX0_RX_VOL_CTL: | ||
| 1286 | case CDC_RX_RX0_RX_PATH_MIX_CTL: | ||
| 1287 | case CDC_RX_RX0_RX_PATH_MIX_CFG: | ||
| 1288 | case CDC_RX_RX0_RX_VOL_MIX_CTL: | ||
| 1289 | case CDC_RX_RX0_RX_PATH_SEC1: | ||
| 1290 | case CDC_RX_RX0_RX_PATH_SEC2: | ||
| 1291 | case CDC_RX_RX0_RX_PATH_SEC3: | ||
| 1292 | case CDC_RX_RX0_RX_PATH_SEC4: | ||
| 1293 | case CDC_RX_RX0_RX_PATH_SEC7: | ||
| 1294 | case CDC_RX_RX0_RX_PATH_MIX_SEC0: | ||
| 1295 | case CDC_RX_RX0_RX_PATH_MIX_SEC1: | ||
| 1296 | case CDC_RX_RX0_RX_PATH_DSM_CTL: | ||
| 1297 | case CDC_RX_RX0_RX_PATH_DSM_DATA1: | ||
| 1298 | case CDC_RX_RX0_RX_PATH_DSM_DATA2: | ||
| 1299 | case CDC_RX_RX0_RX_PATH_DSM_DATA3: | ||
| 1300 | case CDC_RX_RX0_RX_PATH_DSM_DATA4: | ||
| 1301 | case CDC_RX_RX0_RX_PATH_DSM_DATA5: | ||
| 1302 | case CDC_RX_RX0_RX_PATH_DSM_DATA6: | ||
| 1303 | case CDC_RX_RX1_RX_PATH_CTL: | ||
| 1304 | case CDC_RX_RX1_RX_PATH_CFG0: | ||
| 1305 | case CDC_RX_RX1_RX_PATH_CFG1: | ||
| 1306 | case CDC_RX_RX1_RX_PATH_CFG2: | ||
| 1307 | case CDC_RX_RX1_RX_PATH_CFG3: | ||
| 1308 | case CDC_RX_RX1_RX_VOL_CTL: | ||
| 1309 | case CDC_RX_RX1_RX_PATH_MIX_CTL: | ||
| 1310 | case CDC_RX_RX1_RX_PATH_MIX_CFG: | ||
| 1311 | case CDC_RX_RX1_RX_VOL_MIX_CTL: | ||
| 1312 | case CDC_RX_RX1_RX_PATH_SEC1: | ||
| 1313 | case CDC_RX_RX1_RX_PATH_SEC2: | ||
| 1314 | case CDC_RX_RX1_RX_PATH_SEC3: | ||
| 1315 | case CDC_RX_RX1_RX_PATH_SEC4: | ||
| 1316 | case CDC_RX_RX1_RX_PATH_SEC7: | ||
| 1317 | case CDC_RX_RX1_RX_PATH_MIX_SEC0: | ||
| 1318 | case CDC_RX_RX1_RX_PATH_MIX_SEC1: | ||
| 1319 | case CDC_RX_RX1_RX_PATH_DSM_CTL: | ||
| 1320 | case CDC_RX_RX1_RX_PATH_DSM_DATA1: | ||
| 1321 | case CDC_RX_RX1_RX_PATH_DSM_DATA2: | ||
| 1322 | case CDC_RX_RX1_RX_PATH_DSM_DATA3: | ||
| 1323 | case CDC_RX_RX1_RX_PATH_DSM_DATA4: | ||
| 1324 | case CDC_RX_RX1_RX_PATH_DSM_DATA5: | ||
| 1325 | case CDC_RX_RX1_RX_PATH_DSM_DATA6: | ||
| 1326 | case CDC_RX_RX2_RX_PATH_CTL: | ||
| 1327 | case CDC_RX_RX2_RX_PATH_CFG0: | ||
| 1328 | case CDC_RX_RX2_RX_PATH_CFG1: | ||
| 1329 | case CDC_RX_RX2_RX_PATH_CFG2: | ||
| 1330 | case CDC_RX_RX2_RX_PATH_CFG3: | ||
| 1331 | case CDC_RX_RX2_RX_VOL_CTL: | ||
| 1332 | case CDC_RX_RX2_RX_PATH_MIX_CTL: | ||
| 1333 | case CDC_RX_RX2_RX_PATH_MIX_CFG: | ||
| 1334 | case CDC_RX_RX2_RX_VOL_MIX_CTL: | ||
| 1335 | case CDC_RX_RX2_RX_PATH_SEC0: | ||
| 1336 | case CDC_RX_RX2_RX_PATH_SEC1: | ||
| 1337 | case CDC_RX_RX2_RX_PATH_SEC2: | ||
| 1338 | case CDC_RX_RX2_RX_PATH_SEC3: | ||
| 1339 | case CDC_RX_RX2_RX_PATH_SEC4: | ||
| 1340 | case CDC_RX_RX2_RX_PATH_SEC5: | ||
| 1341 | case CDC_RX_RX2_RX_PATH_SEC6: | ||
| 1342 | case CDC_RX_RX2_RX_PATH_SEC7: | ||
| 1343 | case CDC_RX_RX2_RX_PATH_MIX_SEC0: | ||
| 1344 | case CDC_RX_RX2_RX_PATH_MIX_SEC1: | ||
| 1345 | case CDC_RX_RX2_RX_PATH_DSM_CTL: | ||
| 1346 | case CDC_RX_IDLE_DETECT_PATH_CTL: | ||
| 1347 | case CDC_RX_IDLE_DETECT_CFG0: | ||
| 1348 | case CDC_RX_IDLE_DETECT_CFG1: | ||
| 1349 | case CDC_RX_IDLE_DETECT_CFG2: | ||
| 1350 | case CDC_RX_IDLE_DETECT_CFG3: | ||
| 1351 | case CDC_RX_COMPANDER0_CTL0: | ||
| 1352 | case CDC_RX_COMPANDER0_CTL1: | ||
| 1353 | case CDC_RX_COMPANDER0_CTL2: | ||
| 1354 | case CDC_RX_COMPANDER0_CTL3: | ||
| 1355 | case CDC_RX_COMPANDER0_CTL4: | ||
| 1356 | case CDC_RX_COMPANDER0_CTL5: | ||
| 1357 | case CDC_RX_COMPANDER0_CTL7: | ||
| 1358 | case CDC_RX_COMPANDER1_CTL0: | ||
| 1359 | case CDC_RX_COMPANDER1_CTL1: | ||
| 1360 | case CDC_RX_COMPANDER1_CTL2: | ||
| 1361 | case CDC_RX_COMPANDER1_CTL3: | ||
| 1362 | case CDC_RX_COMPANDER1_CTL4: | ||
| 1363 | case CDC_RX_COMPANDER1_CTL5: | ||
| 1364 | case CDC_RX_COMPANDER1_CTL7: | ||
| 1365 | case CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL: | ||
| 1366 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL: | ||
| 1367 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL: | ||
| 1368 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL: | ||
| 1369 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL: | ||
| 1370 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL: | ||
| 1371 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL: | ||
| 1372 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL: | ||
| 1373 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL: | ||
| 1374 | case CDC_RX_SIDETONE_IIR0_IIR_CTL: | ||
| 1375 | case CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL: | ||
| 1376 | case CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL: | ||
| 1377 | case CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL: | ||
| 1378 | case CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL: | ||
| 1379 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL: | ||
| 1380 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL: | ||
| 1381 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL: | ||
| 1382 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL: | ||
| 1383 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL: | ||
| 1384 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL: | ||
| 1385 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL: | ||
| 1386 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL: | ||
| 1387 | case CDC_RX_SIDETONE_IIR1_IIR_CTL: | ||
| 1388 | case CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL: | ||
| 1389 | case CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL: | ||
| 1390 | case CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL: | ||
| 1391 | case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0: | ||
| 1392 | case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1: | ||
| 1393 | case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2: | ||
| 1394 | case CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3: | ||
| 1395 | case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0: | ||
| 1396 | case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1: | ||
| 1397 | case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2: | ||
| 1398 | case CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3: | ||
| 1399 | case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL: | ||
| 1400 | case CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1: | ||
| 1401 | case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL: | ||
| 1402 | case CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1: | ||
| 1403 | case CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL: | ||
| 1404 | case CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0: | ||
| 1405 | case CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL: | ||
| 1406 | case CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0: | ||
| 1407 | case CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL: | ||
| 1408 | case CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0: | ||
| 1409 | case CDC_RX_EC_ASRC0_CLK_RST_CTL: | ||
| 1410 | case CDC_RX_EC_ASRC0_CTL0: | ||
| 1411 | case CDC_RX_EC_ASRC0_CTL1: | ||
| 1412 | case CDC_RX_EC_ASRC0_FIFO_CTL: | ||
| 1413 | case CDC_RX_EC_ASRC1_CLK_RST_CTL: | ||
| 1414 | case CDC_RX_EC_ASRC1_CTL0: | ||
| 1415 | case CDC_RX_EC_ASRC1_CTL1: | ||
| 1416 | case CDC_RX_EC_ASRC1_FIFO_CTL: | ||
| 1417 | case CDC_RX_EC_ASRC2_CLK_RST_CTL: | ||
| 1418 | case CDC_RX_EC_ASRC2_CTL0: | ||
| 1419 | case CDC_RX_EC_ASRC2_CTL1: | ||
| 1420 | case CDC_RX_EC_ASRC2_FIFO_CTL: | ||
| 1421 | case CDC_RX_DSD0_PATH_CTL: | ||
| 1422 | case CDC_RX_DSD0_CFG0: | ||
| 1423 | case CDC_RX_DSD0_CFG1: | ||
| 1424 | case CDC_RX_DSD0_CFG2: | ||
| 1425 | case CDC_RX_DSD1_PATH_CTL: | ||
| 1426 | case CDC_RX_DSD1_CFG0: | ||
| 1427 | case CDC_RX_DSD1_CFG1: | ||
| 1428 | case CDC_RX_DSD1_CFG2: | ||
| 1429 | return true; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | return false; | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | static bool rx_is_writeable_register(struct device *dev, unsigned int reg) | ||
| 1436 | { | ||
| 1437 | bool ret; | ||
| 1438 | |||
| 1439 | ret = rx_is_rw_register(dev, reg); | ||
| 1440 | if (!ret) | ||
| 1441 | return rx_is_wronly_register(dev, reg); | ||
| 1442 | |||
| 1443 | return ret; | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | static bool rx_is_readable_register(struct device *dev, unsigned int reg) | ||
| 1447 | { | ||
| 1448 | switch (reg) { | ||
| 1449 | case CDC_RX_TOP_HPHL_COMP_RD_LSB: | ||
| 1450 | case CDC_RX_TOP_HPHL_COMP_RD_MSB: | ||
| 1451 | case CDC_RX_TOP_HPHR_COMP_RD_LSB: | ||
| 1452 | case CDC_RX_TOP_HPHR_COMP_RD_MSB: | ||
| 1453 | case CDC_RX_TOP_DSD0_DEBUG_CFG2: | ||
| 1454 | case CDC_RX_TOP_DSD1_DEBUG_CFG2: | ||
| 1455 | case CDC_RX_BCL_VBAT_GAIN_MON_VAL: | ||
| 1456 | case CDC_RX_BCL_VBAT_DECODE_ST: | ||
| 1457 | case CDC_RX_INTR_CTRL_PIN1_STATUS0: | ||
| 1458 | case CDC_RX_INTR_CTRL_PIN2_STATUS0: | ||
| 1459 | case CDC_RX_COMPANDER0_CTL6: | ||
| 1460 | case CDC_RX_COMPANDER1_CTL6: | ||
| 1461 | case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB: | ||
| 1462 | case CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB: | ||
| 1463 | case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB: | ||
| 1464 | case CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB: | ||
| 1465 | case CDC_RX_EC_ASRC0_STATUS_FIFO: | ||
| 1466 | case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB: | ||
| 1467 | case CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB: | ||
| 1468 | case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB: | ||
| 1469 | case CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB: | ||
| 1470 | case CDC_RX_EC_ASRC1_STATUS_FIFO: | ||
| 1471 | case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB: | ||
| 1472 | case CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB: | ||
| 1473 | case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB: | ||
| 1474 | case CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB: | ||
| 1475 | case CDC_RX_EC_ASRC2_STATUS_FIFO: | ||
| 1476 | return true; | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | return rx_is_rw_register(dev, reg); | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | static const struct regmap_config rx_regmap_config = { | ||
| 1483 | .name = "rx_macro", | ||
| 1484 | .reg_bits = 16, | ||
| 1485 | .val_bits = 32, /* 8 but with 32 bit read/write */ | ||
| 1486 | .reg_stride = 4, | ||
| 1487 | .cache_type = REGCACHE_FLAT, | ||
| 1488 | .reg_defaults = rx_defaults, | ||
| 1489 | .num_reg_defaults = ARRAY_SIZE(rx_defaults), | ||
| 1490 | .max_register = RX_MAX_OFFSET, | ||
| 1491 | .writeable_reg = rx_is_writeable_register, | ||
| 1492 | .volatile_reg = rx_is_volatile_register, | ||
| 1493 | .readable_reg = rx_is_readable_register, | ||
| 1494 | }; | ||
| 1495 | |||
| 1496 | static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol, | ||
| 1497 | struct snd_ctl_elem_value *ucontrol) | ||
| 1498 | { | ||
| 1499 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 1500 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 1501 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 1502 | unsigned short look_ahead_dly_reg; | ||
| 1503 | unsigned int val; | ||
| 1504 | |||
| 1505 | val = ucontrol->value.enumerated.item[0]; | ||
| 1506 | |||
| 1507 | if (e->reg == CDC_RX_RX0_RX_PATH_CFG1) | ||
| 1508 | look_ahead_dly_reg = CDC_RX_RX0_RX_PATH_CFG0; | ||
| 1509 | else if (e->reg == CDC_RX_RX1_RX_PATH_CFG1) | ||
| 1510 | look_ahead_dly_reg = CDC_RX_RX1_RX_PATH_CFG0; | ||
| 1511 | |||
| 1512 | /* Set Look Ahead Delay */ | ||
| 1513 | if (val) | ||
| 1514 | snd_soc_component_update_bits(component, look_ahead_dly_reg, | ||
| 1515 | CDC_RX_DLY_ZN_EN_MASK, | ||
| 1516 | CDC_RX_DLY_ZN_ENABLE); | ||
| 1517 | else | ||
| 1518 | snd_soc_component_update_bits(component, look_ahead_dly_reg, | ||
| 1519 | CDC_RX_DLY_ZN_EN_MASK, 0); | ||
| 1520 | /* Set DEM INP Select */ | ||
| 1521 | return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | static const struct snd_kcontrol_new rx_int0_dem_inp_mux = | ||
| 1525 | SOC_DAPM_ENUM_EXT("rx_int0_dem_inp", rx_int0_dem_inp_enum, | ||
| 1526 | snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); | ||
| 1527 | static const struct snd_kcontrol_new rx_int1_dem_inp_mux = | ||
| 1528 | SOC_DAPM_ENUM_EXT("rx_int1_dem_inp", rx_int1_dem_inp_enum, | ||
| 1529 | snd_soc_dapm_get_enum_double, rx_macro_int_dem_inp_mux_put); | ||
| 1530 | |||
| 1531 | static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, | ||
| 1532 | int rate_reg_val, u32 sample_rate) | ||
| 1533 | { | ||
| 1534 | |||
| 1535 | u8 int_1_mix1_inp; | ||
| 1536 | u32 j, port; | ||
| 1537 | u16 int_mux_cfg0, int_mux_cfg1; | ||
| 1538 | u16 int_fs_reg; | ||
| 1539 | u8 inp0_sel, inp1_sel, inp2_sel; | ||
| 1540 | struct snd_soc_component *component = dai->component; | ||
| 1541 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 1542 | |||
| 1543 | for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { | ||
| 1544 | int_1_mix1_inp = port; | ||
| 1545 | int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0; | ||
| 1546 | /* | ||
| 1547 | * Loop through all interpolator MUX inputs and find out | ||
| 1548 | * to which interpolator input, the rx port | ||
| 1549 | * is connected | ||
| 1550 | */ | ||
| 1551 | for (j = 0; j < INTERP_MAX; j++) { | ||
| 1552 | int_mux_cfg1 = int_mux_cfg0 + 4; | ||
| 1553 | |||
| 1554 | inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, | ||
| 1555 | CDC_RX_INTX_1_MIX_INP0_SEL_MASK); | ||
| 1556 | inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, | ||
| 1557 | CDC_RX_INTX_1_MIX_INP1_SEL_MASK); | ||
| 1558 | inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, | ||
| 1559 | CDC_RX_INTX_1_MIX_INP2_SEL_MASK); | ||
| 1560 | |||
| 1561 | if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || | ||
| 1562 | (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || | ||
| 1563 | (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { | ||
| 1564 | int_fs_reg = CDC_RX_RXn_RX_PATH_CTL(j); | ||
| 1565 | /* sample_rate is in Hz */ | ||
| 1566 | snd_soc_component_update_bits(component, int_fs_reg, | ||
| 1567 | CDC_RX_PATH_PCM_RATE_MASK, | ||
| 1568 | rate_reg_val); | ||
| 1569 | } | ||
| 1570 | int_mux_cfg0 += 8; | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | return 0; | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, | ||
| 1578 | int rate_reg_val, u32 sample_rate) | ||
| 1579 | { | ||
| 1580 | |||
| 1581 | u8 int_2_inp; | ||
| 1582 | u32 j, port; | ||
| 1583 | u16 int_mux_cfg1, int_fs_reg; | ||
| 1584 | u8 int_mux_cfg1_val; | ||
| 1585 | struct snd_soc_component *component = dai->component; | ||
| 1586 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 1587 | |||
| 1588 | for_each_set_bit(port, &rx->active_ch_mask[dai->id], RX_MACRO_PORTS_MAX) { | ||
| 1589 | int_2_inp = port; | ||
| 1590 | |||
| 1591 | int_mux_cfg1 = CDC_RX_INP_MUX_RX_INT0_CFG1; | ||
| 1592 | for (j = 0; j < INTERP_MAX; j++) { | ||
| 1593 | int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, | ||
| 1594 | CDC_RX_INTX_2_SEL_MASK); | ||
| 1595 | |||
| 1596 | if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { | ||
| 1597 | int_fs_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); | ||
| 1598 | snd_soc_component_update_bits(component, int_fs_reg, | ||
| 1599 | CDC_RX_RXn_MIX_PCM_RATE_MASK, | ||
| 1600 | rate_reg_val); | ||
| 1601 | } | ||
| 1602 | int_mux_cfg1 += 8; | ||
| 1603 | } | ||
| 1604 | } | ||
| 1605 | return 0; | ||
| 1606 | } | ||
| 1607 | |||
| 1608 | static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai, | ||
| 1609 | u32 sample_rate) | ||
| 1610 | { | ||
| 1611 | int rate_val = 0; | ||
| 1612 | int i, ret; | ||
| 1613 | |||
| 1614 | for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) | ||
| 1615 | if (sample_rate == sr_val_tbl[i].sample_rate) | ||
| 1616 | rate_val = sr_val_tbl[i].rate_val; | ||
| 1617 | |||
| 1618 | ret = rx_macro_set_prim_interpolator_rate(dai, rate_val, sample_rate); | ||
| 1619 | if (ret) | ||
| 1620 | return ret; | ||
| 1621 | |||
| 1622 | ret = rx_macro_set_mix_interpolator_rate(dai, rate_val, sample_rate); | ||
| 1623 | if (ret) | ||
| 1624 | return ret; | ||
| 1625 | |||
| 1626 | return ret; | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | static int rx_macro_hw_params(struct snd_pcm_substream *substream, | ||
| 1630 | struct snd_pcm_hw_params *params, | ||
| 1631 | struct snd_soc_dai *dai) | ||
| 1632 | { | ||
| 1633 | struct snd_soc_component *component = dai->component; | ||
| 1634 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 1635 | int ret; | ||
| 1636 | |||
| 1637 | switch (substream->stream) { | ||
| 1638 | case SNDRV_PCM_STREAM_PLAYBACK: | ||
| 1639 | ret = rx_macro_set_interpolator_rate(dai, params_rate(params)); | ||
| 1640 | if (ret) { | ||
| 1641 | dev_err(component->dev, "%s: cannot set sample rate: %u\n", | ||
| 1642 | __func__, params_rate(params)); | ||
| 1643 | return ret; | ||
| 1644 | } | ||
| 1645 | rx->bit_width[dai->id] = params_width(params); | ||
| 1646 | break; | ||
| 1647 | default: | ||
| 1648 | break; | ||
| 1649 | } | ||
| 1650 | return 0; | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | static int rx_macro_get_channel_map(struct snd_soc_dai *dai, | ||
| 1654 | unsigned int *tx_num, unsigned int *tx_slot, | ||
| 1655 | unsigned int *rx_num, unsigned int *rx_slot) | ||
| 1656 | { | ||
| 1657 | struct snd_soc_component *component = dai->component; | ||
| 1658 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 1659 | u16 val, mask = 0, cnt = 0, temp; | ||
| 1660 | |||
| 1661 | switch (dai->id) { | ||
| 1662 | case RX_MACRO_AIF1_PB: | ||
| 1663 | case RX_MACRO_AIF2_PB: | ||
| 1664 | case RX_MACRO_AIF3_PB: | ||
| 1665 | case RX_MACRO_AIF4_PB: | ||
| 1666 | for_each_set_bit(temp, &rx->active_ch_mask[dai->id], | ||
| 1667 | RX_MACRO_PORTS_MAX) { | ||
| 1668 | mask |= (1 << temp); | ||
| 1669 | if (++cnt == RX_MACRO_MAX_DMA_CH_PER_PORT) | ||
| 1670 | break; | ||
| 1671 | } | ||
| 1672 | /* | ||
| 1673 | * CDC_DMA_RX_0 port drives RX0/RX1 -- ch_mask 0x1/0x2/0x3 | ||
| 1674 | * CDC_DMA_RX_1 port drives RX2/RX3 -- ch_mask 0x1/0x2/0x3 | ||
| 1675 | * CDC_DMA_RX_2 port drives RX4 -- ch_mask 0x1 | ||
| 1676 | * CDC_DMA_RX_3 port drives RX5 -- ch_mask 0x1 | ||
| 1677 | * AIFn can pair to any CDC_DMA_RX_n port. | ||
| 1678 | * In general, below convention is used:: | ||
| 1679 | * CDC_DMA_RX_0(AIF1)/CDC_DMA_RX_1(AIF2)/ | ||
| 1680 | * CDC_DMA_RX_2(AIF3)/CDC_DMA_RX_3(AIF4) | ||
| 1681 | */ | ||
| 1682 | if (mask & 0x0C) | ||
| 1683 | mask = mask >> 2; | ||
| 1684 | if ((mask & 0x10) || (mask & 0x20)) | ||
| 1685 | mask = 0x1; | ||
| 1686 | *rx_slot = mask; | ||
| 1687 | *rx_num = rx->active_ch_cnt[dai->id]; | ||
| 1688 | break; | ||
| 1689 | case RX_MACRO_AIF_ECHO: | ||
| 1690 | val = snd_soc_component_read(component, CDC_RX_INP_MUX_RX_MIX_CFG4); | ||
| 1691 | if (val & RX_MACRO_EC_MIX_TX0_MASK) { | ||
| 1692 | mask |= 0x1; | ||
| 1693 | cnt++; | ||
| 1694 | } | ||
| 1695 | if (val & RX_MACRO_EC_MIX_TX1_MASK) { | ||
| 1696 | mask |= 0x2; | ||
| 1697 | cnt++; | ||
| 1698 | } | ||
| 1699 | val = snd_soc_component_read(component, | ||
| 1700 | CDC_RX_INP_MUX_RX_MIX_CFG5); | ||
| 1701 | if (val & RX_MACRO_EC_MIX_TX2_MASK) { | ||
| 1702 | mask |= 0x4; | ||
| 1703 | cnt++; | ||
| 1704 | } | ||
| 1705 | *tx_slot = mask; | ||
| 1706 | *tx_num = cnt; | ||
| 1707 | break; | ||
| 1708 | default: | ||
| 1709 | dev_err(component->dev, "%s: Invalid AIF\n", __func__); | ||
| 1710 | break; | ||
| 1711 | } | ||
| 1712 | return 0; | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) | ||
| 1716 | { | ||
| 1717 | struct snd_soc_component *component = dai->component; | ||
| 1718 | uint16_t j, reg, mix_reg, dsm_reg; | ||
| 1719 | u16 int_mux_cfg0, int_mux_cfg1; | ||
| 1720 | u8 int_mux_cfg0_val, int_mux_cfg1_val; | ||
| 1721 | |||
| 1722 | switch (dai->id) { | ||
| 1723 | case RX_MACRO_AIF1_PB: | ||
| 1724 | case RX_MACRO_AIF2_PB: | ||
| 1725 | case RX_MACRO_AIF3_PB: | ||
| 1726 | case RX_MACRO_AIF4_PB: | ||
| 1727 | for (j = 0; j < INTERP_MAX; j++) { | ||
| 1728 | reg = CDC_RX_RXn_RX_PATH_CTL(j); | ||
| 1729 | mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(j); | ||
| 1730 | dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(j); | ||
| 1731 | |||
| 1732 | if (mute) { | ||
| 1733 | snd_soc_component_update_bits(component, reg, | ||
| 1734 | CDC_RX_PATH_PGA_MUTE_MASK, | ||
| 1735 | CDC_RX_PATH_PGA_MUTE_ENABLE); | ||
| 1736 | snd_soc_component_update_bits(component, mix_reg, | ||
| 1737 | CDC_RX_PATH_PGA_MUTE_MASK, | ||
| 1738 | CDC_RX_PATH_PGA_MUTE_ENABLE); | ||
| 1739 | } else { | ||
| 1740 | snd_soc_component_update_bits(component, reg, | ||
| 1741 | CDC_RX_PATH_PGA_MUTE_MASK, 0x0); | ||
| 1742 | snd_soc_component_update_bits(component, mix_reg, | ||
| 1743 | CDC_RX_PATH_PGA_MUTE_MASK, 0x0); | ||
| 1744 | } | ||
| 1745 | |||
| 1746 | if (j == INTERP_AUX) | ||
| 1747 | dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; | ||
| 1748 | |||
| 1749 | int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; | ||
| 1750 | int_mux_cfg1 = int_mux_cfg0 + 4; | ||
| 1751 | int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); | ||
| 1752 | int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); | ||
| 1753 | |||
| 1754 | if (snd_soc_component_read(component, dsm_reg) & 0x01) { | ||
| 1755 | if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0)) | ||
| 1756 | snd_soc_component_update_bits(component, reg, 0x20, 0x20); | ||
| 1757 | if (int_mux_cfg1_val & 0x0F) { | ||
| 1758 | snd_soc_component_update_bits(component, reg, 0x20, 0x20); | ||
| 1759 | snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20); | ||
| 1760 | } | ||
| 1761 | } | ||
| 1762 | } | ||
| 1763 | break; | ||
| 1764 | default: | ||
| 1765 | break; | ||
| 1766 | } | ||
| 1767 | return 0; | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | static struct snd_soc_dai_ops rx_macro_dai_ops = { | ||
| 1771 | .hw_params = rx_macro_hw_params, | ||
| 1772 | .get_channel_map = rx_macro_get_channel_map, | ||
| 1773 | .mute_stream = rx_macro_digital_mute, | ||
| 1774 | }; | ||
| 1775 | |||
| 1776 | static struct snd_soc_dai_driver rx_macro_dai[] = { | ||
| 1777 | { | ||
| 1778 | .name = "rx_macro_rx1", | ||
| 1779 | .id = RX_MACRO_AIF1_PB, | ||
| 1780 | .playback = { | ||
| 1781 | .stream_name = "RX_MACRO_AIF1 Playback", | ||
| 1782 | .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, | ||
| 1783 | .formats = RX_MACRO_FORMATS, | ||
| 1784 | .rate_max = 384000, | ||
| 1785 | .rate_min = 8000, | ||
| 1786 | .channels_min = 1, | ||
| 1787 | .channels_max = 2, | ||
| 1788 | }, | ||
| 1789 | .ops = &rx_macro_dai_ops, | ||
| 1790 | }, | ||
| 1791 | { | ||
| 1792 | .name = "rx_macro_rx2", | ||
| 1793 | .id = RX_MACRO_AIF2_PB, | ||
| 1794 | .playback = { | ||
| 1795 | .stream_name = "RX_MACRO_AIF2 Playback", | ||
| 1796 | .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, | ||
| 1797 | .formats = RX_MACRO_FORMATS, | ||
| 1798 | .rate_max = 384000, | ||
| 1799 | .rate_min = 8000, | ||
| 1800 | .channels_min = 1, | ||
| 1801 | .channels_max = 2, | ||
| 1802 | }, | ||
| 1803 | .ops = &rx_macro_dai_ops, | ||
| 1804 | }, | ||
| 1805 | { | ||
| 1806 | .name = "rx_macro_rx3", | ||
| 1807 | .id = RX_MACRO_AIF3_PB, | ||
| 1808 | .playback = { | ||
| 1809 | .stream_name = "RX_MACRO_AIF3 Playback", | ||
| 1810 | .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, | ||
| 1811 | .formats = RX_MACRO_FORMATS, | ||
| 1812 | .rate_max = 384000, | ||
| 1813 | .rate_min = 8000, | ||
| 1814 | .channels_min = 1, | ||
| 1815 | .channels_max = 2, | ||
| 1816 | }, | ||
| 1817 | .ops = &rx_macro_dai_ops, | ||
| 1818 | }, | ||
| 1819 | { | ||
| 1820 | .name = "rx_macro_rx4", | ||
| 1821 | .id = RX_MACRO_AIF4_PB, | ||
| 1822 | .playback = { | ||
| 1823 | .stream_name = "RX_MACRO_AIF4 Playback", | ||
| 1824 | .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES, | ||
| 1825 | .formats = RX_MACRO_FORMATS, | ||
| 1826 | .rate_max = 384000, | ||
| 1827 | .rate_min = 8000, | ||
| 1828 | .channels_min = 1, | ||
| 1829 | .channels_max = 2, | ||
| 1830 | }, | ||
| 1831 | .ops = &rx_macro_dai_ops, | ||
| 1832 | }, | ||
| 1833 | { | ||
| 1834 | .name = "rx_macro_echo", | ||
| 1835 | .id = RX_MACRO_AIF_ECHO, | ||
| 1836 | .capture = { | ||
| 1837 | .stream_name = "RX_AIF_ECHO Capture", | ||
| 1838 | .rates = RX_MACRO_ECHO_RATES, | ||
| 1839 | .formats = RX_MACRO_ECHO_FORMATS, | ||
| 1840 | .rate_max = 48000, | ||
| 1841 | .rate_min = 8000, | ||
| 1842 | .channels_min = 1, | ||
| 1843 | .channels_max = 3, | ||
| 1844 | }, | ||
| 1845 | .ops = &rx_macro_dai_ops, | ||
| 1846 | }, | ||
| 1847 | }; | ||
| 1848 | |||
| 1849 | static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable) | ||
| 1850 | { | ||
| 1851 | struct regmap *regmap = rx->regmap; | ||
| 1852 | |||
| 1853 | if (mclk_enable) { | ||
| 1854 | if (rx->rx_mclk_users == 0) { | ||
| 1855 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, | ||
| 1856 | CDC_RX_CLK_MCLK_EN_MASK | | ||
| 1857 | CDC_RX_CLK_MCLK2_EN_MASK, | ||
| 1858 | CDC_RX_CLK_MCLK_ENABLE | | ||
| 1859 | CDC_RX_CLK_MCLK2_ENABLE); | ||
| 1860 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 1861 | CDC_RX_FS_MCLK_CNT_CLR_MASK, 0x00); | ||
| 1862 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 1863 | CDC_RX_FS_MCLK_CNT_EN_MASK, | ||
| 1864 | CDC_RX_FS_MCLK_CNT_ENABLE); | ||
| 1865 | regcache_mark_dirty(regmap); | ||
| 1866 | regcache_sync(regmap); | ||
| 1867 | } | ||
| 1868 | rx->rx_mclk_users++; | ||
| 1869 | } else { | ||
| 1870 | if (rx->rx_mclk_users <= 0) { | ||
| 1871 | dev_err(rx->dev, "%s: clock already disabled\n", __func__); | ||
| 1872 | rx->rx_mclk_users = 0; | ||
| 1873 | return; | ||
| 1874 | } | ||
| 1875 | rx->rx_mclk_users--; | ||
| 1876 | if (rx->rx_mclk_users == 0) { | ||
| 1877 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 1878 | CDC_RX_FS_MCLK_CNT_EN_MASK, 0x0); | ||
| 1879 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 1880 | CDC_RX_FS_MCLK_CNT_CLR_MASK, | ||
| 1881 | CDC_RX_FS_MCLK_CNT_CLR); | ||
| 1882 | regmap_update_bits(regmap, CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, | ||
| 1883 | CDC_RX_CLK_MCLK_EN_MASK | | ||
| 1884 | CDC_RX_CLK_MCLK2_EN_MASK, 0x0); | ||
| 1885 | } | ||
| 1886 | } | ||
| 1887 | } | ||
| 1888 | |||
| 1889 | static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w, | ||
| 1890 | struct snd_kcontrol *kcontrol, int event) | ||
| 1891 | { | ||
| 1892 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 1893 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 1894 | int ret = 0; | ||
| 1895 | |||
| 1896 | switch (event) { | ||
| 1897 | case SND_SOC_DAPM_PRE_PMU: | ||
| 1898 | rx_macro_mclk_enable(rx, true); | ||
| 1899 | break; | ||
| 1900 | case SND_SOC_DAPM_POST_PMD: | ||
| 1901 | rx_macro_mclk_enable(rx, false); | ||
| 1902 | break; | ||
| 1903 | default: | ||
| 1904 | dev_err(component->dev, "%s: invalid DAPM event %d\n", __func__, event); | ||
| 1905 | ret = -EINVAL; | ||
| 1906 | } | ||
| 1907 | return ret; | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | static bool rx_macro_adie_lb(struct snd_soc_component *component, | ||
| 1911 | int interp_idx) | ||
| 1912 | { | ||
| 1913 | u16 int_mux_cfg0, int_mux_cfg1; | ||
| 1914 | u8 int_n_inp0, int_n_inp1, int_n_inp2; | ||
| 1915 | |||
| 1916 | int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; | ||
| 1917 | int_mux_cfg1 = int_mux_cfg0 + 4; | ||
| 1918 | |||
| 1919 | int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, | ||
| 1920 | CDC_RX_INTX_1_MIX_INP0_SEL_MASK); | ||
| 1921 | int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, | ||
| 1922 | CDC_RX_INTX_1_MIX_INP1_SEL_MASK); | ||
| 1923 | int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, | ||
| 1924 | CDC_RX_INTX_1_MIX_INP2_SEL_MASK); | ||
| 1925 | |||
| 1926 | if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || | ||
| 1927 | int_n_inp0 == INTn_1_INP_SEL_DEC1 || | ||
| 1928 | int_n_inp0 == INTn_1_INP_SEL_IIR0 || | ||
| 1929 | int_n_inp0 == INTn_1_INP_SEL_IIR1) | ||
| 1930 | return true; | ||
| 1931 | |||
| 1932 | if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || | ||
| 1933 | int_n_inp1 == INTn_1_INP_SEL_DEC1 || | ||
| 1934 | int_n_inp1 == INTn_1_INP_SEL_IIR0 || | ||
| 1935 | int_n_inp1 == INTn_1_INP_SEL_IIR1) | ||
| 1936 | return true; | ||
| 1937 | |||
| 1938 | if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || | ||
| 1939 | int_n_inp2 == INTn_1_INP_SEL_DEC1 || | ||
| 1940 | int_n_inp2 == INTn_1_INP_SEL_IIR0 || | ||
| 1941 | int_n_inp2 == INTn_1_INP_SEL_IIR1) | ||
| 1942 | return true; | ||
| 1943 | |||
| 1944 | return false; | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | static int rx_macro_enable_interp_clk(struct snd_soc_component *component, | ||
| 1948 | int event, int interp_idx); | ||
| 1949 | static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w, | ||
| 1950 | struct snd_kcontrol *kcontrol, | ||
| 1951 | int event) | ||
| 1952 | { | ||
| 1953 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 1954 | u16 gain_reg, reg; | ||
| 1955 | |||
| 1956 | reg = CDC_RX_RXn_RX_PATH_CTL(w->shift); | ||
| 1957 | gain_reg = CDC_RX_RXn_RX_VOL_CTL(w->shift); | ||
| 1958 | |||
| 1959 | switch (event) { | ||
| 1960 | case SND_SOC_DAPM_PRE_PMU: | ||
| 1961 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 1962 | if (rx_macro_adie_lb(component, w->shift)) | ||
| 1963 | snd_soc_component_update_bits(component, reg, | ||
| 1964 | CDC_RX_PATH_CLK_EN_MASK, | ||
| 1965 | CDC_RX_PATH_CLK_ENABLE); | ||
| 1966 | break; | ||
| 1967 | case SND_SOC_DAPM_POST_PMU: | ||
| 1968 | snd_soc_component_write(component, gain_reg, | ||
| 1969 | snd_soc_component_read(component, gain_reg)); | ||
| 1970 | break; | ||
| 1971 | case SND_SOC_DAPM_POST_PMD: | ||
| 1972 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 1973 | break; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | return 0; | ||
| 1977 | } | ||
| 1978 | |||
| 1979 | static int rx_macro_config_compander(struct snd_soc_component *component, | ||
| 1980 | struct rx_macro *rx, | ||
| 1981 | int comp, int event) | ||
| 1982 | { | ||
| 1983 | u8 pcm_rate, val; | ||
| 1984 | |||
| 1985 | /* AUX does not have compander */ | ||
| 1986 | if (comp == INTERP_AUX) | ||
| 1987 | return 0; | ||
| 1988 | |||
| 1989 | pcm_rate = snd_soc_component_read(component, CDC_RX_RXn_RX_PATH_CTL(comp)) & 0x0F; | ||
| 1990 | if (pcm_rate < 0x06) | ||
| 1991 | val = 0x03; | ||
| 1992 | else if (pcm_rate < 0x08) | ||
| 1993 | val = 0x01; | ||
| 1994 | else if (pcm_rate < 0x0B) | ||
| 1995 | val = 0x02; | ||
| 1996 | else | ||
| 1997 | val = 0x00; | ||
| 1998 | |||
| 1999 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
| 2000 | snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), | ||
| 2001 | CDC_RX_DC_COEFF_SEL_MASK, val); | ||
| 2002 | |||
| 2003 | if (SND_SOC_DAPM_EVENT_OFF(event)) | ||
| 2004 | snd_soc_component_update_bits(component, CDC_RX_RXn_RX_PATH_CFG3(comp), | ||
| 2005 | CDC_RX_DC_COEFF_SEL_MASK, 0x3); | ||
| 2006 | if (!rx->comp_enabled[comp]) | ||
| 2007 | return 0; | ||
| 2008 | |||
| 2009 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2010 | /* Enable Compander Clock */ | ||
| 2011 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2012 | CDC_RX_COMPANDERn_CLK_EN_MASK, 0x1); | ||
| 2013 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2014 | CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x1); | ||
| 2015 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2016 | CDC_RX_COMPANDERn_SOFT_RST_MASK, 0x0); | ||
| 2017 | snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), | ||
| 2018 | CDC_RX_RXn_COMP_EN_MASK, 0x1); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2022 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2023 | CDC_RX_COMPANDERn_HALT_MASK, 0x1); | ||
| 2024 | snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG0(comp), | ||
| 2025 | CDC_RX_RXn_COMP_EN_MASK, 0x0); | ||
| 2026 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2027 | CDC_RX_COMPANDERn_CLK_EN_MASK, 0x0); | ||
| 2028 | snd_soc_component_write_field(component, CDC_RX_COMPANDERn_CTL0(comp), | ||
| 2029 | CDC_RX_COMPANDERn_HALT_MASK, 0x0); | ||
| 2030 | } | ||
| 2031 | |||
| 2032 | return 0; | ||
| 2033 | } | ||
| 2034 | |||
| 2035 | static int rx_macro_load_compander_coeff(struct snd_soc_component *component, | ||
| 2036 | struct rx_macro *rx, | ||
| 2037 | int comp, int event) | ||
| 2038 | { | ||
| 2039 | u16 comp_coeff_lsb_reg, comp_coeff_msb_reg; | ||
| 2040 | int i; | ||
| 2041 | int hph_pwr_mode = HPH_LOHIFI; | ||
| 2042 | |||
| 2043 | if (!rx->comp_enabled[comp]) | ||
| 2044 | return 0; | ||
| 2045 | |||
| 2046 | if (comp == INTERP_HPHL) { | ||
| 2047 | comp_coeff_lsb_reg = CDC_RX_TOP_HPHL_COMP_WR_LSB; | ||
| 2048 | comp_coeff_msb_reg = CDC_RX_TOP_HPHL_COMP_WR_MSB; | ||
| 2049 | } else if (comp == INTERP_HPHR) { | ||
| 2050 | comp_coeff_lsb_reg = CDC_RX_TOP_HPHR_COMP_WR_LSB; | ||
| 2051 | comp_coeff_msb_reg = CDC_RX_TOP_HPHR_COMP_WR_MSB; | ||
| 2052 | } else { | ||
| 2053 | /* compander coefficients are loaded only for hph path */ | ||
| 2054 | return 0; | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | hph_pwr_mode = rx->hph_pwr_mode; | ||
| 2058 | |||
| 2059 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2060 | /* Load Compander Coeff */ | ||
| 2061 | for (i = 0; i < COMP_MAX_COEFF; i++) { | ||
| 2062 | snd_soc_component_write(component, comp_coeff_lsb_reg, | ||
| 2063 | comp_coeff_table[hph_pwr_mode][i].lsb); | ||
| 2064 | snd_soc_component_write(component, comp_coeff_msb_reg, | ||
| 2065 | comp_coeff_table[hph_pwr_mode][i].msb); | ||
| 2066 | } | ||
| 2067 | } | ||
| 2068 | |||
| 2069 | return 0; | ||
| 2070 | } | ||
| 2071 | |||
| 2072 | static void rx_macro_enable_softclip_clk(struct snd_soc_component *component, | ||
| 2073 | struct rx_macro *rx, bool enable) | ||
| 2074 | { | ||
| 2075 | if (enable) { | ||
| 2076 | if (rx->softclip_clk_users == 0) | ||
| 2077 | snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, | ||
| 2078 | CDC_RX_SOFTCLIP_CLK_EN_MASK, 1); | ||
| 2079 | rx->softclip_clk_users++; | ||
| 2080 | } else { | ||
| 2081 | rx->softclip_clk_users--; | ||
| 2082 | if (rx->softclip_clk_users == 0) | ||
| 2083 | snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_CRC, | ||
| 2084 | CDC_RX_SOFTCLIP_CLK_EN_MASK, 0); | ||
| 2085 | } | ||
| 2086 | } | ||
| 2087 | |||
| 2088 | static int rx_macro_config_softclip(struct snd_soc_component *component, | ||
| 2089 | struct rx_macro *rx, int event) | ||
| 2090 | { | ||
| 2091 | |||
| 2092 | if (!rx->is_softclip_on) | ||
| 2093 | return 0; | ||
| 2094 | |||
| 2095 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2096 | /* Enable Softclip clock */ | ||
| 2097 | rx_macro_enable_softclip_clk(component, rx, true); | ||
| 2098 | /* Enable Softclip control */ | ||
| 2099 | snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, | ||
| 2100 | CDC_RX_SOFTCLIP_EN_MASK, 0x01); | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2104 | snd_soc_component_write_field(component, CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, | ||
| 2105 | CDC_RX_SOFTCLIP_EN_MASK, 0x0); | ||
| 2106 | rx_macro_enable_softclip_clk(component, rx, false); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | return 0; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | static int rx_macro_config_aux_hpf(struct snd_soc_component *component, | ||
| 2113 | struct rx_macro *rx, int event) | ||
| 2114 | { | ||
| 2115 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2116 | /* Update Aux HPF control */ | ||
| 2117 | if (!rx->is_aux_hpf_on) | ||
| 2118 | snd_soc_component_update_bits(component, | ||
| 2119 | CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x00); | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2123 | /* Reset to default (HPF=ON) */ | ||
| 2124 | snd_soc_component_update_bits(component, | ||
| 2125 | CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x04); | ||
| 2126 | } | ||
| 2127 | |||
| 2128 | return 0; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | static inline void rx_macro_enable_clsh_block(struct rx_macro *rx, bool enable) | ||
| 2132 | { | ||
| 2133 | if ((enable && ++rx->clsh_users == 1) || (!enable && --rx->clsh_users == 0)) | ||
| 2134 | snd_soc_component_update_bits(rx->component, CDC_RX_CLSH_CRC, | ||
| 2135 | CDC_RX_CLSH_CLK_EN_MASK, enable); | ||
| 2136 | if (rx->clsh_users < 0) | ||
| 2137 | rx->clsh_users = 0; | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | static int rx_macro_config_classh(struct snd_soc_component *component, | ||
| 2141 | struct rx_macro *rx, | ||
| 2142 | int interp_n, int event) | ||
| 2143 | { | ||
| 2144 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2145 | rx_macro_enable_clsh_block(rx, false); | ||
| 2146 | return 0; | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | if (!SND_SOC_DAPM_EVENT_ON(event)) | ||
| 2150 | return 0; | ||
| 2151 | |||
| 2152 | rx_macro_enable_clsh_block(rx, true); | ||
| 2153 | if (interp_n == INTERP_HPHL || | ||
| 2154 | interp_n == INTERP_HPHR) { | ||
| 2155 | /* | ||
| 2156 | * These K1 values depend on the Headphone Impedance | ||
| 2157 | * For now it is assumed to be 16 ohm | ||
| 2158 | */ | ||
| 2159 | snd_soc_component_write(component, CDC_RX_CLSH_K1_LSB, 0xc0); | ||
| 2160 | snd_soc_component_write_field(component, CDC_RX_CLSH_K1_MSB, | ||
| 2161 | CDC_RX_CLSH_K1_MSB_COEFF_MASK, 0); | ||
| 2162 | } | ||
| 2163 | switch (interp_n) { | ||
| 2164 | case INTERP_HPHL: | ||
| 2165 | if (rx->is_ear_mode_on) | ||
| 2166 | snd_soc_component_update_bits(component, | ||
| 2167 | CDC_RX_CLSH_HPH_V_PA, | ||
| 2168 | CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); | ||
| 2169 | else | ||
| 2170 | snd_soc_component_update_bits(component, | ||
| 2171 | CDC_RX_CLSH_HPH_V_PA, | ||
| 2172 | CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); | ||
| 2173 | snd_soc_component_update_bits(component, | ||
| 2174 | CDC_RX_CLSH_DECAY_CTRL, | ||
| 2175 | CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); | ||
| 2176 | snd_soc_component_write_field(component, | ||
| 2177 | CDC_RX_RX0_RX_PATH_CFG0, | ||
| 2178 | CDC_RX_RXn_CLSH_EN_MASK, 0x1); | ||
| 2179 | break; | ||
| 2180 | case INTERP_HPHR: | ||
| 2181 | if (rx->is_ear_mode_on) | ||
| 2182 | snd_soc_component_update_bits(component, | ||
| 2183 | CDC_RX_CLSH_HPH_V_PA, | ||
| 2184 | CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x39); | ||
| 2185 | else | ||
| 2186 | snd_soc_component_update_bits(component, | ||
| 2187 | CDC_RX_CLSH_HPH_V_PA, | ||
| 2188 | CDC_RX_CLSH_HPH_V_PA_MIN_MASK, 0x1c); | ||
| 2189 | snd_soc_component_update_bits(component, | ||
| 2190 | CDC_RX_CLSH_DECAY_CTRL, | ||
| 2191 | CDC_RX_CLSH_DECAY_RATE_MASK, 0x0); | ||
| 2192 | snd_soc_component_update_bits(component, | ||
| 2193 | CDC_RX_RX1_RX_PATH_CFG0, | ||
| 2194 | CDC_RX_RXn_CLSH_EN_MASK, 0x1); | ||
| 2195 | break; | ||
| 2196 | case INTERP_AUX: | ||
| 2197 | snd_soc_component_update_bits(component, | ||
| 2198 | CDC_RX_RX2_RX_PATH_CFG0, | ||
| 2199 | CDC_RX_RX2_DLY_Z_EN_MASK, 1); | ||
| 2200 | snd_soc_component_write_field(component, | ||
| 2201 | CDC_RX_RX2_RX_PATH_CFG0, | ||
| 2202 | CDC_RX_RX2_CLSH_EN_MASK, 1); | ||
| 2203 | break; | ||
| 2204 | } | ||
| 2205 | |||
| 2206 | return 0; | ||
| 2207 | } | ||
| 2208 | |||
| 2209 | static void rx_macro_hd2_control(struct snd_soc_component *component, | ||
| 2210 | u16 interp_idx, int event) | ||
| 2211 | { | ||
| 2212 | u16 hd2_scale_reg, hd2_enable_reg; | ||
| 2213 | |||
| 2214 | switch (interp_idx) { | ||
| 2215 | case INTERP_HPHL: | ||
| 2216 | hd2_scale_reg = CDC_RX_RX0_RX_PATH_SEC3; | ||
| 2217 | hd2_enable_reg = CDC_RX_RX0_RX_PATH_CFG0; | ||
| 2218 | break; | ||
| 2219 | case INTERP_HPHR: | ||
| 2220 | hd2_scale_reg = CDC_RX_RX1_RX_PATH_SEC3; | ||
| 2221 | hd2_enable_reg = CDC_RX_RX1_RX_PATH_CFG0; | ||
| 2222 | break; | ||
| 2223 | } | ||
| 2224 | |||
| 2225 | if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2226 | snd_soc_component_update_bits(component, hd2_scale_reg, | ||
| 2227 | CDC_RX_RXn_HD2_ALPHA_MASK, 0x14); | ||
| 2228 | snd_soc_component_write_field(component, hd2_enable_reg, | ||
| 2229 | CDC_RX_RXn_HD2_EN_MASK, 1); | ||
| 2230 | } | ||
| 2231 | |||
| 2232 | if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2233 | snd_soc_component_write_field(component, hd2_enable_reg, | ||
| 2234 | CDC_RX_RXn_HD2_EN_MASK, 0); | ||
| 2235 | snd_soc_component_update_bits(component, hd2_scale_reg, | ||
| 2236 | CDC_RX_RXn_HD2_ALPHA_MASK, 0x0); | ||
| 2237 | } | ||
| 2238 | } | ||
| 2239 | |||
| 2240 | static int rx_macro_get_compander(struct snd_kcontrol *kcontrol, | ||
| 2241 | struct snd_ctl_elem_value *ucontrol) | ||
| 2242 | { | ||
| 2243 | struct snd_soc_component *component = | ||
| 2244 | snd_soc_kcontrol_component(kcontrol); | ||
| 2245 | int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; | ||
| 2246 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2247 | |||
| 2248 | ucontrol->value.integer.value[0] = rx->comp_enabled[comp]; | ||
| 2249 | return 0; | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | static int rx_macro_set_compander(struct snd_kcontrol *kcontrol, | ||
| 2253 | struct snd_ctl_elem_value *ucontrol) | ||
| 2254 | { | ||
| 2255 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2256 | int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; | ||
| 2257 | int value = ucontrol->value.integer.value[0]; | ||
| 2258 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2259 | |||
| 2260 | rx->comp_enabled[comp] = value; | ||
| 2261 | |||
| 2262 | return 0; | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | static int rx_macro_mux_get(struct snd_kcontrol *kcontrol, | ||
| 2266 | struct snd_ctl_elem_value *ucontrol) | ||
| 2267 | { | ||
| 2268 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 2269 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 2270 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2271 | |||
| 2272 | ucontrol->value.integer.value[0] = | ||
| 2273 | rx->rx_port_value[widget->shift]; | ||
| 2274 | return 0; | ||
| 2275 | } | ||
| 2276 | |||
| 2277 | static int rx_macro_mux_put(struct snd_kcontrol *kcontrol, | ||
| 2278 | struct snd_ctl_elem_value *ucontrol) | ||
| 2279 | { | ||
| 2280 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 2281 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 2282 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 2283 | struct snd_soc_dapm_update *update = NULL; | ||
| 2284 | u32 rx_port_value = ucontrol->value.integer.value[0]; | ||
| 2285 | u32 aif_rst; | ||
| 2286 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2287 | |||
| 2288 | aif_rst = rx->rx_port_value[widget->shift]; | ||
| 2289 | if (!rx_port_value) { | ||
| 2290 | if (aif_rst == 0) { | ||
| 2291 | dev_err(component->dev, "%s:AIF reset already\n", __func__); | ||
| 2292 | return 0; | ||
| 2293 | } | ||
| 2294 | if (aif_rst > RX_MACRO_AIF4_PB) { | ||
| 2295 | dev_err(component->dev, "%s: Invalid AIF reset\n", __func__); | ||
| 2296 | return 0; | ||
| 2297 | } | ||
| 2298 | } | ||
| 2299 | rx->rx_port_value[widget->shift] = rx_port_value; | ||
| 2300 | |||
| 2301 | switch (rx_port_value) { | ||
| 2302 | case 0: | ||
| 2303 | if (rx->active_ch_cnt[aif_rst]) { | ||
| 2304 | clear_bit(widget->shift, | ||
| 2305 | &rx->active_ch_mask[aif_rst]); | ||
| 2306 | rx->active_ch_cnt[aif_rst]--; | ||
| 2307 | } | ||
| 2308 | break; | ||
| 2309 | case 1: | ||
| 2310 | case 2: | ||
| 2311 | case 3: | ||
| 2312 | case 4: | ||
| 2313 | set_bit(widget->shift, | ||
| 2314 | &rx->active_ch_mask[rx_port_value]); | ||
| 2315 | rx->active_ch_cnt[rx_port_value]++; | ||
| 2316 | break; | ||
| 2317 | default: | ||
| 2318 | dev_err(component->dev, | ||
| 2319 | "%s:Invalid AIF_ID for RX_MACRO MUX %d\n", | ||
| 2320 | __func__, rx_port_value); | ||
| 2321 | goto err; | ||
| 2322 | } | ||
| 2323 | |||
| 2324 | snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, | ||
| 2325 | rx_port_value, e, update); | ||
| 2326 | return 0; | ||
| 2327 | err: | ||
| 2328 | return -EINVAL; | ||
| 2329 | } | ||
| 2330 | |||
| 2331 | static const struct snd_kcontrol_new rx_macro_rx0_mux = | ||
| 2332 | SOC_DAPM_ENUM_EXT("rx_macro_rx0", rx_macro_rx0_enum, | ||
| 2333 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2334 | static const struct snd_kcontrol_new rx_macro_rx1_mux = | ||
| 2335 | SOC_DAPM_ENUM_EXT("rx_macro_rx1", rx_macro_rx1_enum, | ||
| 2336 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2337 | static const struct snd_kcontrol_new rx_macro_rx2_mux = | ||
| 2338 | SOC_DAPM_ENUM_EXT("rx_macro_rx2", rx_macro_rx2_enum, | ||
| 2339 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2340 | static const struct snd_kcontrol_new rx_macro_rx3_mux = | ||
| 2341 | SOC_DAPM_ENUM_EXT("rx_macro_rx3", rx_macro_rx3_enum, | ||
| 2342 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2343 | static const struct snd_kcontrol_new rx_macro_rx4_mux = | ||
| 2344 | SOC_DAPM_ENUM_EXT("rx_macro_rx4", rx_macro_rx4_enum, | ||
| 2345 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2346 | static const struct snd_kcontrol_new rx_macro_rx5_mux = | ||
| 2347 | SOC_DAPM_ENUM_EXT("rx_macro_rx5", rx_macro_rx5_enum, | ||
| 2348 | rx_macro_mux_get, rx_macro_mux_put); | ||
| 2349 | |||
| 2350 | static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol, | ||
| 2351 | struct snd_ctl_elem_value *ucontrol) | ||
| 2352 | { | ||
| 2353 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2354 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2355 | |||
| 2356 | ucontrol->value.integer.value[0] = rx->is_ear_mode_on; | ||
| 2357 | return 0; | ||
| 2358 | } | ||
| 2359 | |||
| 2360 | static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol, | ||
| 2361 | struct snd_ctl_elem_value *ucontrol) | ||
| 2362 | { | ||
| 2363 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2364 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2365 | |||
| 2366 | rx->is_ear_mode_on = (!ucontrol->value.integer.value[0] ? false : true); | ||
| 2367 | return 0; | ||
| 2368 | } | ||
| 2369 | |||
| 2370 | static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol, | ||
| 2371 | struct snd_ctl_elem_value *ucontrol) | ||
| 2372 | { | ||
| 2373 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2374 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2375 | |||
| 2376 | ucontrol->value.integer.value[0] = rx->hph_hd2_mode; | ||
| 2377 | return 0; | ||
| 2378 | } | ||
| 2379 | |||
| 2380 | static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol, | ||
| 2381 | struct snd_ctl_elem_value *ucontrol) | ||
| 2382 | { | ||
| 2383 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2384 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2385 | |||
| 2386 | rx->hph_hd2_mode = ucontrol->value.integer.value[0]; | ||
| 2387 | return 0; | ||
| 2388 | } | ||
| 2389 | |||
| 2390 | static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol, | ||
| 2391 | struct snd_ctl_elem_value *ucontrol) | ||
| 2392 | { | ||
| 2393 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2394 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2395 | |||
| 2396 | ucontrol->value.integer.value[0] = rx->hph_pwr_mode; | ||
| 2397 | return 0; | ||
| 2398 | } | ||
| 2399 | |||
| 2400 | static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol, | ||
| 2401 | struct snd_ctl_elem_value *ucontrol) | ||
| 2402 | { | ||
| 2403 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2404 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2405 | |||
| 2406 | rx->hph_pwr_mode = ucontrol->value.integer.value[0]; | ||
| 2407 | return 0; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, | ||
| 2411 | struct snd_ctl_elem_value *ucontrol) | ||
| 2412 | { | ||
| 2413 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2414 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2415 | |||
| 2416 | ucontrol->value.integer.value[0] = rx->is_softclip_on; | ||
| 2417 | |||
| 2418 | return 0; | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, | ||
| 2422 | struct snd_ctl_elem_value *ucontrol) | ||
| 2423 | { | ||
| 2424 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2425 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2426 | |||
| 2427 | rx->is_softclip_on = ucontrol->value.integer.value[0]; | ||
| 2428 | |||
| 2429 | return 0; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | static int rx_macro_aux_hpf_mode_get(struct snd_kcontrol *kcontrol, | ||
| 2433 | struct snd_ctl_elem_value *ucontrol) | ||
| 2434 | { | ||
| 2435 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2436 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2437 | |||
| 2438 | ucontrol->value.integer.value[0] = rx->is_aux_hpf_on; | ||
| 2439 | |||
| 2440 | return 0; | ||
| 2441 | } | ||
| 2442 | |||
| 2443 | static int rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol, | ||
| 2444 | struct snd_ctl_elem_value *ucontrol) | ||
| 2445 | { | ||
| 2446 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 2447 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2448 | |||
| 2449 | rx->is_aux_hpf_on = ucontrol->value.integer.value[0]; | ||
| 2450 | |||
| 2451 | return 0; | ||
| 2452 | } | ||
| 2453 | |||
| 2454 | static int rx_macro_hphdelay_lutbypass(struct snd_soc_component *component, | ||
| 2455 | struct rx_macro *rx, | ||
| 2456 | u16 interp_idx, int event) | ||
| 2457 | { | ||
| 2458 | u16 hph_lut_bypass_reg; | ||
| 2459 | u16 hph_comp_ctrl7; | ||
| 2460 | |||
| 2461 | switch (interp_idx) { | ||
| 2462 | case INTERP_HPHL: | ||
| 2463 | hph_lut_bypass_reg = CDC_RX_TOP_HPHL_COMP_LUT; | ||
| 2464 | hph_comp_ctrl7 = CDC_RX_COMPANDER0_CTL7; | ||
| 2465 | break; | ||
| 2466 | case INTERP_HPHR: | ||
| 2467 | hph_lut_bypass_reg = CDC_RX_TOP_HPHR_COMP_LUT; | ||
| 2468 | hph_comp_ctrl7 = CDC_RX_COMPANDER1_CTL7; | ||
| 2469 | break; | ||
| 2470 | default: | ||
| 2471 | return -EINVAL; | ||
| 2472 | } | ||
| 2473 | |||
| 2474 | if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2475 | if (interp_idx == INTERP_HPHL) { | ||
| 2476 | if (rx->is_ear_mode_on) | ||
| 2477 | snd_soc_component_write_field(component, | ||
| 2478 | CDC_RX_RX0_RX_PATH_CFG1, | ||
| 2479 | CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x1); | ||
| 2480 | else | ||
| 2481 | snd_soc_component_write_field(component, | ||
| 2482 | hph_lut_bypass_reg, | ||
| 2483 | CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); | ||
| 2484 | } else { | ||
| 2485 | snd_soc_component_write_field(component, hph_lut_bypass_reg, | ||
| 2486 | CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 1); | ||
| 2487 | } | ||
| 2488 | if (rx->hph_pwr_mode) | ||
| 2489 | snd_soc_component_write_field(component, hph_comp_ctrl7, | ||
| 2490 | CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x0); | ||
| 2491 | } | ||
| 2492 | |||
| 2493 | if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2494 | snd_soc_component_write_field(component, | ||
| 2495 | CDC_RX_RX0_RX_PATH_CFG1, | ||
| 2496 | CDC_RX_RX0_HPH_L_EAR_SEL_MASK, 0x0); | ||
| 2497 | snd_soc_component_update_bits(component, hph_lut_bypass_reg, | ||
| 2498 | CDC_RX_TOP_HPH_LUT_BYPASS_MASK, 0); | ||
| 2499 | snd_soc_component_write_field(component, hph_comp_ctrl7, | ||
| 2500 | CDC_RX_COMPANDER1_HPH_LOW_PWR_MODE_MASK, 0x1); | ||
| 2501 | } | ||
| 2502 | |||
| 2503 | return 0; | ||
| 2504 | } | ||
| 2505 | |||
| 2506 | static int rx_macro_enable_interp_clk(struct snd_soc_component *component, | ||
| 2507 | int event, int interp_idx) | ||
| 2508 | { | ||
| 2509 | u16 main_reg, dsm_reg, rx_cfg2_reg; | ||
| 2510 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 2511 | |||
| 2512 | main_reg = CDC_RX_RXn_RX_PATH_CTL(interp_idx); | ||
| 2513 | dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(interp_idx); | ||
| 2514 | if (interp_idx == INTERP_AUX) | ||
| 2515 | dsm_reg = CDC_RX_RX2_RX_PATH_DSM_CTL; | ||
| 2516 | rx_cfg2_reg = CDC_RX_RXn_RX_PATH_CFG2(interp_idx); | ||
| 2517 | |||
| 2518 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 2519 | if (rx->main_clk_users[interp_idx] == 0) { | ||
| 2520 | /* Main path PGA mute enable */ | ||
| 2521 | snd_soc_component_write_field(component, main_reg, | ||
| 2522 | CDC_RX_PATH_PGA_MUTE_MASK, 0x1); | ||
| 2523 | snd_soc_component_write_field(component, dsm_reg, | ||
| 2524 | CDC_RX_RXn_DSM_CLK_EN_MASK, 0x1); | ||
| 2525 | snd_soc_component_update_bits(component, rx_cfg2_reg, | ||
| 2526 | CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x03); | ||
| 2527 | rx_macro_load_compander_coeff(component, rx, interp_idx, event); | ||
| 2528 | if (rx->hph_hd2_mode) | ||
| 2529 | rx_macro_hd2_control(component, interp_idx, event); | ||
| 2530 | rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); | ||
| 2531 | rx_macro_config_compander(component, rx, interp_idx, event); | ||
| 2532 | if (interp_idx == INTERP_AUX) { | ||
| 2533 | rx_macro_config_softclip(component, rx, event); | ||
| 2534 | rx_macro_config_aux_hpf(component, rx, event); | ||
| 2535 | } | ||
| 2536 | rx_macro_config_classh(component, rx, interp_idx, event); | ||
| 2537 | } | ||
| 2538 | rx->main_clk_users[interp_idx]++; | ||
| 2539 | } | ||
| 2540 | |||
| 2541 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
| 2542 | rx->main_clk_users[interp_idx]--; | ||
| 2543 | if (rx->main_clk_users[interp_idx] <= 0) { | ||
| 2544 | rx->main_clk_users[interp_idx] = 0; | ||
| 2545 | /* Main path PGA mute enable */ | ||
| 2546 | snd_soc_component_write_field(component, main_reg, | ||
| 2547 | CDC_RX_PATH_PGA_MUTE_MASK, 0x1); | ||
| 2548 | /* Clk Disable */ | ||
| 2549 | snd_soc_component_write_field(component, dsm_reg, | ||
| 2550 | CDC_RX_RXn_DSM_CLK_EN_MASK, 0); | ||
| 2551 | snd_soc_component_write_field(component, main_reg, | ||
| 2552 | CDC_RX_PATH_CLK_EN_MASK, 0); | ||
| 2553 | /* Reset enable and disable */ | ||
| 2554 | snd_soc_component_write_field(component, main_reg, | ||
| 2555 | CDC_RX_PATH_RESET_EN_MASK, 1); | ||
| 2556 | snd_soc_component_write_field(component, main_reg, | ||
| 2557 | CDC_RX_PATH_RESET_EN_MASK, 0); | ||
| 2558 | /* Reset rate to 48K*/ | ||
| 2559 | snd_soc_component_update_bits(component, main_reg, | ||
| 2560 | CDC_RX_PATH_PCM_RATE_MASK, | ||
| 2561 | 0x04); | ||
| 2562 | snd_soc_component_update_bits(component, rx_cfg2_reg, | ||
| 2563 | CDC_RX_RXn_HPF_CUT_FREQ_MASK, 0x00); | ||
| 2564 | rx_macro_config_classh(component, rx, interp_idx, event); | ||
| 2565 | rx_macro_config_compander(component, rx, interp_idx, event); | ||
| 2566 | if (interp_idx == INTERP_AUX) { | ||
| 2567 | rx_macro_config_softclip(component, rx, event); | ||
| 2568 | rx_macro_config_aux_hpf(component, rx, event); | ||
| 2569 | } | ||
| 2570 | rx_macro_hphdelay_lutbypass(component, rx, interp_idx, event); | ||
| 2571 | if (rx->hph_hd2_mode) | ||
| 2572 | rx_macro_hd2_control(component, interp_idx, event); | ||
| 2573 | } | ||
| 2574 | } | ||
| 2575 | |||
| 2576 | return rx->main_clk_users[interp_idx]; | ||
| 2577 | } | ||
| 2578 | |||
| 2579 | static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w, | ||
| 2580 | struct snd_kcontrol *kcontrol, int event) | ||
| 2581 | { | ||
| 2582 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 2583 | u16 gain_reg, mix_reg; | ||
| 2584 | |||
| 2585 | gain_reg = CDC_RX_RXn_RX_VOL_MIX_CTL(w->shift); | ||
| 2586 | mix_reg = CDC_RX_RXn_RX_PATH_MIX_CTL(w->shift); | ||
| 2587 | |||
| 2588 | switch (event) { | ||
| 2589 | case SND_SOC_DAPM_PRE_PMU: | ||
| 2590 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 2591 | break; | ||
| 2592 | case SND_SOC_DAPM_POST_PMU: | ||
| 2593 | snd_soc_component_write(component, gain_reg, | ||
| 2594 | snd_soc_component_read(component, gain_reg)); | ||
| 2595 | break; | ||
| 2596 | case SND_SOC_DAPM_POST_PMD: | ||
| 2597 | /* Clk Disable */ | ||
| 2598 | snd_soc_component_update_bits(component, mix_reg, | ||
| 2599 | CDC_RX_RXn_MIX_CLK_EN_MASK, 0x00); | ||
| 2600 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 2601 | /* Reset enable and disable */ | ||
| 2602 | snd_soc_component_update_bits(component, mix_reg, | ||
| 2603 | CDC_RX_RXn_MIX_RESET_MASK, | ||
| 2604 | CDC_RX_RXn_MIX_RESET); | ||
| 2605 | snd_soc_component_update_bits(component, mix_reg, | ||
| 2606 | CDC_RX_RXn_MIX_RESET_MASK, 0x00); | ||
| 2607 | break; | ||
| 2608 | } | ||
| 2609 | |||
| 2610 | return 0; | ||
| 2611 | } | ||
| 2612 | |||
| 2613 | static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w, | ||
| 2614 | struct snd_kcontrol *kcontrol, int event) | ||
| 2615 | { | ||
| 2616 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 2617 | |||
| 2618 | switch (event) { | ||
| 2619 | case SND_SOC_DAPM_PRE_PMU: | ||
| 2620 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 2621 | snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), | ||
| 2622 | CDC_RX_RXn_SIDETONE_EN_MASK, 1); | ||
| 2623 | snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CTL(w->shift), | ||
| 2624 | CDC_RX_PATH_CLK_EN_MASK, 1); | ||
| 2625 | break; | ||
| 2626 | case SND_SOC_DAPM_POST_PMD: | ||
| 2627 | snd_soc_component_write_field(component, CDC_RX_RXn_RX_PATH_CFG1(w->shift), | ||
| 2628 | CDC_RX_RXn_SIDETONE_EN_MASK, 0); | ||
| 2629 | rx_macro_enable_interp_clk(component, event, w->shift); | ||
| 2630 | break; | ||
| 2631 | default: | ||
| 2632 | break; | ||
| 2633 | }; | ||
| 2634 | return 0; | ||
| 2635 | } | ||
| 2636 | |||
| 2637 | static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w, | ||
| 2638 | struct snd_kcontrol *kcontrol, int event) | ||
| 2639 | { | ||
| 2640 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 2641 | |||
| 2642 | switch (event) { | ||
| 2643 | case SND_SOC_DAPM_POST_PMU: /* fall through */ | ||
| 2644 | case SND_SOC_DAPM_PRE_PMD: | ||
| 2645 | if (strnstr(w->name, "IIR0", sizeof("IIR0"))) { | ||
| 2646 | snd_soc_component_write(component, | ||
| 2647 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, | ||
| 2648 | snd_soc_component_read(component, | ||
| 2649 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)); | ||
| 2650 | snd_soc_component_write(component, | ||
| 2651 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, | ||
| 2652 | snd_soc_component_read(component, | ||
| 2653 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)); | ||
| 2654 | snd_soc_component_write(component, | ||
| 2655 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, | ||
| 2656 | snd_soc_component_read(component, | ||
| 2657 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)); | ||
| 2658 | snd_soc_component_write(component, | ||
| 2659 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, | ||
| 2660 | snd_soc_component_read(component, | ||
| 2661 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)); | ||
| 2662 | } else { | ||
| 2663 | snd_soc_component_write(component, | ||
| 2664 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, | ||
| 2665 | snd_soc_component_read(component, | ||
| 2666 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)); | ||
| 2667 | snd_soc_component_write(component, | ||
| 2668 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, | ||
| 2669 | snd_soc_component_read(component, | ||
| 2670 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)); | ||
| 2671 | snd_soc_component_write(component, | ||
| 2672 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, | ||
| 2673 | snd_soc_component_read(component, | ||
| 2674 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)); | ||
| 2675 | snd_soc_component_write(component, | ||
| 2676 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, | ||
| 2677 | snd_soc_component_read(component, | ||
| 2678 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)); | ||
| 2679 | } | ||
| 2680 | break; | ||
| 2681 | } | ||
| 2682 | return 0; | ||
| 2683 | } | ||
| 2684 | |||
| 2685 | static uint32_t get_iir_band_coeff(struct snd_soc_component *component, | ||
| 2686 | int iir_idx, int band_idx, int coeff_idx) | ||
| 2687 | { | ||
| 2688 | u32 value; | ||
| 2689 | int reg, b2_reg; | ||
| 2690 | |||
| 2691 | /* Address does not automatically update if reading */ | ||
| 2692 | reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; | ||
| 2693 | b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; | ||
| 2694 | |||
| 2695 | snd_soc_component_write(component, reg, | ||
| 2696 | ((band_idx * BAND_MAX + coeff_idx) * | ||
| 2697 | sizeof(uint32_t)) & 0x7F); | ||
| 2698 | |||
| 2699 | value = snd_soc_component_read(component, b2_reg); | ||
| 2700 | snd_soc_component_write(component, reg, | ||
| 2701 | ((band_idx * BAND_MAX + coeff_idx) | ||
| 2702 | * sizeof(uint32_t) + 1) & 0x7F); | ||
| 2703 | |||
| 2704 | value |= (snd_soc_component_read(component, b2_reg) << 8); | ||
| 2705 | snd_soc_component_write(component, reg, | ||
| 2706 | ((band_idx * BAND_MAX + coeff_idx) | ||
| 2707 | * sizeof(uint32_t) + 2) & 0x7F); | ||
| 2708 | |||
| 2709 | value |= (snd_soc_component_read(component, b2_reg) << 16); | ||
| 2710 | snd_soc_component_write(component, reg, | ||
| 2711 | ((band_idx * BAND_MAX + coeff_idx) | ||
| 2712 | * sizeof(uint32_t) + 3) & 0x7F); | ||
| 2713 | |||
| 2714 | /* Mask bits top 2 bits since they are reserved */ | ||
| 2715 | value |= (snd_soc_component_read(component, b2_reg) << 24); | ||
| 2716 | return value; | ||
| 2717 | } | ||
| 2718 | |||
| 2719 | static void set_iir_band_coeff(struct snd_soc_component *component, | ||
| 2720 | int iir_idx, int band_idx, uint32_t value) | ||
| 2721 | { | ||
| 2722 | int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx; | ||
| 2723 | |||
| 2724 | snd_soc_component_write(component, reg, (value & 0xFF)); | ||
| 2725 | snd_soc_component_write(component, reg, (value >> 8) & 0xFF); | ||
| 2726 | snd_soc_component_write(component, reg, (value >> 16) & 0xFF); | ||
| 2727 | /* Mask top 2 bits, 7-8 are reserved */ | ||
| 2728 | snd_soc_component_write(component, reg, (value >> 24) & 0x3F); | ||
| 2729 | } | ||
| 2730 | |||
| 2731 | static int rx_macro_put_iir_band_audio_mixer( | ||
| 2732 | struct snd_kcontrol *kcontrol, | ||
| 2733 | struct snd_ctl_elem_value *ucontrol) | ||
| 2734 | { | ||
| 2735 | struct snd_soc_component *component = | ||
| 2736 | snd_soc_kcontrol_component(kcontrol); | ||
| 2737 | struct wcd_iir_filter_ctl *ctl = | ||
| 2738 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | ||
| 2739 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
| 2740 | int iir_idx = ctl->iir_idx; | ||
| 2741 | int band_idx = ctl->band_idx; | ||
| 2742 | u32 coeff[BAND_MAX]; | ||
| 2743 | int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx; | ||
| 2744 | |||
| 2745 | memcpy(&coeff[0], ucontrol->value.bytes.data, params->max); | ||
| 2746 | |||
| 2747 | /* Mask top bit it is reserved */ | ||
| 2748 | /* Updates addr automatically for each B2 write */ | ||
| 2749 | snd_soc_component_write(component, reg, (band_idx * BAND_MAX * | ||
| 2750 | sizeof(uint32_t)) & 0x7F); | ||
| 2751 | |||
| 2752 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]); | ||
| 2753 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]); | ||
| 2754 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]); | ||
| 2755 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]); | ||
| 2756 | set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]); | ||
| 2757 | |||
| 2758 | return 0; | ||
| 2759 | } | ||
| 2760 | |||
| 2761 | static int rx_macro_get_iir_band_audio_mixer(struct snd_kcontrol *kcontrol, | ||
| 2762 | struct snd_ctl_elem_value *ucontrol) | ||
| 2763 | { | ||
| 2764 | struct snd_soc_component *component = | ||
| 2765 | snd_soc_kcontrol_component(kcontrol); | ||
| 2766 | struct wcd_iir_filter_ctl *ctl = | ||
| 2767 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | ||
| 2768 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
| 2769 | int iir_idx = ctl->iir_idx; | ||
| 2770 | int band_idx = ctl->band_idx; | ||
| 2771 | u32 coeff[BAND_MAX]; | ||
| 2772 | |||
| 2773 | coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0); | ||
| 2774 | coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1); | ||
| 2775 | coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2); | ||
| 2776 | coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3); | ||
| 2777 | coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4); | ||
| 2778 | |||
| 2779 | memcpy(ucontrol->value.bytes.data, &coeff[0], params->max); | ||
| 2780 | |||
| 2781 | return 0; | ||
| 2782 | } | ||
| 2783 | |||
| 2784 | static int rx_macro_iir_filter_info(struct snd_kcontrol *kcontrol, | ||
| 2785 | struct snd_ctl_elem_info *ucontrol) | ||
| 2786 | { | ||
| 2787 | struct wcd_iir_filter_ctl *ctl = | ||
| 2788 | (struct wcd_iir_filter_ctl *)kcontrol->private_value; | ||
| 2789 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
| 2790 | |||
| 2791 | ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
| 2792 | ucontrol->count = params->max; | ||
| 2793 | |||
| 2794 | return 0; | ||
| 2795 | } | ||
| 2796 | |||
| 2797 | static const struct snd_kcontrol_new rx_macro_snd_controls[] = { | ||
| 2798 | SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume", CDC_RX_RX0_RX_VOL_CTL, | ||
| 2799 | -84, 40, digital_gain), | ||
| 2800 | SOC_SINGLE_S8_TLV("RX_RX1 Digital Volume", CDC_RX_RX1_RX_VOL_CTL, | ||
| 2801 | -84, 40, digital_gain), | ||
| 2802 | SOC_SINGLE_S8_TLV("RX_RX2 Digital Volume", CDC_RX_RX2_RX_VOL_CTL, | ||
| 2803 | -84, 40, digital_gain), | ||
| 2804 | SOC_SINGLE_S8_TLV("RX_RX0 Mix Digital Volume", CDC_RX_RX0_RX_VOL_MIX_CTL, | ||
| 2805 | -84, 40, digital_gain), | ||
| 2806 | SOC_SINGLE_S8_TLV("RX_RX1 Mix Digital Volume", CDC_RX_RX1_RX_VOL_MIX_CTL, | ||
| 2807 | -84, 40, digital_gain), | ||
| 2808 | SOC_SINGLE_S8_TLV("RX_RX2 Mix Digital Volume", CDC_RX_RX2_RX_VOL_MIX_CTL, | ||
| 2809 | -84, 40, digital_gain), | ||
| 2810 | |||
| 2811 | SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0, | ||
| 2812 | rx_macro_get_compander, rx_macro_set_compander), | ||
| 2813 | SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0, | ||
| 2814 | rx_macro_get_compander, rx_macro_set_compander), | ||
| 2815 | |||
| 2816 | SOC_SINGLE_EXT("RX_EAR Mode Switch", SND_SOC_NOPM, 0, 1, 0, | ||
| 2817 | rx_macro_get_ear_mode, rx_macro_put_ear_mode), | ||
| 2818 | |||
| 2819 | SOC_SINGLE_EXT("RX_HPH HD2 Mode Switch", SND_SOC_NOPM, 0, 1, 0, | ||
| 2820 | rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode), | ||
| 2821 | |||
| 2822 | SOC_ENUM_EXT("RX_HPH PWR Mode", rx_macro_hph_pwr_mode_enum, | ||
| 2823 | rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode), | ||
| 2824 | |||
| 2825 | SOC_SINGLE_EXT("RX_Softclip Switch", SND_SOC_NOPM, 0, 1, 0, | ||
| 2826 | rx_macro_soft_clip_enable_get, | ||
| 2827 | rx_macro_soft_clip_enable_put), | ||
| 2828 | SOC_SINGLE_EXT("AUX_HPF Switch", SND_SOC_NOPM, 0, 1, 0, | ||
| 2829 | rx_macro_aux_hpf_mode_get, | ||
| 2830 | rx_macro_aux_hpf_mode_put), | ||
| 2831 | |||
| 2832 | SOC_SINGLE_S8_TLV("IIR0 INP0 Volume", | ||
| 2833 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40, | ||
| 2834 | digital_gain), | ||
| 2835 | SOC_SINGLE_S8_TLV("IIR0 INP1 Volume", | ||
| 2836 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40, | ||
| 2837 | digital_gain), | ||
| 2838 | SOC_SINGLE_S8_TLV("IIR0 INP2 Volume", | ||
| 2839 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40, | ||
| 2840 | digital_gain), | ||
| 2841 | SOC_SINGLE_S8_TLV("IIR0 INP3 Volume", | ||
| 2842 | CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40, | ||
| 2843 | digital_gain), | ||
| 2844 | SOC_SINGLE_S8_TLV("IIR1 INP0 Volume", | ||
| 2845 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40, | ||
| 2846 | digital_gain), | ||
| 2847 | SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", | ||
| 2848 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40, | ||
| 2849 | digital_gain), | ||
| 2850 | SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", | ||
| 2851 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40, | ||
| 2852 | digital_gain), | ||
| 2853 | SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", | ||
| 2854 | CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40, | ||
| 2855 | digital_gain), | ||
| 2856 | |||
| 2857 | SOC_SINGLE("IIR1 Band1 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, | ||
| 2858 | 0, 1, 0), | ||
| 2859 | SOC_SINGLE("IIR1 Band2 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, | ||
| 2860 | 1, 1, 0), | ||
| 2861 | SOC_SINGLE("IIR1 Band3 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, | ||
| 2862 | 2, 1, 0), | ||
| 2863 | SOC_SINGLE("IIR1 Band4 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, | ||
| 2864 | 3, 1, 0), | ||
| 2865 | SOC_SINGLE("IIR1 Band5 Switch", CDC_RX_SIDETONE_IIR0_IIR_CTL, | ||
| 2866 | 4, 1, 0), | ||
| 2867 | SOC_SINGLE("IIR2 Band1 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, | ||
| 2868 | 0, 1, 0), | ||
| 2869 | SOC_SINGLE("IIR2 Band2 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, | ||
| 2870 | 1, 1, 0), | ||
| 2871 | SOC_SINGLE("IIR2 Band3 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, | ||
| 2872 | 2, 1, 0), | ||
| 2873 | SOC_SINGLE("IIR2 Band4 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, | ||
| 2874 | 3, 1, 0), | ||
| 2875 | SOC_SINGLE("IIR2 Band5 Switch", CDC_RX_SIDETONE_IIR1_IIR_CTL, | ||
| 2876 | 4, 1, 0), | ||
| 2877 | |||
| 2878 | RX_MACRO_IIR_FILTER_CTL("IIR0 Band1", IIR0, BAND1), | ||
| 2879 | RX_MACRO_IIR_FILTER_CTL("IIR0 Band2", IIR0, BAND2), | ||
| 2880 | RX_MACRO_IIR_FILTER_CTL("IIR0 Band3", IIR0, BAND3), | ||
| 2881 | RX_MACRO_IIR_FILTER_CTL("IIR0 Band4", IIR0, BAND4), | ||
| 2882 | RX_MACRO_IIR_FILTER_CTL("IIR0 Band5", IIR0, BAND5), | ||
| 2883 | |||
| 2884 | RX_MACRO_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1), | ||
| 2885 | RX_MACRO_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2), | ||
| 2886 | RX_MACRO_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3), | ||
| 2887 | RX_MACRO_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4), | ||
| 2888 | RX_MACRO_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5), | ||
| 2889 | |||
| 2890 | }; | ||
| 2891 | |||
| 2892 | static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w, | ||
| 2893 | struct snd_kcontrol *kcontrol, | ||
| 2894 | int event) | ||
| 2895 | { | ||
| 2896 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 2897 | u16 val, ec_hq_reg; | ||
| 2898 | int ec_tx; | ||
| 2899 | |||
| 2900 | val = snd_soc_component_read(component, | ||
| 2901 | CDC_RX_INP_MUX_RX_MIX_CFG4); | ||
| 2902 | if (!(strcmp(w->name, "RX MIX TX0 MUX"))) | ||
| 2903 | ec_tx = ((val & 0xf0) >> 0x4) - 1; | ||
| 2904 | else if (!(strcmp(w->name, "RX MIX TX1 MUX"))) | ||
| 2905 | ec_tx = (val & 0x0f) - 1; | ||
| 2906 | |||
| 2907 | val = snd_soc_component_read(component, | ||
| 2908 | CDC_RX_INP_MUX_RX_MIX_CFG5); | ||
| 2909 | if (!(strcmp(w->name, "RX MIX TX2 MUX"))) | ||
| 2910 | ec_tx = (val & 0x0f) - 1; | ||
| 2911 | |||
| 2912 | if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) { | ||
| 2913 | dev_err(component->dev, "%s: EC mix control not set correctly\n", | ||
| 2914 | __func__); | ||
| 2915 | return -EINVAL; | ||
| 2916 | } | ||
| 2917 | ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL + | ||
| 2918 | 0x40 * ec_tx; | ||
| 2919 | snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01); | ||
| 2920 | ec_hq_reg = CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 + | ||
| 2921 | 0x40 * ec_tx; | ||
| 2922 | /* default set to 48k */ | ||
| 2923 | snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08); | ||
| 2924 | |||
| 2925 | return 0; | ||
| 2926 | } | ||
| 2927 | |||
| 2928 | static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = { | ||
| 2929 | SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0, | ||
| 2930 | SND_SOC_NOPM, 0, 0), | ||
| 2931 | |||
| 2932 | SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0, | ||
| 2933 | SND_SOC_NOPM, 0, 0), | ||
| 2934 | |||
| 2935 | SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0, | ||
| 2936 | SND_SOC_NOPM, 0, 0), | ||
| 2937 | |||
| 2938 | SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0, | ||
| 2939 | SND_SOC_NOPM, 0, 0), | ||
| 2940 | |||
| 2941 | SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0, | ||
| 2942 | SND_SOC_NOPM, 0, 0), | ||
| 2943 | |||
| 2944 | SND_SOC_DAPM_MUX("RX_MACRO RX0 MUX", SND_SOC_NOPM, RX_MACRO_RX0, 0, | ||
| 2945 | &rx_macro_rx0_mux), | ||
| 2946 | SND_SOC_DAPM_MUX("RX_MACRO RX1 MUX", SND_SOC_NOPM, RX_MACRO_RX1, 0, | ||
| 2947 | &rx_macro_rx1_mux), | ||
| 2948 | SND_SOC_DAPM_MUX("RX_MACRO RX2 MUX", SND_SOC_NOPM, RX_MACRO_RX2, 0, | ||
| 2949 | &rx_macro_rx2_mux), | ||
| 2950 | SND_SOC_DAPM_MUX("RX_MACRO RX3 MUX", SND_SOC_NOPM, RX_MACRO_RX3, 0, | ||
| 2951 | &rx_macro_rx3_mux), | ||
| 2952 | SND_SOC_DAPM_MUX("RX_MACRO RX4 MUX", SND_SOC_NOPM, RX_MACRO_RX4, 0, | ||
| 2953 | &rx_macro_rx4_mux), | ||
| 2954 | SND_SOC_DAPM_MUX("RX_MACRO RX5 MUX", SND_SOC_NOPM, RX_MACRO_RX5, 0, | ||
| 2955 | &rx_macro_rx5_mux), | ||
| 2956 | |||
| 2957 | SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2958 | SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2959 | SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2960 | SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2961 | SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2962 | SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 2963 | |||
| 2964 | SND_SOC_DAPM_MUX("IIR0 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp0_mux), | ||
| 2965 | SND_SOC_DAPM_MUX("IIR0 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp1_mux), | ||
| 2966 | SND_SOC_DAPM_MUX("IIR0 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp2_mux), | ||
| 2967 | SND_SOC_DAPM_MUX("IIR0 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir0_inp3_mux), | ||
| 2968 | SND_SOC_DAPM_MUX("IIR1 INP0 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp0_mux), | ||
| 2969 | SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux), | ||
| 2970 | SND_SOC_DAPM_MUX("IIR1 INP2 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp2_mux), | ||
| 2971 | SND_SOC_DAPM_MUX("IIR1 INP3 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp3_mux), | ||
| 2972 | |||
| 2973 | SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM, | ||
| 2974 | RX_MACRO_EC0_MUX, 0, | ||
| 2975 | &rx_mix_tx0_mux, rx_macro_enable_echo, | ||
| 2976 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 2977 | SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM, | ||
| 2978 | RX_MACRO_EC1_MUX, 0, | ||
| 2979 | &rx_mix_tx1_mux, rx_macro_enable_echo, | ||
| 2980 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 2981 | SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM, | ||
| 2982 | RX_MACRO_EC2_MUX, 0, | ||
| 2983 | &rx_mix_tx2_mux, rx_macro_enable_echo, | ||
| 2984 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 2985 | |||
| 2986 | SND_SOC_DAPM_MIXER_E("IIR0", CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, | ||
| 2987 | 4, 0, NULL, 0, rx_macro_set_iir_gain, | ||
| 2988 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
| 2989 | SND_SOC_DAPM_MIXER_E("IIR1", CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, | ||
| 2990 | 4, 0, NULL, 0, rx_macro_set_iir_gain, | ||
| 2991 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
| 2992 | SND_SOC_DAPM_MIXER("SRC0", CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, | ||
| 2993 | 4, 0, NULL, 0), | ||
| 2994 | SND_SOC_DAPM_MIXER("SRC1", CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, | ||
| 2995 | 4, 0, NULL, 0), | ||
| 2996 | |||
| 2997 | SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, | ||
| 2998 | &rx_int0_dem_inp_mux), | ||
| 2999 | SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, | ||
| 3000 | &rx_int1_dem_inp_mux), | ||
| 3001 | |||
| 3002 | SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0, | ||
| 3003 | &rx_int0_2_mux, rx_macro_enable_mix_path, | ||
| 3004 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3005 | SND_SOC_DAPM_POST_PMD), | ||
| 3006 | SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0, | ||
| 3007 | &rx_int1_2_mux, rx_macro_enable_mix_path, | ||
| 3008 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3009 | SND_SOC_DAPM_POST_PMD), | ||
| 3010 | SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0, | ||
| 3011 | &rx_int2_2_mux, rx_macro_enable_mix_path, | ||
| 3012 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3013 | SND_SOC_DAPM_POST_PMD), | ||
| 3014 | |||
| 3015 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp0_mux), | ||
| 3016 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp1_mux), | ||
| 3017 | SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int0_1_mix_inp2_mux), | ||
| 3018 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp0_mux), | ||
| 3019 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp1_mux), | ||
| 3020 | SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int1_1_mix_inp2_mux), | ||
| 3021 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp0_mux), | ||
| 3022 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp1_mux), | ||
| 3023 | SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, &rx_int2_1_mix_inp2_mux), | ||
| 3024 | |||
| 3025 | SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0, | ||
| 3026 | &rx_int0_1_interp_mux, rx_macro_enable_main_path, | ||
| 3027 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3028 | SND_SOC_DAPM_POST_PMD), | ||
| 3029 | SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0, | ||
| 3030 | &rx_int1_1_interp_mux, rx_macro_enable_main_path, | ||
| 3031 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3032 | SND_SOC_DAPM_POST_PMD), | ||
| 3033 | SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0, | ||
| 3034 | &rx_int2_1_interp_mux, rx_macro_enable_main_path, | ||
| 3035 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 3036 | SND_SOC_DAPM_POST_PMD), | ||
| 3037 | |||
| 3038 | SND_SOC_DAPM_MUX("RX INT0_2 INTERP", SND_SOC_NOPM, 0, 0, | ||
| 3039 | &rx_int0_2_interp_mux), | ||
| 3040 | SND_SOC_DAPM_MUX("RX INT1_2 INTERP", SND_SOC_NOPM, 0, 0, | ||
| 3041 | &rx_int1_2_interp_mux), | ||
| 3042 | SND_SOC_DAPM_MUX("RX INT2_2 INTERP", SND_SOC_NOPM, 0, 0, | ||
| 3043 | &rx_int2_2_interp_mux), | ||
| 3044 | |||
| 3045 | SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3046 | SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3047 | SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3048 | SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3049 | SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3050 | SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3051 | |||
| 3052 | SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, | ||
| 3053 | 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk, | ||
| 3054 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 3055 | SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, | ||
| 3056 | 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk, | ||
| 3057 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 3058 | SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX, | ||
| 3059 | 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk, | ||
| 3060 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 3061 | |||
| 3062 | SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3063 | SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3064 | SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 3065 | |||
| 3066 | SND_SOC_DAPM_OUTPUT("HPHL_OUT"), | ||
| 3067 | SND_SOC_DAPM_OUTPUT("HPHR_OUT"), | ||
| 3068 | SND_SOC_DAPM_OUTPUT("AUX_OUT"), | ||
| 3069 | |||
| 3070 | SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"), | ||
| 3071 | SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"), | ||
| 3072 | SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"), | ||
| 3073 | SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"), | ||
| 3074 | |||
| 3075 | SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0, | ||
| 3076 | rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 3077 | }; | ||
| 3078 | |||
| 3079 | static const struct snd_soc_dapm_route rx_audio_map[] = { | ||
| 3080 | {"RX AIF1 PB", NULL, "RX_MCLK"}, | ||
| 3081 | {"RX AIF2 PB", NULL, "RX_MCLK"}, | ||
| 3082 | {"RX AIF3 PB", NULL, "RX_MCLK"}, | ||
| 3083 | {"RX AIF4 PB", NULL, "RX_MCLK"}, | ||
| 3084 | |||
| 3085 | {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3086 | {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3087 | {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3088 | {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3089 | {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3090 | {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"}, | ||
| 3091 | |||
| 3092 | {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3093 | {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3094 | {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3095 | {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3096 | {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3097 | {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"}, | ||
| 3098 | |||
| 3099 | {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3100 | {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3101 | {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3102 | {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3103 | {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3104 | {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"}, | ||
| 3105 | |||
| 3106 | {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3107 | {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3108 | {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3109 | {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3110 | {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3111 | {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"}, | ||
| 3112 | |||
| 3113 | {"RX_RX0", NULL, "RX_MACRO RX0 MUX"}, | ||
| 3114 | {"RX_RX1", NULL, "RX_MACRO RX1 MUX"}, | ||
| 3115 | {"RX_RX2", NULL, "RX_MACRO RX2 MUX"}, | ||
| 3116 | {"RX_RX3", NULL, "RX_MACRO RX3 MUX"}, | ||
| 3117 | {"RX_RX4", NULL, "RX_MACRO RX4 MUX"}, | ||
| 3118 | {"RX_RX5", NULL, "RX_MACRO RX5 MUX"}, | ||
| 3119 | |||
| 3120 | {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"}, | ||
| 3121 | {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"}, | ||
| 3122 | {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"}, | ||
| 3123 | {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"}, | ||
| 3124 | {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"}, | ||
| 3125 | {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"}, | ||
| 3126 | {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"}, | ||
| 3127 | {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"}, | ||
| 3128 | {"RX INT0_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3129 | {"RX INT0_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3130 | {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"}, | ||
| 3131 | {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"}, | ||
| 3132 | {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"}, | ||
| 3133 | {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"}, | ||
| 3134 | {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"}, | ||
| 3135 | {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"}, | ||
| 3136 | {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"}, | ||
| 3137 | {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"}, | ||
| 3138 | {"RX INT0_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3139 | {"RX INT0_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3140 | {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"}, | ||
| 3141 | {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"}, | ||
| 3142 | {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"}, | ||
| 3143 | {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"}, | ||
| 3144 | {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"}, | ||
| 3145 | {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"}, | ||
| 3146 | {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"}, | ||
| 3147 | {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"}, | ||
| 3148 | {"RX INT0_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3149 | {"RX INT0_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3150 | |||
| 3151 | {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"}, | ||
| 3152 | {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"}, | ||
| 3153 | {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"}, | ||
| 3154 | {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"}, | ||
| 3155 | {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"}, | ||
| 3156 | {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"}, | ||
| 3157 | {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"}, | ||
| 3158 | {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"}, | ||
| 3159 | {"RX INT1_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3160 | {"RX INT1_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3161 | {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"}, | ||
| 3162 | {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"}, | ||
| 3163 | {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"}, | ||
| 3164 | {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"}, | ||
| 3165 | {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"}, | ||
| 3166 | {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"}, | ||
| 3167 | {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"}, | ||
| 3168 | {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"}, | ||
| 3169 | {"RX INT1_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3170 | {"RX INT1_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3171 | {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"}, | ||
| 3172 | {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"}, | ||
| 3173 | {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"}, | ||
| 3174 | {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"}, | ||
| 3175 | {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"}, | ||
| 3176 | {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"}, | ||
| 3177 | {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"}, | ||
| 3178 | {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"}, | ||
| 3179 | {"RX INT1_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3180 | {"RX INT1_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3181 | |||
| 3182 | {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"}, | ||
| 3183 | {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"}, | ||
| 3184 | {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"}, | ||
| 3185 | {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"}, | ||
| 3186 | {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"}, | ||
| 3187 | {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"}, | ||
| 3188 | {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"}, | ||
| 3189 | {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"}, | ||
| 3190 | {"RX INT2_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3191 | {"RX INT2_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3192 | {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"}, | ||
| 3193 | {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"}, | ||
| 3194 | {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"}, | ||
| 3195 | {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"}, | ||
| 3196 | {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"}, | ||
| 3197 | {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"}, | ||
| 3198 | {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"}, | ||
| 3199 | {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"}, | ||
| 3200 | {"RX INT2_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3201 | {"RX INT2_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3202 | {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"}, | ||
| 3203 | {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"}, | ||
| 3204 | {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"}, | ||
| 3205 | {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"}, | ||
| 3206 | {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"}, | ||
| 3207 | {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"}, | ||
| 3208 | {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"}, | ||
| 3209 | {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"}, | ||
| 3210 | {"RX INT2_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3211 | {"RX INT2_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3212 | |||
| 3213 | {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"}, | ||
| 3214 | {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"}, | ||
| 3215 | {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"}, | ||
| 3216 | {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"}, | ||
| 3217 | {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"}, | ||
| 3218 | {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"}, | ||
| 3219 | {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"}, | ||
| 3220 | {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"}, | ||
| 3221 | {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"}, | ||
| 3222 | |||
| 3223 | {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, | ||
| 3224 | {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, | ||
| 3225 | {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, | ||
| 3226 | {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, | ||
| 3227 | {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, | ||
| 3228 | {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, | ||
| 3229 | {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"}, | ||
| 3230 | {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"}, | ||
| 3231 | {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"}, | ||
| 3232 | {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"}, | ||
| 3233 | {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"}, | ||
| 3234 | {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"}, | ||
| 3235 | {"RX AIF_ECHO", NULL, "RX_MCLK"}, | ||
| 3236 | |||
| 3237 | /* Mixing path INT0 */ | ||
| 3238 | {"RX INT0_2 MUX", "RX0", "RX_RX0"}, | ||
| 3239 | {"RX INT0_2 MUX", "RX1", "RX_RX1"}, | ||
| 3240 | {"RX INT0_2 MUX", "RX2", "RX_RX2"}, | ||
| 3241 | {"RX INT0_2 MUX", "RX3", "RX_RX3"}, | ||
| 3242 | {"RX INT0_2 MUX", "RX4", "RX_RX4"}, | ||
| 3243 | {"RX INT0_2 MUX", "RX5", "RX_RX5"}, | ||
| 3244 | {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"}, | ||
| 3245 | {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"}, | ||
| 3246 | |||
| 3247 | /* Mixing path INT1 */ | ||
| 3248 | {"RX INT1_2 MUX", "RX0", "RX_RX0"}, | ||
| 3249 | {"RX INT1_2 MUX", "RX1", "RX_RX1"}, | ||
| 3250 | {"RX INT1_2 MUX", "RX2", "RX_RX2"}, | ||
| 3251 | {"RX INT1_2 MUX", "RX3", "RX_RX3"}, | ||
| 3252 | {"RX INT1_2 MUX", "RX4", "RX_RX4"}, | ||
| 3253 | {"RX INT1_2 MUX", "RX5", "RX_RX5"}, | ||
| 3254 | {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"}, | ||
| 3255 | {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"}, | ||
| 3256 | |||
| 3257 | /* Mixing path INT2 */ | ||
| 3258 | {"RX INT2_2 MUX", "RX0", "RX_RX0"}, | ||
| 3259 | {"RX INT2_2 MUX", "RX1", "RX_RX1"}, | ||
| 3260 | {"RX INT2_2 MUX", "RX2", "RX_RX2"}, | ||
| 3261 | {"RX INT2_2 MUX", "RX3", "RX_RX3"}, | ||
| 3262 | {"RX INT2_2 MUX", "RX4", "RX_RX4"}, | ||
| 3263 | {"RX INT2_2 MUX", "RX5", "RX_RX5"}, | ||
| 3264 | {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"}, | ||
| 3265 | {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"}, | ||
| 3266 | |||
| 3267 | {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"}, | ||
| 3268 | {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"}, | ||
| 3269 | {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"}, | ||
| 3270 | {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"}, | ||
| 3271 | {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"}, | ||
| 3272 | {"HPHL_OUT", NULL, "RX INT0 DEM MUX"}, | ||
| 3273 | {"HPHL_OUT", NULL, "RX_MCLK"}, | ||
| 3274 | |||
| 3275 | {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"}, | ||
| 3276 | {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"}, | ||
| 3277 | {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"}, | ||
| 3278 | {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"}, | ||
| 3279 | {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"}, | ||
| 3280 | {"HPHR_OUT", NULL, "RX INT1 DEM MUX"}, | ||
| 3281 | {"HPHR_OUT", NULL, "RX_MCLK"}, | ||
| 3282 | |||
| 3283 | {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"}, | ||
| 3284 | |||
| 3285 | {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"}, | ||
| 3286 | {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"}, | ||
| 3287 | {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"}, | ||
| 3288 | {"AUX_OUT", NULL, "RX INT2 MIX2"}, | ||
| 3289 | {"AUX_OUT", NULL, "RX_MCLK"}, | ||
| 3290 | |||
| 3291 | {"IIR0", NULL, "RX_MCLK"}, | ||
| 3292 | {"IIR0", NULL, "IIR0 INP0 MUX"}, | ||
| 3293 | {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3294 | {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3295 | {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3296 | {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3297 | {"IIR0 INP0 MUX", "RX0", "RX_RX0"}, | ||
| 3298 | {"IIR0 INP0 MUX", "RX1", "RX_RX1"}, | ||
| 3299 | {"IIR0 INP0 MUX", "RX2", "RX_RX2"}, | ||
| 3300 | {"IIR0 INP0 MUX", "RX3", "RX_RX3"}, | ||
| 3301 | {"IIR0 INP0 MUX", "RX4", "RX_RX4"}, | ||
| 3302 | {"IIR0 INP0 MUX", "RX5", "RX_RX5"}, | ||
| 3303 | {"IIR0", NULL, "IIR0 INP1 MUX"}, | ||
| 3304 | {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3305 | {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3306 | {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3307 | {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3308 | {"IIR0 INP1 MUX", "RX0", "RX_RX0"}, | ||
| 3309 | {"IIR0 INP1 MUX", "RX1", "RX_RX1"}, | ||
| 3310 | {"IIR0 INP1 MUX", "RX2", "RX_RX2"}, | ||
| 3311 | {"IIR0 INP1 MUX", "RX3", "RX_RX3"}, | ||
| 3312 | {"IIR0 INP1 MUX", "RX4", "RX_RX4"}, | ||
| 3313 | {"IIR0 INP1 MUX", "RX5", "RX_RX5"}, | ||
| 3314 | {"IIR0", NULL, "IIR0 INP2 MUX"}, | ||
| 3315 | {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3316 | {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3317 | {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3318 | {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3319 | {"IIR0 INP2 MUX", "RX0", "RX_RX0"}, | ||
| 3320 | {"IIR0 INP2 MUX", "RX1", "RX_RX1"}, | ||
| 3321 | {"IIR0 INP2 MUX", "RX2", "RX_RX2"}, | ||
| 3322 | {"IIR0 INP2 MUX", "RX3", "RX_RX3"}, | ||
| 3323 | {"IIR0 INP2 MUX", "RX4", "RX_RX4"}, | ||
| 3324 | {"IIR0 INP2 MUX", "RX5", "RX_RX5"}, | ||
| 3325 | {"IIR0", NULL, "IIR0 INP3 MUX"}, | ||
| 3326 | {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3327 | {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3328 | {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3329 | {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3330 | {"IIR0 INP3 MUX", "RX0", "RX_RX0"}, | ||
| 3331 | {"IIR0 INP3 MUX", "RX1", "RX_RX1"}, | ||
| 3332 | {"IIR0 INP3 MUX", "RX2", "RX_RX2"}, | ||
| 3333 | {"IIR0 INP3 MUX", "RX3", "RX_RX3"}, | ||
| 3334 | {"IIR0 INP3 MUX", "RX4", "RX_RX4"}, | ||
| 3335 | {"IIR0 INP3 MUX", "RX5", "RX_RX5"}, | ||
| 3336 | |||
| 3337 | {"IIR1", NULL, "RX_MCLK"}, | ||
| 3338 | {"IIR1", NULL, "IIR1 INP0 MUX"}, | ||
| 3339 | {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3340 | {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3341 | {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3342 | {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3343 | {"IIR1 INP0 MUX", "RX0", "RX_RX0"}, | ||
| 3344 | {"IIR1 INP0 MUX", "RX1", "RX_RX1"}, | ||
| 3345 | {"IIR1 INP0 MUX", "RX2", "RX_RX2"}, | ||
| 3346 | {"IIR1 INP0 MUX", "RX3", "RX_RX3"}, | ||
| 3347 | {"IIR1 INP0 MUX", "RX4", "RX_RX4"}, | ||
| 3348 | {"IIR1 INP0 MUX", "RX5", "RX_RX5"}, | ||
| 3349 | {"IIR1", NULL, "IIR1 INP1 MUX"}, | ||
| 3350 | {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3351 | {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3352 | {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3353 | {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3354 | {"IIR1 INP1 MUX", "RX0", "RX_RX0"}, | ||
| 3355 | {"IIR1 INP1 MUX", "RX1", "RX_RX1"}, | ||
| 3356 | {"IIR1 INP1 MUX", "RX2", "RX_RX2"}, | ||
| 3357 | {"IIR1 INP1 MUX", "RX3", "RX_RX3"}, | ||
| 3358 | {"IIR1 INP1 MUX", "RX4", "RX_RX4"}, | ||
| 3359 | {"IIR1 INP1 MUX", "RX5", "RX_RX5"}, | ||
| 3360 | {"IIR1", NULL, "IIR1 INP2 MUX"}, | ||
| 3361 | {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3362 | {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3363 | {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3364 | {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3365 | {"IIR1 INP2 MUX", "RX0", "RX_RX0"}, | ||
| 3366 | {"IIR1 INP2 MUX", "RX1", "RX_RX1"}, | ||
| 3367 | {"IIR1 INP2 MUX", "RX2", "RX_RX2"}, | ||
| 3368 | {"IIR1 INP2 MUX", "RX3", "RX_RX3"}, | ||
| 3369 | {"IIR1 INP2 MUX", "RX4", "RX_RX4"}, | ||
| 3370 | {"IIR1 INP2 MUX", "RX5", "RX_RX5"}, | ||
| 3371 | {"IIR1", NULL, "IIR1 INP3 MUX"}, | ||
| 3372 | {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"}, | ||
| 3373 | {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"}, | ||
| 3374 | {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"}, | ||
| 3375 | {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"}, | ||
| 3376 | {"IIR1 INP3 MUX", "RX0", "RX_RX0"}, | ||
| 3377 | {"IIR1 INP3 MUX", "RX1", "RX_RX1"}, | ||
| 3378 | {"IIR1 INP3 MUX", "RX2", "RX_RX2"}, | ||
| 3379 | {"IIR1 INP3 MUX", "RX3", "RX_RX3"}, | ||
| 3380 | {"IIR1 INP3 MUX", "RX4", "RX_RX4"}, | ||
| 3381 | {"IIR1 INP3 MUX", "RX5", "RX_RX5"}, | ||
| 3382 | |||
| 3383 | {"SRC0", NULL, "IIR0"}, | ||
| 3384 | {"SRC1", NULL, "IIR1"}, | ||
| 3385 | {"RX INT0 MIX2 INP", "SRC0", "SRC0"}, | ||
| 3386 | {"RX INT0 MIX2 INP", "SRC1", "SRC1"}, | ||
| 3387 | {"RX INT1 MIX2 INP", "SRC0", "SRC0"}, | ||
| 3388 | {"RX INT1 MIX2 INP", "SRC1", "SRC1"}, | ||
| 3389 | {"RX INT2 MIX2 INP", "SRC0", "SRC0"}, | ||
| 3390 | {"RX INT2 MIX2 INP", "SRC1", "SRC1"}, | ||
| 3391 | }; | ||
| 3392 | |||
| 3393 | static int rx_macro_component_probe(struct snd_soc_component *component) | ||
| 3394 | { | ||
| 3395 | struct rx_macro *rx = snd_soc_component_get_drvdata(component); | ||
| 3396 | |||
| 3397 | snd_soc_component_init_regmap(component, rx->regmap); | ||
| 3398 | |||
| 3399 | snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_SEC7, | ||
| 3400 | CDC_RX_DSM_OUT_DELAY_SEL_MASK, | ||
| 3401 | CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); | ||
| 3402 | snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_SEC7, | ||
| 3403 | CDC_RX_DSM_OUT_DELAY_SEL_MASK, | ||
| 3404 | CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); | ||
| 3405 | snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_SEC7, | ||
| 3406 | CDC_RX_DSM_OUT_DELAY_SEL_MASK, | ||
| 3407 | CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE); | ||
| 3408 | snd_soc_component_update_bits(component, CDC_RX_RX0_RX_PATH_CFG3, | ||
| 3409 | CDC_RX_DC_COEFF_SEL_MASK, | ||
| 3410 | CDC_RX_DC_COEFF_SEL_TWO); | ||
| 3411 | snd_soc_component_update_bits(component, CDC_RX_RX1_RX_PATH_CFG3, | ||
| 3412 | CDC_RX_DC_COEFF_SEL_MASK, | ||
| 3413 | CDC_RX_DC_COEFF_SEL_TWO); | ||
| 3414 | snd_soc_component_update_bits(component, CDC_RX_RX2_RX_PATH_CFG3, | ||
| 3415 | CDC_RX_DC_COEFF_SEL_MASK, | ||
| 3416 | CDC_RX_DC_COEFF_SEL_TWO); | ||
| 3417 | |||
| 3418 | rx->component = component; | ||
| 3419 | |||
| 3420 | return 0; | ||
| 3421 | } | ||
| 3422 | |||
| 3423 | static int swclk_gate_enable(struct clk_hw *hw) | ||
| 3424 | { | ||
| 3425 | struct rx_macro *rx = to_rx_macro(hw); | ||
| 3426 | |||
| 3427 | rx_macro_mclk_enable(rx, true); | ||
| 3428 | if (rx->reset_swr) | ||
| 3429 | regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 3430 | CDC_RX_SWR_RESET_MASK, | ||
| 3431 | CDC_RX_SWR_RESET); | ||
| 3432 | |||
| 3433 | regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 3434 | CDC_RX_SWR_CLK_EN_MASK, 1); | ||
| 3435 | |||
| 3436 | if (rx->reset_swr) | ||
| 3437 | regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 3438 | CDC_RX_SWR_RESET_MASK, 0); | ||
| 3439 | rx->reset_swr = false; | ||
| 3440 | |||
| 3441 | return 0; | ||
| 3442 | } | ||
| 3443 | |||
| 3444 | static void swclk_gate_disable(struct clk_hw *hw) | ||
| 3445 | { | ||
| 3446 | struct rx_macro *rx = to_rx_macro(hw); | ||
| 3447 | |||
| 3448 | regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 3449 | CDC_RX_SWR_CLK_EN_MASK, 0); | ||
| 3450 | |||
| 3451 | rx_macro_mclk_enable(rx, false); | ||
| 3452 | } | ||
| 3453 | |||
| 3454 | static int swclk_gate_is_enabled(struct clk_hw *hw) | ||
| 3455 | { | ||
| 3456 | struct rx_macro *rx = to_rx_macro(hw); | ||
| 3457 | int ret, val; | ||
| 3458 | |||
| 3459 | regmap_read(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL, &val); | ||
| 3460 | ret = val & BIT(0); | ||
| 3461 | |||
| 3462 | return ret; | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | static unsigned long swclk_recalc_rate(struct clk_hw *hw, | ||
| 3466 | unsigned long parent_rate) | ||
| 3467 | { | ||
| 3468 | return parent_rate / 2; | ||
| 3469 | } | ||
| 3470 | |||
| 3471 | static const struct clk_ops swclk_gate_ops = { | ||
| 3472 | .prepare = swclk_gate_enable, | ||
| 3473 | .unprepare = swclk_gate_disable, | ||
| 3474 | .is_enabled = swclk_gate_is_enabled, | ||
| 3475 | .recalc_rate = swclk_recalc_rate, | ||
| 3476 | |||
| 3477 | }; | ||
| 3478 | |||
| 3479 | static struct clk *rx_macro_register_mclk_output(struct rx_macro *rx) | ||
| 3480 | { | ||
| 3481 | struct device *dev = rx->dev; | ||
| 3482 | struct device_node *np = dev->of_node; | ||
| 3483 | const char *parent_clk_name = NULL; | ||
| 3484 | const char *clk_name = "lpass-rx-mclk"; | ||
| 3485 | struct clk_hw *hw; | ||
| 3486 | struct clk_init_data init; | ||
| 3487 | int ret; | ||
| 3488 | |||
| 3489 | parent_clk_name = __clk_get_name(rx->clks[2].clk); | ||
| 3490 | |||
| 3491 | init.name = clk_name; | ||
| 3492 | init.ops = &swclk_gate_ops; | ||
| 3493 | init.flags = 0; | ||
| 3494 | init.parent_names = &parent_clk_name; | ||
| 3495 | init.num_parents = 1; | ||
| 3496 | rx->hw.init = &init; | ||
| 3497 | hw = &rx->hw; | ||
| 3498 | ret = clk_hw_register(rx->dev, hw); | ||
| 3499 | if (ret) | ||
| 3500 | return ERR_PTR(ret); | ||
| 3501 | |||
| 3502 | of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); | ||
| 3503 | |||
| 3504 | return NULL; | ||
| 3505 | } | ||
| 3506 | |||
| 3507 | static const struct snd_soc_component_driver rx_macro_component_drv = { | ||
| 3508 | .name = "RX-MACRO", | ||
| 3509 | .probe = rx_macro_component_probe, | ||
| 3510 | .controls = rx_macro_snd_controls, | ||
| 3511 | .num_controls = ARRAY_SIZE(rx_macro_snd_controls), | ||
| 3512 | .dapm_widgets = rx_macro_dapm_widgets, | ||
| 3513 | .num_dapm_widgets = ARRAY_SIZE(rx_macro_dapm_widgets), | ||
| 3514 | .dapm_routes = rx_audio_map, | ||
| 3515 | .num_dapm_routes = ARRAY_SIZE(rx_audio_map), | ||
| 3516 | }; | ||
| 3517 | |||
| 3518 | static int rx_macro_probe(struct platform_device *pdev) | ||
| 3519 | { | ||
| 3520 | struct device *dev = &pdev->dev; | ||
| 3521 | struct rx_macro *rx; | ||
| 3522 | void __iomem *base; | ||
| 3523 | int ret; | ||
| 3524 | |||
| 3525 | rx = devm_kzalloc(dev, sizeof(*rx), GFP_KERNEL); | ||
| 3526 | if (!rx) | ||
| 3527 | return -ENOMEM; | ||
| 3528 | |||
| 3529 | rx->clks[0].id = "macro"; | ||
| 3530 | rx->clks[1].id = "dcodec"; | ||
| 3531 | rx->clks[2].id = "mclk"; | ||
| 3532 | rx->clks[3].id = "npl"; | ||
| 3533 | rx->clks[4].id = "fsgen"; | ||
| 3534 | |||
| 3535 | ret = devm_clk_bulk_get(dev, RX_NUM_CLKS_MAX, rx->clks); | ||
| 3536 | if (ret) { | ||
| 3537 | dev_err(dev, "Error getting RX Clocks (%d)\n", ret); | ||
| 3538 | return ret; | ||
| 3539 | } | ||
| 3540 | |||
| 3541 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 3542 | if (IS_ERR(base)) | ||
| 3543 | return PTR_ERR(base); | ||
| 3544 | |||
| 3545 | rx->regmap = devm_regmap_init_mmio(dev, base, &rx_regmap_config); | ||
| 3546 | |||
| 3547 | dev_set_drvdata(dev, rx); | ||
| 3548 | |||
| 3549 | rx->reset_swr = true; | ||
| 3550 | rx->dev = dev; | ||
| 3551 | |||
| 3552 | /* set MCLK and NPL rates */ | ||
| 3553 | clk_set_rate(rx->clks[2].clk, MCLK_FREQ); | ||
| 3554 | clk_set_rate(rx->clks[3].clk, MCLK_FREQ); | ||
| 3555 | |||
| 3556 | ret = clk_bulk_prepare_enable(RX_NUM_CLKS_MAX, rx->clks); | ||
| 3557 | if (ret) | ||
| 3558 | return ret; | ||
| 3559 | |||
| 3560 | rx_macro_register_mclk_output(rx); | ||
| 3561 | |||
| 3562 | ret = devm_snd_soc_register_component(dev, &rx_macro_component_drv, | ||
| 3563 | rx_macro_dai, | ||
| 3564 | ARRAY_SIZE(rx_macro_dai)); | ||
| 3565 | if (ret) | ||
| 3566 | clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); | ||
| 3567 | |||
| 3568 | return ret; | ||
| 3569 | } | ||
| 3570 | |||
| 3571 | static int rx_macro_remove(struct platform_device *pdev) | ||
| 3572 | { | ||
| 3573 | struct rx_macro *rx = dev_get_drvdata(&pdev->dev); | ||
| 3574 | |||
| 3575 | of_clk_del_provider(pdev->dev.of_node); | ||
| 3576 | clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks); | ||
| 3577 | return 0; | ||
| 3578 | } | ||
| 3579 | |||
| 3580 | static const struct of_device_id rx_macro_dt_match[] = { | ||
| 3581 | { .compatible = "qcom,sm8250-lpass-rx-macro" }, | ||
| 3582 | { } | ||
| 3583 | }; | ||
| 3584 | |||
| 3585 | static struct platform_driver rx_macro_driver = { | ||
| 3586 | .driver = { | ||
| 3587 | .name = "rx_macro", | ||
| 3588 | .owner = THIS_MODULE, | ||
| 3589 | .of_match_table = rx_macro_dt_match, | ||
| 3590 | .suppress_bind_attrs = true, | ||
| 3591 | }, | ||
| 3592 | .probe = rx_macro_probe, | ||
| 3593 | .remove = rx_macro_remove, | ||
| 3594 | }; | ||
| 3595 | |||
| 3596 | module_platform_driver(rx_macro_driver); | ||
| 3597 | |||
| 3598 | MODULE_DESCRIPTION("RX macro driver"); | ||
| 3599 | MODULE_LICENSE("GPL"); | ||
| @@ -0,0 +1,1862 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. | ||
| 3 | |||
| 4 | #include <linux/module.h> | ||
| 5 | #include <linux/init.h> | ||
| 6 | #include <linux/clk.h> | ||
| 7 | #include <linux/io.h> | ||
| 8 | #include <linux/platform_device.h> | ||
| 9 | #include <linux/regmap.h> | ||
| 10 | #include <sound/soc.h> | ||
| 11 | #include <sound/soc-dapm.h> | ||
| 12 | #include <sound/tlv.h> | ||
| 13 | #include <linux/of_clk.h> | ||
| 14 | #include <linux/clk-provider.h> | ||
| 15 | |||
| 16 | #define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000) | ||
| 17 | #define CDC_TX_MCLK_EN_MASK BIT(0) | ||
| 18 | #define CDC_TX_MCLK_ENABLE BIT(0) | ||
| 19 | #define CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (0x0004) | ||
| 20 | #define CDC_TX_FS_CNT_EN_MASK BIT(0) | ||
| 21 | #define CDC_TX_FS_CNT_ENABLE BIT(0) | ||
| 22 | #define CDC_TX_CLK_RST_CTRL_SWR_CONTROL (0x0008) | ||
| 23 | #define CDC_TX_SWR_RESET_MASK BIT(1) | ||
| 24 | #define CDC_TX_SWR_RESET_ENABLE BIT(1) | ||
| 25 | #define CDC_TX_SWR_CLK_EN_MASK BIT(0) | ||
| 26 | #define CDC_TX_SWR_CLK_ENABLE BIT(0) | ||
| 27 | #define CDC_TX_TOP_CSR_TOP_CFG0 (0x0080) | ||
| 28 | #define CDC_TX_TOP_CSR_ANC_CFG (0x0084) | ||
| 29 | #define CDC_TX_TOP_CSR_SWR_CTRL (0x0088) | ||
| 30 | #define CDC_TX_TOP_CSR_FREQ_MCLK (0x0090) | ||
| 31 | #define CDC_TX_TOP_CSR_DEBUG_BUS (0x0094) | ||
| 32 | #define CDC_TX_TOP_CSR_DEBUG_EN (0x0098) | ||
| 33 | #define CDC_TX_TOP_CSR_TX_I2S_CTL (0x00A4) | ||
| 34 | #define CDC_TX_TOP_CSR_I2S_CLK (0x00A8) | ||
| 35 | #define CDC_TX_TOP_CSR_I2S_RESET (0x00AC) | ||
| 36 | #define CDC_TX_TOP_CSR_SWR_DMICn_CTL(n) (0x00C0 + n * 0x4) | ||
| 37 | #define CDC_TX_TOP_CSR_SWR_DMIC0_CTL (0x00C0) | ||
| 38 | #define CDC_TX_SWR_DMIC_CLK_SEL_MASK GENMASK(3, 1) | ||
| 39 | #define CDC_TX_TOP_CSR_SWR_DMIC1_CTL (0x00C4) | ||
| 40 | #define CDC_TX_TOP_CSR_SWR_DMIC2_CTL (0x00C8) | ||
| 41 | #define CDC_TX_TOP_CSR_SWR_DMIC3_CTL (0x00CC) | ||
| 42 | #define CDC_TX_TOP_CSR_SWR_AMIC0_CTL (0x00D0) | ||
| 43 | #define CDC_TX_TOP_CSR_SWR_AMIC1_CTL (0x00D4) | ||
| 44 | #define CDC_TX_INP_MUX_ADC_MUXn_CFG0(n) (0x0100 + 0x8 * n) | ||
| 45 | #define CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK GENMASK(3, 0) | ||
| 46 | #define CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x0100) | ||
| 47 | #define CDC_TX_INP_MUX_ADC_MUXn_CFG1(n) (0x0104 + 0x8 * n) | ||
| 48 | #define CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x0104) | ||
| 49 | #define CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x0108) | ||
| 50 | #define CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x010C) | ||
| 51 | #define CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x0110) | ||
| 52 | #define CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x0114) | ||
| 53 | #define CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x0118) | ||
| 54 | #define CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x011C) | ||
| 55 | #define CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x0120) | ||
| 56 | #define CDC_TX_INP_MUX_ADC_MUX4_CFG1 (0x0124) | ||
| 57 | #define CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x0128) | ||
| 58 | #define CDC_TX_INP_MUX_ADC_MUX5_CFG1 (0x012C) | ||
| 59 | #define CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x0130) | ||
| 60 | #define CDC_TX_INP_MUX_ADC_MUX6_CFG1 (0x0134) | ||
| 61 | #define CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x0138) | ||
| 62 | #define CDC_TX_INP_MUX_ADC_MUX7_CFG1 (0x013C) | ||
| 63 | #define CDC_TX_ANC0_CLK_RESET_CTL (0x0200) | ||
| 64 | #define CDC_TX_ANC0_MODE_1_CTL (0x0204) | ||
| 65 | #define CDC_TX_ANC0_MODE_2_CTL (0x0208) | ||
| 66 | #define CDC_TX_ANC0_FF_SHIFT (0x020C) | ||
| 67 | #define CDC_TX_ANC0_FB_SHIFT (0x0210) | ||
| 68 | #define CDC_TX_ANC0_LPF_FF_A_CTL (0x0214) | ||
| 69 | #define CDC_TX_ANC0_LPF_FF_B_CTL (0x0218) | ||
| 70 | #define CDC_TX_ANC0_LPF_FB_CTL (0x021C) | ||
| 71 | #define CDC_TX_ANC0_SMLPF_CTL (0x0220) | ||
| 72 | #define CDC_TX_ANC0_DCFLT_SHIFT_CTL (0x0224) | ||
| 73 | #define CDC_TX_ANC0_IIR_ADAPT_CTL (0x0228) | ||
| 74 | #define CDC_TX_ANC0_IIR_COEFF_1_CTL (0x022C) | ||
| 75 | #define CDC_TX_ANC0_IIR_COEFF_2_CTL (0x0230) | ||
| 76 | #define CDC_TX_ANC0_FF_A_GAIN_CTL (0x0234) | ||
| 77 | #define CDC_TX_ANC0_FF_B_GAIN_CTL (0x0238) | ||
| 78 | #define CDC_TX_ANC0_FB_GAIN_CTL (0x023C) | ||
| 79 | #define CDC_TXn_TX_PATH_CTL(n) (0x0400 + 0x80 * n) | ||
| 80 | #define CDC_TXn_PCM_RATE_MASK GENMASK(3, 0) | ||
| 81 | #define CDC_TXn_PGA_MUTE_MASK BIT(4) | ||
| 82 | #define CDC_TXn_CLK_EN_MASK BIT(5) | ||
| 83 | #define CDC_TX0_TX_PATH_CTL (0x0400) | ||
| 84 | #define CDC_TXn_TX_PATH_CFG0(n) (0x0404 + 0x80 * n) | ||
| 85 | #define CDC_TX0_TX_PATH_CFG0 (0x0404) | ||
| 86 | #define CDC_TXn_PH_EN_MASK BIT(0) | ||
| 87 | #define CDC_TXn_ADC_MODE_MASK GENMASK(2, 1) | ||
| 88 | #define CDC_TXn_HPF_CUT_FREQ_MASK GENMASK(6, 5) | ||
| 89 | #define CDC_TXn_ADC_DMIC_SEL_MASK BIT(7) | ||
| 90 | #define CDC_TX0_TX_PATH_CFG1 (0x0408) | ||
| 91 | #define CDC_TXn_TX_VOL_CTL(n) (0x040C + 0x80 * n) | ||
| 92 | #define CDC_TX0_TX_VOL_CTL (0x040C) | ||
| 93 | #define CDC_TX0_TX_PATH_SEC0 (0x0410) | ||
| 94 | #define CDC_TX0_TX_PATH_SEC1 (0x0414) | ||
| 95 | #define CDC_TXn_TX_PATH_SEC2(n) (0x0418 + 0x80 * n) | ||
| 96 | #define CDC_TXn_HPF_F_CHANGE_MASK BIT(1) | ||
| 97 | #define CDC_TXn_HPF_ZERO_GATE_MASK BIT(0) | ||
| 98 | #define CDC_TX0_TX_PATH_SEC2 (0x0418) | ||
| 99 | #define CDC_TX0_TX_PATH_SEC3 (0x041C) | ||
| 100 | #define CDC_TX0_TX_PATH_SEC4 (0x0420) | ||
| 101 | #define CDC_TX0_TX_PATH_SEC5 (0x0424) | ||
| 102 | #define CDC_TX0_TX_PATH_SEC6 (0x0428) | ||
| 103 | #define CDC_TX0_TX_PATH_SEC7 (0x042C) | ||
| 104 | #define CDC_TX0_MBHC_CTL_EN_MASK BIT(6) | ||
| 105 | #define CDC_TX1_TX_PATH_CTL (0x0480) | ||
| 106 | #define CDC_TX1_TX_PATH_CFG0 (0x0484) | ||
| 107 | #define CDC_TX1_TX_PATH_CFG1 (0x0488) | ||
| 108 | #define CDC_TX1_TX_VOL_CTL (0x048C) | ||
| 109 | #define CDC_TX1_TX_PATH_SEC0 (0x0490) | ||
| 110 | #define CDC_TX1_TX_PATH_SEC1 (0x0494) | ||
| 111 | #define CDC_TX1_TX_PATH_SEC2 (0x0498) | ||
| 112 | #define CDC_TX1_TX_PATH_SEC3 (0x049C) | ||
| 113 | #define CDC_TX1_TX_PATH_SEC4 (0x04A0) | ||
| 114 | #define CDC_TX1_TX_PATH_SEC5 (0x04A4) | ||
| 115 | #define CDC_TX1_TX_PATH_SEC6 (0x04A8) | ||
| 116 | #define CDC_TX2_TX_PATH_CTL (0x0500) | ||
| 117 | #define CDC_TX2_TX_PATH_CFG0 (0x0504) | ||
| 118 | #define CDC_TX2_TX_PATH_CFG1 (0x0508) | ||
| 119 | #define CDC_TX2_TX_VOL_CTL (0x050C) | ||
| 120 | #define CDC_TX2_TX_PATH_SEC0 (0x0510) | ||
| 121 | #define CDC_TX2_TX_PATH_SEC1 (0x0514) | ||
| 122 | #define CDC_TX2_TX_PATH_SEC2 (0x0518) | ||
| 123 | #define CDC_TX2_TX_PATH_SEC3 (0x051C) | ||
| 124 | #define CDC_TX2_TX_PATH_SEC4 (0x0520) | ||
| 125 | #define CDC_TX2_TX_PATH_SEC5 (0x0524) | ||
| 126 | #define CDC_TX2_TX_PATH_SEC6 (0x0528) | ||
| 127 | #define CDC_TX3_TX_PATH_CTL (0x0580) | ||
| 128 | #define CDC_TX3_TX_PATH_CFG0 (0x0584) | ||
| 129 | #define CDC_TX3_TX_PATH_CFG1 (0x0588) | ||
| 130 | #define CDC_TX3_TX_VOL_CTL (0x058C) | ||
| 131 | #define CDC_TX3_TX_PATH_SEC0 (0x0590) | ||
| 132 | #define CDC_TX3_TX_PATH_SEC1 (0x0594) | ||
| 133 | #define CDC_TX3_TX_PATH_SEC2 (0x0598) | ||
| 134 | #define CDC_TX3_TX_PATH_SEC3 (0x059C) | ||
| 135 | #define CDC_TX3_TX_PATH_SEC4 (0x05A0) | ||
| 136 | #define CDC_TX3_TX_PATH_SEC5 (0x05A4) | ||
| 137 | #define CDC_TX3_TX_PATH_SEC6 (0x05A8) | ||
| 138 | #define CDC_TX4_TX_PATH_CTL (0x0600) | ||
| 139 | #define CDC_TX4_TX_PATH_CFG0 (0x0604) | ||
| 140 | #define CDC_TX4_TX_PATH_CFG1 (0x0608) | ||
| 141 | #define CDC_TX4_TX_VOL_CTL (0x060C) | ||
| 142 | #define CDC_TX4_TX_PATH_SEC0 (0x0610) | ||
| 143 | #define CDC_TX4_TX_PATH_SEC1 (0x0614) | ||
| 144 | #define CDC_TX4_TX_PATH_SEC2 (0x0618) | ||
| 145 | #define CDC_TX4_TX_PATH_SEC3 (0x061C) | ||
| 146 | #define CDC_TX4_TX_PATH_SEC4 (0x0620) | ||
| 147 | #define CDC_TX4_TX_PATH_SEC5 (0x0624) | ||
| 148 | #define CDC_TX4_TX_PATH_SEC6 (0x0628) | ||
| 149 | #define CDC_TX5_TX_PATH_CTL (0x0680) | ||
| 150 | #define CDC_TX5_TX_PATH_CFG0 (0x0684) | ||
| 151 | #define CDC_TX5_TX_PATH_CFG1 (0x0688) | ||
| 152 | #define CDC_TX5_TX_VOL_CTL (0x068C) | ||
| 153 | #define CDC_TX5_TX_PATH_SEC0 (0x0690) | ||
| 154 | #define CDC_TX5_TX_PATH_SEC1 (0x0694) | ||
| 155 | #define CDC_TX5_TX_PATH_SEC2 (0x0698) | ||
| 156 | #define CDC_TX5_TX_PATH_SEC3 (0x069C) | ||
| 157 | #define CDC_TX5_TX_PATH_SEC4 (0x06A0) | ||
| 158 | #define CDC_TX5_TX_PATH_SEC5 (0x06A4) | ||
| 159 | #define CDC_TX5_TX_PATH_SEC6 (0x06A8) | ||
| 160 | #define CDC_TX6_TX_PATH_CTL (0x0700) | ||
| 161 | #define CDC_TX6_TX_PATH_CFG0 (0x0704) | ||
| 162 | #define CDC_TX6_TX_PATH_CFG1 (0x0708) | ||
| 163 | #define CDC_TX6_TX_VOL_CTL (0x070C) | ||
| 164 | #define CDC_TX6_TX_PATH_SEC0 (0x0710) | ||
| 165 | #define CDC_TX6_TX_PATH_SEC1 (0x0714) | ||
| 166 | #define CDC_TX6_TX_PATH_SEC2 (0x0718) | ||
| 167 | #define CDC_TX6_TX_PATH_SEC3 (0x071C) | ||
| 168 | #define CDC_TX6_TX_PATH_SEC4 (0x0720) | ||
| 169 | #define CDC_TX6_TX_PATH_SEC5 (0x0724) | ||
| 170 | #define CDC_TX6_TX_PATH_SEC6 (0x0728) | ||
| 171 | #define CDC_TX7_TX_PATH_CTL (0x0780) | ||
| 172 | #define CDC_TX7_TX_PATH_CFG0 (0x0784) | ||
| 173 | #define CDC_TX7_TX_PATH_CFG1 (0x0788) | ||
| 174 | #define CDC_TX7_TX_VOL_CTL (0x078C) | ||
| 175 | #define CDC_TX7_TX_PATH_SEC0 (0x0790) | ||
| 176 | #define CDC_TX7_TX_PATH_SEC1 (0x0794) | ||
| 177 | #define CDC_TX7_TX_PATH_SEC2 (0x0798) | ||
| 178 | #define CDC_TX7_TX_PATH_SEC3 (0x079C) | ||
| 179 | #define CDC_TX7_TX_PATH_SEC4 (0x07A0) | ||
| 180 | #define CDC_TX7_TX_PATH_SEC5 (0x07A4) | ||
| 181 | #define CDC_TX7_TX_PATH_SEC6 (0x07A8) | ||
| 182 | #define TX_MAX_OFFSET (0x07A8) | ||
| 183 | |||
| 184 | #define TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | ||
| 185 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ | ||
| 186 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) | ||
| 187 | #define TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | ||
| 188 | SNDRV_PCM_FMTBIT_S24_LE |\ | ||
| 189 | SNDRV_PCM_FMTBIT_S24_3LE) | ||
| 190 | |||
| 191 | #define CF_MIN_3DB_4HZ 0x0 | ||
| 192 | #define CF_MIN_3DB_75HZ 0x1 | ||
| 193 | #define CF_MIN_3DB_150HZ 0x2 | ||
| 194 | #define TX_ADC_MAX 5 | ||
| 195 | #define TX_ADC_TO_DMIC(n) ((n - TX_ADC_MAX)/2) | ||
| 196 | #define NUM_DECIMATORS 8 | ||
| 197 | #define TX_NUM_CLKS_MAX 5 | ||
| 198 | #define TX_MACRO_DMIC_UNMUTE_DELAY_MS 40 | ||
| 199 | #define TX_MACRO_AMIC_UNMUTE_DELAY_MS 100 | ||
| 200 | #define TX_MACRO_DMIC_HPF_DELAY_MS 300 | ||
| 201 | #define TX_MACRO_AMIC_HPF_DELAY_MS 300 | ||
| 202 | #define MCLK_FREQ 9600000 | ||
| 203 | |||
| 204 | enum { | ||
| 205 | TX_MACRO_AIF_INVALID = 0, | ||
| 206 | TX_MACRO_AIF1_CAP, | ||
| 207 | TX_MACRO_AIF2_CAP, | ||
| 208 | TX_MACRO_AIF3_CAP, | ||
| 209 | TX_MACRO_MAX_DAIS | ||
| 210 | }; | ||
| 211 | |||
| 212 | enum { | ||
| 213 | TX_MACRO_DEC0, | ||
| 214 | TX_MACRO_DEC1, | ||
| 215 | TX_MACRO_DEC2, | ||
| 216 | TX_MACRO_DEC3, | ||
| 217 | TX_MACRO_DEC4, | ||
| 218 | TX_MACRO_DEC5, | ||
| 219 | TX_MACRO_DEC6, | ||
| 220 | TX_MACRO_DEC7, | ||
| 221 | TX_MACRO_DEC_MAX, | ||
| 222 | }; | ||
| 223 | |||
| 224 | enum { | ||
| 225 | TX_MACRO_CLK_DIV_2, | ||
| 226 | TX_MACRO_CLK_DIV_3, | ||
| 227 | TX_MACRO_CLK_DIV_4, | ||
| 228 | TX_MACRO_CLK_DIV_6, | ||
| 229 | TX_MACRO_CLK_DIV_8, | ||
| 230 | TX_MACRO_CLK_DIV_16, | ||
| 231 | }; | ||
| 232 | |||
| 233 | enum { | ||
| 234 | MSM_DMIC, | ||
| 235 | SWR_MIC, | ||
| 236 | ANC_FB_TUNE1 | ||
| 237 | }; | ||
| 238 | |||
| 239 | struct tx_mute_work { | ||
| 240 | struct tx_macro *tx; | ||
| 241 | u32 decimator; | ||
| 242 | struct delayed_work dwork; | ||
| 243 | }; | ||
| 244 | |||
| 245 | struct hpf_work { | ||
| 246 | struct tx_macro *tx; | ||
| 247 | u8 decimator; | ||
| 248 | u8 hpf_cut_off_freq; | ||
| 249 | struct delayed_work dwork; | ||
| 250 | }; | ||
| 251 | |||
| 252 | struct tx_macro { | ||
| 253 | struct device *dev; | ||
| 254 | struct snd_soc_component *component; | ||
| 255 | struct hpf_work tx_hpf_work[NUM_DECIMATORS]; | ||
| 256 | struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS]; | ||
| 257 | unsigned long active_ch_mask[TX_MACRO_MAX_DAIS]; | ||
| 258 | unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS]; | ||
| 259 | unsigned long active_decimator[TX_MACRO_MAX_DAIS]; | ||
| 260 | struct regmap *regmap; | ||
| 261 | struct clk_bulk_data clks[TX_NUM_CLKS_MAX]; | ||
| 262 | struct clk_hw hw; | ||
| 263 | bool dec_active[NUM_DECIMATORS]; | ||
| 264 | bool reset_swr; | ||
| 265 | int tx_mclk_users; | ||
| 266 | u16 dmic_clk_div; | ||
| 267 | bool bcs_enable; | ||
| 268 | int dec_mode[NUM_DECIMATORS]; | ||
| 269 | bool bcs_clk_en; | ||
| 270 | }; | ||
| 271 | #define to_tx_macro(_hw) container_of(_hw, struct tx_macro, hw) | ||
| 272 | |||
| 273 | static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); | ||
| 274 | |||
| 275 | static const struct reg_default tx_defaults[] = { | ||
| 276 | /* TX Macro */ | ||
| 277 | { CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 }, | ||
| 278 | { CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 }, | ||
| 279 | { CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00}, | ||
| 280 | { CDC_TX_TOP_CSR_TOP_CFG0, 0x00}, | ||
| 281 | { CDC_TX_TOP_CSR_ANC_CFG, 0x00}, | ||
| 282 | { CDC_TX_TOP_CSR_SWR_CTRL, 0x00}, | ||
| 283 | { CDC_TX_TOP_CSR_FREQ_MCLK, 0x00}, | ||
| 284 | { CDC_TX_TOP_CSR_DEBUG_BUS, 0x00}, | ||
| 285 | { CDC_TX_TOP_CSR_DEBUG_EN, 0x00}, | ||
| 286 | { CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C}, | ||
| 287 | { CDC_TX_TOP_CSR_I2S_CLK, 0x00}, | ||
| 288 | { CDC_TX_TOP_CSR_I2S_RESET, 0x00}, | ||
| 289 | { CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00}, | ||
| 290 | { CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00}, | ||
| 291 | { CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00}, | ||
| 292 | { CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00}, | ||
| 293 | { CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00}, | ||
| 294 | { CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00}, | ||
| 295 | { CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00}, | ||
| 296 | { CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00}, | ||
| 297 | { CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00}, | ||
| 298 | { CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00}, | ||
| 299 | { CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00}, | ||
| 300 | { CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00}, | ||
| 301 | { CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00}, | ||
| 302 | { CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00}, | ||
| 303 | { CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00}, | ||
| 304 | { CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00}, | ||
| 305 | { CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00}, | ||
| 306 | { CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00}, | ||
| 307 | { CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00}, | ||
| 308 | { CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00}, | ||
| 309 | { CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00}, | ||
| 310 | { CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00}, | ||
| 311 | { CDC_TX_ANC0_CLK_RESET_CTL, 0x00}, | ||
| 312 | { CDC_TX_ANC0_MODE_1_CTL, 0x00}, | ||
| 313 | { CDC_TX_ANC0_MODE_2_CTL, 0x00}, | ||
| 314 | { CDC_TX_ANC0_FF_SHIFT, 0x00}, | ||
| 315 | { CDC_TX_ANC0_FB_SHIFT, 0x00}, | ||
| 316 | { CDC_TX_ANC0_LPF_FF_A_CTL, 0x00}, | ||
| 317 | { CDC_TX_ANC0_LPF_FF_B_CTL, 0x00}, | ||
| 318 | { CDC_TX_ANC0_LPF_FB_CTL, 0x00}, | ||
| 319 | { CDC_TX_ANC0_SMLPF_CTL, 0x00}, | ||
| 320 | { CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00}, | ||
| 321 | { CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00}, | ||
| 322 | { CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00}, | ||
| 323 | { CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00}, | ||
| 324 | { CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00}, | ||
| 325 | { CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00}, | ||
| 326 | { CDC_TX_ANC0_FB_GAIN_CTL, 0x00}, | ||
| 327 | { CDC_TX0_TX_PATH_CTL, 0x04}, | ||
| 328 | { CDC_TX0_TX_PATH_CFG0, 0x10}, | ||
| 329 | { CDC_TX0_TX_PATH_CFG1, 0x0B}, | ||
| 330 | { CDC_TX0_TX_VOL_CTL, 0x00}, | ||
| 331 | { CDC_TX0_TX_PATH_SEC0, 0x00}, | ||
| 332 | { CDC_TX0_TX_PATH_SEC1, 0x00}, | ||
| 333 | { CDC_TX0_TX_PATH_SEC2, 0x01}, | ||
| 334 | { CDC_TX0_TX_PATH_SEC3, 0x3C}, | ||
| 335 | { CDC_TX0_TX_PATH_SEC4, 0x20}, | ||
| 336 | { CDC_TX0_TX_PATH_SEC5, 0x00}, | ||
| 337 | { CDC_TX0_TX_PATH_SEC6, 0x00}, | ||
| 338 | { CDC_TX0_TX_PATH_SEC7, 0x25}, | ||
| 339 | { CDC_TX1_TX_PATH_CTL, 0x04}, | ||
| 340 | { CDC_TX1_TX_PATH_CFG0, 0x10}, | ||
| 341 | { CDC_TX1_TX_PATH_CFG1, 0x0B}, | ||
| 342 | { CDC_TX1_TX_VOL_CTL, 0x00}, | ||
| 343 | { CDC_TX1_TX_PATH_SEC0, 0x00}, | ||
| 344 | { CDC_TX1_TX_PATH_SEC1, 0x00}, | ||
| 345 | { CDC_TX1_TX_PATH_SEC2, 0x01}, | ||
| 346 | { CDC_TX1_TX_PATH_SEC3, 0x3C}, | ||
| 347 | { CDC_TX1_TX_PATH_SEC4, 0x20}, | ||
| 348 | { CDC_TX1_TX_PATH_SEC5, 0x00}, | ||
| 349 | { CDC_TX1_TX_PATH_SEC6, 0x00}, | ||
| 350 | { CDC_TX2_TX_PATH_CTL, 0x04}, | ||
| 351 | { CDC_TX2_TX_PATH_CFG0, 0x10}, | ||
| 352 | { CDC_TX2_TX_PATH_CFG1, 0x0B}, | ||
| 353 | { CDC_TX2_TX_VOL_CTL, 0x00}, | ||
| 354 | { CDC_TX2_TX_PATH_SEC0, 0x00}, | ||
| 355 | { CDC_TX2_TX_PATH_SEC1, 0x00}, | ||
| 356 | { CDC_TX2_TX_PATH_SEC2, 0x01}, | ||
| 357 | { CDC_TX2_TX_PATH_SEC3, 0x3C}, | ||
| 358 | { CDC_TX2_TX_PATH_SEC4, 0x20}, | ||
| 359 | { CDC_TX2_TX_PATH_SEC5, 0x00}, | ||
| 360 | { CDC_TX2_TX_PATH_SEC6, 0x00}, | ||
| 361 | { CDC_TX3_TX_PATH_CTL, 0x04}, | ||
| 362 | { CDC_TX3_TX_PATH_CFG0, 0x10}, | ||
| 363 | { CDC_TX3_TX_PATH_CFG1, 0x0B}, | ||
| 364 | { CDC_TX3_TX_VOL_CTL, 0x00}, | ||
| 365 | { CDC_TX3_TX_PATH_SEC0, 0x00}, | ||
| 366 | { CDC_TX3_TX_PATH_SEC1, 0x00}, | ||
| 367 | { CDC_TX3_TX_PATH_SEC2, 0x01}, | ||
| 368 | { CDC_TX3_TX_PATH_SEC3, 0x3C}, | ||
| 369 | { CDC_TX3_TX_PATH_SEC4, 0x20}, | ||
| 370 | { CDC_TX3_TX_PATH_SEC5, 0x00}, | ||
| 371 | { CDC_TX3_TX_PATH_SEC6, 0x00}, | ||
| 372 | { CDC_TX4_TX_PATH_CTL, 0x04}, | ||
| 373 | { CDC_TX4_TX_PATH_CFG0, 0x10}, | ||
| 374 | { CDC_TX4_TX_PATH_CFG1, 0x0B}, | ||
| 375 | { CDC_TX4_TX_VOL_CTL, 0x00}, | ||
| 376 | { CDC_TX4_TX_PATH_SEC0, 0x00}, | ||
| 377 | { CDC_TX4_TX_PATH_SEC1, 0x00}, | ||
| 378 | { CDC_TX4_TX_PATH_SEC2, 0x01}, | ||
| 379 | { CDC_TX4_TX_PATH_SEC3, 0x3C}, | ||
| 380 | { CDC_TX4_TX_PATH_SEC4, 0x20}, | ||
| 381 | { CDC_TX4_TX_PATH_SEC5, 0x00}, | ||
| 382 | { CDC_TX4_TX_PATH_SEC6, 0x00}, | ||
| 383 | { CDC_TX5_TX_PATH_CTL, 0x04}, | ||
| 384 | { CDC_TX5_TX_PATH_CFG0, 0x10}, | ||
| 385 | { CDC_TX5_TX_PATH_CFG1, 0x0B}, | ||
| 386 | { CDC_TX5_TX_VOL_CTL, 0x00}, | ||
| 387 | { CDC_TX5_TX_PATH_SEC0, 0x00}, | ||
| 388 | { CDC_TX5_TX_PATH_SEC1, 0x00}, | ||
| 389 | { CDC_TX5_TX_PATH_SEC2, 0x01}, | ||
| 390 | { CDC_TX5_TX_PATH_SEC3, 0x3C}, | ||
| 391 | { CDC_TX5_TX_PATH_SEC4, 0x20}, | ||
| 392 | { CDC_TX5_TX_PATH_SEC5, 0x00}, | ||
| 393 | { CDC_TX5_TX_PATH_SEC6, 0x00}, | ||
| 394 | { CDC_TX6_TX_PATH_CTL, 0x04}, | ||
| 395 | { CDC_TX6_TX_PATH_CFG0, 0x10}, | ||
| 396 | { CDC_TX6_TX_PATH_CFG1, 0x0B}, | ||
| 397 | { CDC_TX6_TX_VOL_CTL, 0x00}, | ||
| 398 | { CDC_TX6_TX_PATH_SEC0, 0x00}, | ||
| 399 | { CDC_TX6_TX_PATH_SEC1, 0x00}, | ||
| 400 | { CDC_TX6_TX_PATH_SEC2, 0x01}, | ||
| 401 | { CDC_TX6_TX_PATH_SEC3, 0x3C}, | ||
| 402 | { CDC_TX6_TX_PATH_SEC4, 0x20}, | ||
| 403 | { CDC_TX6_TX_PATH_SEC5, 0x00}, | ||
| 404 | { CDC_TX6_TX_PATH_SEC6, 0x00}, | ||
| 405 | { CDC_TX7_TX_PATH_CTL, 0x04}, | ||
| 406 | { CDC_TX7_TX_PATH_CFG0, 0x10}, | ||
| 407 | { CDC_TX7_TX_PATH_CFG1, 0x0B}, | ||
| 408 | { CDC_TX7_TX_VOL_CTL, 0x00}, | ||
| 409 | { CDC_TX7_TX_PATH_SEC0, 0x00}, | ||
| 410 | { CDC_TX7_TX_PATH_SEC1, 0x00}, | ||
| 411 | { CDC_TX7_TX_PATH_SEC2, 0x01}, | ||
| 412 | { CDC_TX7_TX_PATH_SEC3, 0x3C}, | ||
| 413 | { CDC_TX7_TX_PATH_SEC4, 0x20}, | ||
| 414 | { CDC_TX7_TX_PATH_SEC5, 0x00}, | ||
| 415 | { CDC_TX7_TX_PATH_SEC6, 0x00}, | ||
| 416 | }; | ||
| 417 | |||
| 418 | static bool tx_is_volatile_register(struct device *dev, unsigned int reg) | ||
| 419 | { | ||
| 420 | /* Update volatile list for tx/tx macros */ | ||
| 421 | switch (reg) { | ||
| 422 | case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: | ||
| 423 | case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: | ||
| 424 | case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: | ||
| 425 | case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: | ||
| 426 | return true; | ||
| 427 | } | ||
| 428 | return false; | ||
| 429 | } | ||
| 430 | |||
| 431 | static bool tx_is_rw_register(struct device *dev, unsigned int reg) | ||
| 432 | { | ||
| 433 | switch (reg) { | ||
| 434 | case CDC_TX_CLK_RST_CTRL_MCLK_CONTROL: | ||
| 435 | case CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL: | ||
| 436 | case CDC_TX_CLK_RST_CTRL_SWR_CONTROL: | ||
| 437 | case CDC_TX_TOP_CSR_TOP_CFG0: | ||
| 438 | case CDC_TX_TOP_CSR_ANC_CFG: | ||
| 439 | case CDC_TX_TOP_CSR_SWR_CTRL: | ||
| 440 | case CDC_TX_TOP_CSR_FREQ_MCLK: | ||
| 441 | case CDC_TX_TOP_CSR_DEBUG_BUS: | ||
| 442 | case CDC_TX_TOP_CSR_DEBUG_EN: | ||
| 443 | case CDC_TX_TOP_CSR_TX_I2S_CTL: | ||
| 444 | case CDC_TX_TOP_CSR_I2S_CLK: | ||
| 445 | case CDC_TX_TOP_CSR_I2S_RESET: | ||
| 446 | case CDC_TX_TOP_CSR_SWR_DMIC0_CTL: | ||
| 447 | case CDC_TX_TOP_CSR_SWR_DMIC1_CTL: | ||
| 448 | case CDC_TX_TOP_CSR_SWR_DMIC2_CTL: | ||
| 449 | case CDC_TX_TOP_CSR_SWR_DMIC3_CTL: | ||
| 450 | case CDC_TX_TOP_CSR_SWR_AMIC0_CTL: | ||
| 451 | case CDC_TX_TOP_CSR_SWR_AMIC1_CTL: | ||
| 452 | case CDC_TX_ANC0_CLK_RESET_CTL: | ||
| 453 | case CDC_TX_ANC0_MODE_1_CTL: | ||
| 454 | case CDC_TX_ANC0_MODE_2_CTL: | ||
| 455 | case CDC_TX_ANC0_FF_SHIFT: | ||
| 456 | case CDC_TX_ANC0_FB_SHIFT: | ||
| 457 | case CDC_TX_ANC0_LPF_FF_A_CTL: | ||
| 458 | case CDC_TX_ANC0_LPF_FF_B_CTL: | ||
| 459 | case CDC_TX_ANC0_LPF_FB_CTL: | ||
| 460 | case CDC_TX_ANC0_SMLPF_CTL: | ||
| 461 | case CDC_TX_ANC0_DCFLT_SHIFT_CTL: | ||
| 462 | case CDC_TX_ANC0_IIR_ADAPT_CTL: | ||
| 463 | case CDC_TX_ANC0_IIR_COEFF_1_CTL: | ||
| 464 | case CDC_TX_ANC0_IIR_COEFF_2_CTL: | ||
| 465 | case CDC_TX_ANC0_FF_A_GAIN_CTL: | ||
| 466 | case CDC_TX_ANC0_FF_B_GAIN_CTL: | ||
| 467 | case CDC_TX_ANC0_FB_GAIN_CTL: | ||
| 468 | case CDC_TX_INP_MUX_ADC_MUX0_CFG0: | ||
| 469 | case CDC_TX_INP_MUX_ADC_MUX0_CFG1: | ||
| 470 | case CDC_TX_INP_MUX_ADC_MUX1_CFG0: | ||
| 471 | case CDC_TX_INP_MUX_ADC_MUX1_CFG1: | ||
| 472 | case CDC_TX_INP_MUX_ADC_MUX2_CFG0: | ||
| 473 | case CDC_TX_INP_MUX_ADC_MUX2_CFG1: | ||
| 474 | case CDC_TX_INP_MUX_ADC_MUX3_CFG0: | ||
| 475 | case CDC_TX_INP_MUX_ADC_MUX3_CFG1: | ||
| 476 | case CDC_TX_INP_MUX_ADC_MUX4_CFG0: | ||
| 477 | case CDC_TX_INP_MUX_ADC_MUX4_CFG1: | ||
| 478 | case CDC_TX_INP_MUX_ADC_MUX5_CFG0: | ||
| 479 | case CDC_TX_INP_MUX_ADC_MUX5_CFG1: | ||
| 480 | case CDC_TX_INP_MUX_ADC_MUX6_CFG0: | ||
| 481 | case CDC_TX_INP_MUX_ADC_MUX6_CFG1: | ||
| 482 | case CDC_TX_INP_MUX_ADC_MUX7_CFG0: | ||
| 483 | case CDC_TX_INP_MUX_ADC_MUX7_CFG1: | ||
| 484 | case CDC_TX0_TX_PATH_CTL: | ||
| 485 | case CDC_TX0_TX_PATH_CFG0: | ||
| 486 | case CDC_TX0_TX_PATH_CFG1: | ||
| 487 | case CDC_TX0_TX_VOL_CTL: | ||
| 488 | case CDC_TX0_TX_PATH_SEC0: | ||
| 489 | case CDC_TX0_TX_PATH_SEC1: | ||
| 490 | case CDC_TX0_TX_PATH_SEC2: | ||
| 491 | case CDC_TX0_TX_PATH_SEC3: | ||
| 492 | case CDC_TX0_TX_PATH_SEC4: | ||
| 493 | case CDC_TX0_TX_PATH_SEC5: | ||
| 494 | case CDC_TX0_TX_PATH_SEC6: | ||
| 495 | case CDC_TX0_TX_PATH_SEC7: | ||
| 496 | case CDC_TX1_TX_PATH_CTL: | ||
| 497 | case CDC_TX1_TX_PATH_CFG0: | ||
| 498 | case CDC_TX1_TX_PATH_CFG1: | ||
| 499 | case CDC_TX1_TX_VOL_CTL: | ||
| 500 | case CDC_TX1_TX_PATH_SEC0: | ||
| 501 | case CDC_TX1_TX_PATH_SEC1: | ||
| 502 | case CDC_TX1_TX_PATH_SEC2: | ||
| 503 | case CDC_TX1_TX_PATH_SEC3: | ||
| 504 | case CDC_TX1_TX_PATH_SEC4: | ||
| 505 | case CDC_TX1_TX_PATH_SEC5: | ||
| 506 | case CDC_TX1_TX_PATH_SEC6: | ||
| 507 | case CDC_TX2_TX_PATH_CTL: | ||
| 508 | case CDC_TX2_TX_PATH_CFG0: | ||
| 509 | case CDC_TX2_TX_PATH_CFG1: | ||
| 510 | case CDC_TX2_TX_VOL_CTL: | ||
| 511 | case CDC_TX2_TX_PATH_SEC0: | ||
| 512 | case CDC_TX2_TX_PATH_SEC1: | ||
| 513 | case CDC_TX2_TX_PATH_SEC2: | ||
| 514 | case CDC_TX2_TX_PATH_SEC3: | ||
| 515 | case CDC_TX2_TX_PATH_SEC4: | ||
| 516 | case CDC_TX2_TX_PATH_SEC5: | ||
| 517 | case CDC_TX2_TX_PATH_SEC6: | ||
| 518 | case CDC_TX3_TX_PATH_CTL: | ||
| 519 | case CDC_TX3_TX_PATH_CFG0: | ||
| 520 | case CDC_TX3_TX_PATH_CFG1: | ||
| 521 | case CDC_TX3_TX_VOL_CTL: | ||
| 522 | case CDC_TX3_TX_PATH_SEC0: | ||
| 523 | case CDC_TX3_TX_PATH_SEC1: | ||
| 524 | case CDC_TX3_TX_PATH_SEC2: | ||
| 525 | case CDC_TX3_TX_PATH_SEC3: | ||
| 526 | case CDC_TX3_TX_PATH_SEC4: | ||
| 527 | case CDC_TX3_TX_PATH_SEC5: | ||
| 528 | case CDC_TX3_TX_PATH_SEC6: | ||
| 529 | case CDC_TX4_TX_PATH_CTL: | ||
| 530 | case CDC_TX4_TX_PATH_CFG0: | ||
| 531 | case CDC_TX4_TX_PATH_CFG1: | ||
| 532 | case CDC_TX4_TX_VOL_CTL: | ||
| 533 | case CDC_TX4_TX_PATH_SEC0: | ||
| 534 | case CDC_TX4_TX_PATH_SEC1: | ||
| 535 | case CDC_TX4_TX_PATH_SEC2: | ||
| 536 | case CDC_TX4_TX_PATH_SEC3: | ||
| 537 | case CDC_TX4_TX_PATH_SEC4: | ||
| 538 | case CDC_TX4_TX_PATH_SEC5: | ||
| 539 | case CDC_TX4_TX_PATH_SEC6: | ||
| 540 | case CDC_TX5_TX_PATH_CTL: | ||
| 541 | case CDC_TX5_TX_PATH_CFG0: | ||
| 542 | case CDC_TX5_TX_PATH_CFG1: | ||
| 543 | case CDC_TX5_TX_VOL_CTL: | ||
| 544 | case CDC_TX5_TX_PATH_SEC0: | ||
| 545 | case CDC_TX5_TX_PATH_SEC1: | ||
| 546 | case CDC_TX5_TX_PATH_SEC2: | ||
| 547 | case CDC_TX5_TX_PATH_SEC3: | ||
| 548 | case CDC_TX5_TX_PATH_SEC4: | ||
| 549 | case CDC_TX5_TX_PATH_SEC5: | ||
| 550 | case CDC_TX5_TX_PATH_SEC6: | ||
| 551 | case CDC_TX6_TX_PATH_CTL: | ||
| 552 | case CDC_TX6_TX_PATH_CFG0: | ||
| 553 | case CDC_TX6_TX_PATH_CFG1: | ||
| 554 | case CDC_TX6_TX_VOL_CTL: | ||
| 555 | case CDC_TX6_TX_PATH_SEC0: | ||
| 556 | case CDC_TX6_TX_PATH_SEC1: | ||
| 557 | case CDC_TX6_TX_PATH_SEC2: | ||
| 558 | case CDC_TX6_TX_PATH_SEC3: | ||
| 559 | case CDC_TX6_TX_PATH_SEC4: | ||
| 560 | case CDC_TX6_TX_PATH_SEC5: | ||
| 561 | case CDC_TX6_TX_PATH_SEC6: | ||
| 562 | case CDC_TX7_TX_PATH_CTL: | ||
| 563 | case CDC_TX7_TX_PATH_CFG0: | ||
| 564 | case CDC_TX7_TX_PATH_CFG1: | ||
| 565 | case CDC_TX7_TX_VOL_CTL: | ||
| 566 | case CDC_TX7_TX_PATH_SEC0: | ||
| 567 | case CDC_TX7_TX_PATH_SEC1: | ||
| 568 | case CDC_TX7_TX_PATH_SEC2: | ||
| 569 | case CDC_TX7_TX_PATH_SEC3: | ||
| 570 | case CDC_TX7_TX_PATH_SEC4: | ||
| 571 | case CDC_TX7_TX_PATH_SEC5: | ||
| 572 | case CDC_TX7_TX_PATH_SEC6: | ||
| 573 | return true; | ||
| 574 | } | ||
| 575 | |||
| 576 | return false; | ||
| 577 | } | ||
| 578 | |||
| 579 | static const struct regmap_config tx_regmap_config = { | ||
| 580 | .name = "tx_macro", | ||
| 581 | .reg_bits = 16, | ||
| 582 | .val_bits = 32, | ||
| 583 | .reg_stride = 4, | ||
| 584 | .cache_type = REGCACHE_FLAT, | ||
| 585 | .max_register = TX_MAX_OFFSET, | ||
| 586 | .reg_defaults = tx_defaults, | ||
| 587 | .num_reg_defaults = ARRAY_SIZE(tx_defaults), | ||
| 588 | .writeable_reg = tx_is_rw_register, | ||
| 589 | .volatile_reg = tx_is_volatile_register, | ||
| 590 | .readable_reg = tx_is_rw_register, | ||
| 591 | }; | ||
| 592 | |||
| 593 | static int tx_macro_mclk_enable(struct tx_macro *tx, | ||
| 594 | bool mclk_enable) | ||
| 595 | { | ||
| 596 | struct regmap *regmap = tx->regmap; | ||
| 597 | |||
| 598 | if (mclk_enable) { | ||
| 599 | if (tx->tx_mclk_users == 0) { | ||
| 600 | /* 9.6MHz MCLK, set value 0x00 if other frequency */ | ||
| 601 | regmap_update_bits(regmap, CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01); | ||
| 602 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, | ||
| 603 | CDC_TX_MCLK_EN_MASK, | ||
| 604 | CDC_TX_MCLK_ENABLE); | ||
| 605 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 606 | CDC_TX_FS_CNT_EN_MASK, | ||
| 607 | CDC_TX_FS_CNT_ENABLE); | ||
| 608 | regcache_mark_dirty(regmap); | ||
| 609 | regcache_sync(regmap); | ||
| 610 | } | ||
| 611 | tx->tx_mclk_users++; | ||
| 612 | } else { | ||
| 613 | if (tx->tx_mclk_users <= 0) { | ||
| 614 | dev_err(tx->dev, "clock already disabled\n"); | ||
| 615 | tx->tx_mclk_users = 0; | ||
| 616 | goto exit; | ||
| 617 | } | ||
| 618 | tx->tx_mclk_users--; | ||
| 619 | if (tx->tx_mclk_users == 0) { | ||
| 620 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, | ||
| 621 | CDC_TX_FS_CNT_EN_MASK, 0x0); | ||
| 622 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, | ||
| 623 | CDC_TX_MCLK_EN_MASK, 0x0); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | exit: | ||
| 627 | return 0; | ||
| 628 | } | ||
| 629 | |||
| 630 | static bool is_amic_enabled(struct snd_soc_component *component, int decimator) | ||
| 631 | { | ||
| 632 | u16 adc_mux_reg, adc_reg, adc_n; | ||
| 633 | |||
| 634 | adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); | ||
| 635 | |||
| 636 | if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { | ||
| 637 | adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); | ||
| 638 | adc_n = snd_soc_component_read_field(component, adc_reg, | ||
| 639 | CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK); | ||
| 640 | if (adc_n < TX_ADC_MAX) | ||
| 641 | return true; | ||
| 642 | } | ||
| 643 | |||
| 644 | return false; | ||
| 645 | } | ||
| 646 | |||
| 647 | static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) | ||
| 648 | { | ||
| 649 | struct delayed_work *hpf_delayed_work; | ||
| 650 | struct hpf_work *hpf_work; | ||
| 651 | struct tx_macro *tx; | ||
| 652 | struct snd_soc_component *component; | ||
| 653 | u16 dec_cfg_reg, hpf_gate_reg; | ||
| 654 | u8 hpf_cut_off_freq; | ||
| 655 | |||
| 656 | hpf_delayed_work = to_delayed_work(work); | ||
| 657 | hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork); | ||
| 658 | tx = hpf_work->tx; | ||
| 659 | component = tx->component; | ||
| 660 | hpf_cut_off_freq = hpf_work->hpf_cut_off_freq; | ||
| 661 | |||
| 662 | dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(hpf_work->decimator); | ||
| 663 | hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(hpf_work->decimator); | ||
| 664 | |||
| 665 | if (is_amic_enabled(component, hpf_work->decimator)) { | ||
| 666 | snd_soc_component_write_field(component, | ||
| 667 | dec_cfg_reg, | ||
| 668 | CDC_TXn_HPF_CUT_FREQ_MASK, | ||
| 669 | hpf_cut_off_freq); | ||
| 670 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 671 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 672 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 673 | 0x02); | ||
| 674 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 675 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 676 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 677 | 0x01); | ||
| 678 | } else { | ||
| 679 | snd_soc_component_write_field(component, dec_cfg_reg, | ||
| 680 | CDC_TXn_HPF_CUT_FREQ_MASK, | ||
| 681 | hpf_cut_off_freq); | ||
| 682 | snd_soc_component_write_field(component, hpf_gate_reg, | ||
| 683 | CDC_TXn_HPF_F_CHANGE_MASK, 0x1); | ||
| 684 | /* Minimum 1 clk cycle delay is required as per HW spec */ | ||
| 685 | usleep_range(1000, 1010); | ||
| 686 | snd_soc_component_write_field(component, hpf_gate_reg, | ||
| 687 | CDC_TXn_HPF_F_CHANGE_MASK, 0x0); | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | static void tx_macro_mute_update_callback(struct work_struct *work) | ||
| 692 | { | ||
| 693 | struct tx_mute_work *tx_mute_dwork; | ||
| 694 | struct snd_soc_component *component; | ||
| 695 | struct tx_macro *tx; | ||
| 696 | struct delayed_work *delayed_work; | ||
| 697 | u8 decimator; | ||
| 698 | |||
| 699 | delayed_work = to_delayed_work(work); | ||
| 700 | tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork); | ||
| 701 | tx = tx_mute_dwork->tx; | ||
| 702 | component = tx->component; | ||
| 703 | decimator = tx_mute_dwork->decimator; | ||
| 704 | |||
| 705 | snd_soc_component_write_field(component, CDC_TXn_TX_PATH_CTL(decimator), | ||
| 706 | CDC_TXn_PGA_MUTE_MASK, 0x0); | ||
| 707 | } | ||
| 708 | |||
| 709 | static int tx_macro_mclk_event(struct snd_soc_dapm_widget *w, | ||
| 710 | struct snd_kcontrol *kcontrol, int event) | ||
| 711 | { | ||
| 712 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 713 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 714 | |||
| 715 | switch (event) { | ||
| 716 | case SND_SOC_DAPM_PRE_PMU: | ||
| 717 | tx_macro_mclk_enable(tx, true); | ||
| 718 | break; | ||
| 719 | case SND_SOC_DAPM_POST_PMD: | ||
| 720 | tx_macro_mclk_enable(tx, false); | ||
| 721 | break; | ||
| 722 | default: | ||
| 723 | break; | ||
| 724 | } | ||
| 725 | |||
| 726 | return 0; | ||
| 727 | } | ||
| 728 | |||
| 729 | static int tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol, | ||
| 730 | struct snd_ctl_elem_value *ucontrol) | ||
| 731 | { | ||
| 732 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 733 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 734 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 735 | unsigned int val, dmic; | ||
| 736 | u16 mic_sel_reg; | ||
| 737 | u16 dmic_clk_reg; | ||
| 738 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 739 | |||
| 740 | val = ucontrol->value.enumerated.item[0]; | ||
| 741 | |||
| 742 | switch (e->reg) { | ||
| 743 | case CDC_TX_INP_MUX_ADC_MUX0_CFG0: | ||
| 744 | mic_sel_reg = CDC_TX0_TX_PATH_CFG0; | ||
| 745 | break; | ||
| 746 | case CDC_TX_INP_MUX_ADC_MUX1_CFG0: | ||
| 747 | mic_sel_reg = CDC_TX1_TX_PATH_CFG0; | ||
| 748 | break; | ||
| 749 | case CDC_TX_INP_MUX_ADC_MUX2_CFG0: | ||
| 750 | mic_sel_reg = CDC_TX2_TX_PATH_CFG0; | ||
| 751 | break; | ||
| 752 | case CDC_TX_INP_MUX_ADC_MUX3_CFG0: | ||
| 753 | mic_sel_reg = CDC_TX3_TX_PATH_CFG0; | ||
| 754 | break; | ||
| 755 | case CDC_TX_INP_MUX_ADC_MUX4_CFG0: | ||
| 756 | mic_sel_reg = CDC_TX4_TX_PATH_CFG0; | ||
| 757 | break; | ||
| 758 | case CDC_TX_INP_MUX_ADC_MUX5_CFG0: | ||
| 759 | mic_sel_reg = CDC_TX5_TX_PATH_CFG0; | ||
| 760 | break; | ||
| 761 | case CDC_TX_INP_MUX_ADC_MUX6_CFG0: | ||
| 762 | mic_sel_reg = CDC_TX6_TX_PATH_CFG0; | ||
| 763 | break; | ||
| 764 | case CDC_TX_INP_MUX_ADC_MUX7_CFG0: | ||
| 765 | mic_sel_reg = CDC_TX7_TX_PATH_CFG0; | ||
| 766 | break; | ||
| 767 | } | ||
| 768 | |||
| 769 | if (val != 0) { | ||
| 770 | if (val < 5) { | ||
| 771 | snd_soc_component_write_field(component, mic_sel_reg, | ||
| 772 | CDC_TXn_ADC_DMIC_SEL_MASK, 0); | ||
| 773 | } else { | ||
| 774 | snd_soc_component_write_field(component, mic_sel_reg, | ||
| 775 | CDC_TXn_ADC_DMIC_SEL_MASK, 1); | ||
| 776 | dmic = TX_ADC_TO_DMIC(val); | ||
| 777 | dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); | ||
| 778 | snd_soc_component_write_field(component, dmic_clk_reg, | ||
| 779 | CDC_TX_SWR_DMIC_CLK_SEL_MASK, | ||
| 780 | tx->dmic_clk_div); | ||
| 781 | } | ||
| 782 | } | ||
| 783 | |||
| 784 | return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); | ||
| 785 | } | ||
| 786 | |||
| 787 | static int tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol, | ||
| 788 | struct snd_ctl_elem_value *ucontrol) | ||
| 789 | { | ||
| 790 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 791 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 792 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; | ||
| 793 | u32 dai_id = widget->shift; | ||
| 794 | u32 dec_id = mc->shift; | ||
| 795 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 796 | |||
| 797 | if (test_bit(dec_id, &tx->active_ch_mask[dai_id])) | ||
| 798 | ucontrol->value.integer.value[0] = 1; | ||
| 799 | else | ||
| 800 | ucontrol->value.integer.value[0] = 0; | ||
| 801 | |||
| 802 | return 0; | ||
| 803 | } | ||
| 804 | |||
| 805 | static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, | ||
| 806 | struct snd_ctl_elem_value *ucontrol) | ||
| 807 | { | ||
| 808 | struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); | ||
| 809 | struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); | ||
| 810 | struct snd_soc_dapm_update *update = NULL; | ||
| 811 | struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; | ||
| 812 | u32 dai_id = widget->shift; | ||
| 813 | u32 dec_id = mc->shift; | ||
| 814 | u32 enable = ucontrol->value.integer.value[0]; | ||
| 815 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 816 | |||
| 817 | if (enable) { | ||
| 818 | set_bit(dec_id, &tx->active_ch_mask[dai_id]); | ||
| 819 | tx->active_ch_cnt[dai_id]++; | ||
| 820 | tx->active_decimator[dai_id] = dec_id; | ||
| 821 | } else { | ||
| 822 | tx->active_ch_cnt[dai_id]--; | ||
| 823 | clear_bit(dec_id, &tx->active_ch_mask[dai_id]); | ||
| 824 | tx->active_decimator[dai_id] = -1; | ||
| 825 | } | ||
| 826 | snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); | ||
| 827 | |||
| 828 | return 0; | ||
| 829 | } | ||
| 830 | |||
| 831 | static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, | ||
| 832 | struct snd_kcontrol *kcontrol, int event) | ||
| 833 | { | ||
| 834 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 835 | unsigned int decimator; | ||
| 836 | u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg, tx_gain_ctl_reg; | ||
| 837 | u8 hpf_cut_off_freq; | ||
| 838 | int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS; | ||
| 839 | int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS; | ||
| 840 | u16 adc_mux_reg, adc_reg, adc_n, dmic; | ||
| 841 | u16 dmic_clk_reg; | ||
| 842 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 843 | |||
| 844 | decimator = w->shift; | ||
| 845 | tx_vol_ctl_reg = CDC_TXn_TX_PATH_CTL(decimator); | ||
| 846 | hpf_gate_reg = CDC_TXn_TX_PATH_SEC2(decimator); | ||
| 847 | dec_cfg_reg = CDC_TXn_TX_PATH_CFG0(decimator); | ||
| 848 | tx_gain_ctl_reg = CDC_TXn_TX_VOL_CTL(decimator); | ||
| 849 | |||
| 850 | switch (event) { | ||
| 851 | case SND_SOC_DAPM_PRE_PMU: | ||
| 852 | adc_mux_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG1(decimator); | ||
| 853 | if (snd_soc_component_read(component, adc_mux_reg) & SWR_MIC) { | ||
| 854 | adc_reg = CDC_TX_INP_MUX_ADC_MUXn_CFG0(decimator); | ||
| 855 | adc_n = snd_soc_component_read(component, adc_reg) & | ||
| 856 | CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK; | ||
| 857 | if (adc_n >= TX_ADC_MAX) { | ||
| 858 | dmic = TX_ADC_TO_DMIC(adc_n); | ||
| 859 | dmic_clk_reg = CDC_TX_TOP_CSR_SWR_DMICn_CTL(dmic); | ||
| 860 | |||
| 861 | snd_soc_component_write_field(component, dmic_clk_reg, | ||
| 862 | CDC_TX_SWR_DMIC_CLK_SEL_MASK, | ||
| 863 | tx->dmic_clk_div); | ||
| 864 | } | ||
| 865 | } | ||
| 866 | snd_soc_component_write_field(component, dec_cfg_reg, | ||
| 867 | CDC_TXn_ADC_MODE_MASK, | ||
| 868 | tx->dec_mode[decimator]); | ||
| 869 | /* Enable TX PGA Mute */ | ||
| 870 | snd_soc_component_write_field(component, tx_vol_ctl_reg, | ||
| 871 | CDC_TXn_PGA_MUTE_MASK, 0x1); | ||
| 872 | break; | ||
| 873 | case SND_SOC_DAPM_POST_PMU: | ||
| 874 | snd_soc_component_write_field(component, tx_vol_ctl_reg, | ||
| 875 | CDC_TXn_CLK_EN_MASK, 0x1); | ||
| 876 | if (!is_amic_enabled(component, decimator)) { | ||
| 877 | snd_soc_component_update_bits(component, hpf_gate_reg, 0x01, 0x00); | ||
| 878 | /* Minimum 1 clk cycle delay is required as per HW spec */ | ||
| 879 | usleep_range(1000, 1010); | ||
| 880 | } | ||
| 881 | hpf_cut_off_freq = snd_soc_component_read_field(component, dec_cfg_reg, | ||
| 882 | CDC_TXn_HPF_CUT_FREQ_MASK); | ||
| 883 | |||
| 884 | tx->tx_hpf_work[decimator].hpf_cut_off_freq = | ||
| 885 | hpf_cut_off_freq; | ||
| 886 | |||
| 887 | if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) | ||
| 888 | snd_soc_component_write_field(component, dec_cfg_reg, | ||
| 889 | CDC_TXn_HPF_CUT_FREQ_MASK, | ||
| 890 | CF_MIN_3DB_150HZ); | ||
| 891 | |||
| 892 | if (is_amic_enabled(component, decimator)) { | ||
| 893 | hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS; | ||
| 894 | unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS; | ||
| 895 | } | ||
| 896 | /* schedule work queue to Remove Mute */ | ||
| 897 | queue_delayed_work(system_freezable_wq, | ||
| 898 | &tx->tx_mute_dwork[decimator].dwork, | ||
| 899 | msecs_to_jiffies(unmute_delay)); | ||
| 900 | if (tx->tx_hpf_work[decimator].hpf_cut_off_freq != CF_MIN_3DB_150HZ) { | ||
| 901 | queue_delayed_work(system_freezable_wq, | ||
| 902 | &tx->tx_hpf_work[decimator].dwork, | ||
| 903 | msecs_to_jiffies(hpf_delay)); | ||
| 904 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 905 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 906 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 907 | 0x02); | ||
| 908 | if (!is_amic_enabled(component, decimator)) | ||
| 909 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 910 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 911 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 912 | 0x00); | ||
| 913 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 914 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 915 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 916 | 0x01); | ||
| 917 | |||
| 918 | /* | ||
| 919 | * 6ms delay is required as per HW spec | ||
| 920 | */ | ||
| 921 | usleep_range(6000, 6010); | ||
| 922 | } | ||
| 923 | /* apply gain after decimator is enabled */ | ||
| 924 | snd_soc_component_write(component, tx_gain_ctl_reg, | ||
| 925 | snd_soc_component_read(component, | ||
| 926 | tx_gain_ctl_reg)); | ||
| 927 | if (tx->bcs_enable) { | ||
| 928 | snd_soc_component_update_bits(component, dec_cfg_reg, | ||
| 929 | 0x01, 0x01); | ||
| 930 | tx->bcs_clk_en = true; | ||
| 931 | } | ||
| 932 | break; | ||
| 933 | case SND_SOC_DAPM_PRE_PMD: | ||
| 934 | hpf_cut_off_freq = | ||
| 935 | tx->tx_hpf_work[decimator].hpf_cut_off_freq; | ||
| 936 | snd_soc_component_write_field(component, tx_vol_ctl_reg, | ||
| 937 | CDC_TXn_PGA_MUTE_MASK, 0x1); | ||
| 938 | if (cancel_delayed_work_sync( | ||
| 939 | &tx->tx_hpf_work[decimator].dwork)) { | ||
| 940 | if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) { | ||
| 941 | snd_soc_component_write_field( | ||
| 942 | component, dec_cfg_reg, | ||
| 943 | CDC_TXn_HPF_CUT_FREQ_MASK, | ||
| 944 | hpf_cut_off_freq); | ||
| 945 | if (is_amic_enabled(component, decimator)) | ||
| 946 | snd_soc_component_update_bits(component, | ||
| 947 | hpf_gate_reg, | ||
| 948 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 949 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 950 | 0x02); | ||
| 951 | else | ||
| 952 | snd_soc_component_update_bits(component, | ||
| 953 | hpf_gate_reg, | ||
| 954 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 955 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 956 | 0x03); | ||
| 957 | |||
| 958 | /* | ||
| 959 | * Minimum 1 clk cycle delay is required | ||
| 960 | * as per HW spec | ||
| 961 | */ | ||
| 962 | usleep_range(1000, 1010); | ||
| 963 | snd_soc_component_update_bits(component, hpf_gate_reg, | ||
| 964 | CDC_TXn_HPF_F_CHANGE_MASK | | ||
| 965 | CDC_TXn_HPF_ZERO_GATE_MASK, | ||
| 966 | 0x1); | ||
| 967 | } | ||
| 968 | } | ||
| 969 | cancel_delayed_work_sync(&tx->tx_mute_dwork[decimator].dwork); | ||
| 970 | break; | ||
| 971 | case SND_SOC_DAPM_POST_PMD: | ||
| 972 | snd_soc_component_write_field(component, tx_vol_ctl_reg, | ||
| 973 | CDC_TXn_CLK_EN_MASK, 0x0); | ||
| 974 | snd_soc_component_write_field(component, dec_cfg_reg, | ||
| 975 | CDC_TXn_ADC_MODE_MASK, 0x0); | ||
| 976 | snd_soc_component_write_field(component, tx_vol_ctl_reg, | ||
| 977 | CDC_TXn_PGA_MUTE_MASK, 0x0); | ||
| 978 | if (tx->bcs_enable) { | ||
| 979 | snd_soc_component_write_field(component, dec_cfg_reg, | ||
| 980 | CDC_TXn_PH_EN_MASK, 0x0); | ||
| 981 | snd_soc_component_write_field(component, | ||
| 982 | CDC_TX0_TX_PATH_SEC7, | ||
| 983 | CDC_TX0_MBHC_CTL_EN_MASK, | ||
| 984 | 0x0); | ||
| 985 | tx->bcs_clk_en = false; | ||
| 986 | } | ||
| 987 | break; | ||
| 988 | } | ||
| 989 | return 0; | ||
| 990 | } | ||
| 991 | |||
| 992 | static int tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol, | ||
| 993 | struct snd_ctl_elem_value *ucontrol) | ||
| 994 | { | ||
| 995 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 996 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 997 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 998 | int path = e->shift_l; | ||
| 999 | |||
| 1000 | ucontrol->value.integer.value[0] = tx->dec_mode[path]; | ||
| 1001 | |||
| 1002 | return 0; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, | ||
| 1006 | struct snd_ctl_elem_value *ucontrol) | ||
| 1007 | { | ||
| 1008 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 1009 | int value = ucontrol->value.integer.value[0]; | ||
| 1010 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
| 1011 | int path = e->shift_l; | ||
| 1012 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1013 | |||
| 1014 | tx->dec_mode[path] = value; | ||
| 1015 | |||
| 1016 | return 0; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, | ||
| 1020 | struct snd_ctl_elem_value *ucontrol) | ||
| 1021 | { | ||
| 1022 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 1023 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1024 | |||
| 1025 | ucontrol->value.integer.value[0] = tx->bcs_enable; | ||
| 1026 | |||
| 1027 | return 0; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | static int tx_macro_set_bcs(struct snd_kcontrol *kcontrol, | ||
| 1031 | struct snd_ctl_elem_value *ucontrol) | ||
| 1032 | { | ||
| 1033 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); | ||
| 1034 | int value = ucontrol->value.integer.value[0]; | ||
| 1035 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1036 | |||
| 1037 | tx->bcs_enable = value; | ||
| 1038 | |||
| 1039 | return 0; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | static int tx_macro_hw_params(struct snd_pcm_substream *substream, | ||
| 1043 | struct snd_pcm_hw_params *params, | ||
| 1044 | struct snd_soc_dai *dai) | ||
| 1045 | { | ||
| 1046 | struct snd_soc_component *component = dai->component; | ||
| 1047 | u32 decimator, sample_rate; | ||
| 1048 | int tx_fs_rate; | ||
| 1049 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1050 | |||
| 1051 | sample_rate = params_rate(params); | ||
| 1052 | switch (sample_rate) { | ||
| 1053 | case 8000: | ||
| 1054 | tx_fs_rate = 0; | ||
| 1055 | break; | ||
| 1056 | case 16000: | ||
| 1057 | tx_fs_rate = 1; | ||
| 1058 | break; | ||
| 1059 | case 32000: | ||
| 1060 | tx_fs_rate = 3; | ||
| 1061 | break; | ||
| 1062 | case 48000: | ||
| 1063 | tx_fs_rate = 4; | ||
| 1064 | break; | ||
| 1065 | case 96000: | ||
| 1066 | tx_fs_rate = 5; | ||
| 1067 | break; | ||
| 1068 | case 192000: | ||
| 1069 | tx_fs_rate = 6; | ||
| 1070 | break; | ||
| 1071 | case 384000: | ||
| 1072 | tx_fs_rate = 7; | ||
| 1073 | break; | ||
| 1074 | default: | ||
| 1075 | dev_err(component->dev, "%s: Invalid TX sample rate: %d\n", | ||
| 1076 | __func__, params_rate(params)); | ||
| 1077 | return -EINVAL; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | for_each_set_bit(decimator, &tx->active_ch_mask[dai->id], TX_MACRO_DEC_MAX) | ||
| 1081 | snd_soc_component_update_bits(component, CDC_TXn_TX_PATH_CTL(decimator), | ||
| 1082 | CDC_TXn_PCM_RATE_MASK, | ||
| 1083 | tx_fs_rate); | ||
| 1084 | return 0; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | static int tx_macro_get_channel_map(struct snd_soc_dai *dai, | ||
| 1088 | unsigned int *tx_num, unsigned int *tx_slot, | ||
| 1089 | unsigned int *rx_num, unsigned int *rx_slot) | ||
| 1090 | { | ||
| 1091 | struct snd_soc_component *component = dai->component; | ||
| 1092 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1093 | |||
| 1094 | switch (dai->id) { | ||
| 1095 | case TX_MACRO_AIF1_CAP: | ||
| 1096 | case TX_MACRO_AIF2_CAP: | ||
| 1097 | case TX_MACRO_AIF3_CAP: | ||
| 1098 | *tx_slot = tx->active_ch_mask[dai->id]; | ||
| 1099 | *tx_num = tx->active_ch_cnt[dai->id]; | ||
| 1100 | break; | ||
| 1101 | default: | ||
| 1102 | break; | ||
| 1103 | } | ||
| 1104 | return 0; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | static int tx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) | ||
| 1108 | { | ||
| 1109 | struct snd_soc_component *component = dai->component; | ||
| 1110 | struct tx_macro *tx = snd_soc_component_get_drvdata(component); | ||
| 1111 | u16 decimator; | ||
| 1112 | |||
| 1113 | decimator = tx->active_decimator[dai->id]; | ||
| 1114 | |||
| 1115 | if (mute) | ||
| 1116 | snd_soc_component_write_field(component, | ||
| 1117 | CDC_TXn_TX_PATH_CTL(decimator), | ||
| 1118 | CDC_TXn_PGA_MUTE_MASK, 0x1); | ||
| 1119 | else | ||
| 1120 | snd_soc_component_update_bits(component, | ||
| 1121 | CDC_TXn_TX_PATH_CTL(decimator), | ||
| 1122 | CDC_TXn_PGA_MUTE_MASK, 0x0); | ||
| 1123 | |||
| 1124 | return 0; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | static struct snd_soc_dai_ops tx_macro_dai_ops = { | ||
| 1128 | .hw_params = tx_macro_hw_params, | ||
| 1129 | .get_channel_map = tx_macro_get_channel_map, | ||
| 1130 | .mute_stream = tx_macro_digital_mute, | ||
| 1131 | }; | ||
| 1132 | |||
| 1133 | static struct snd_soc_dai_driver tx_macro_dai[] = { | ||
| 1134 | { | ||
| 1135 | .name = "tx_macro_tx1", | ||
| 1136 | .id = TX_MACRO_AIF1_CAP, | ||
| 1137 | .capture = { | ||
| 1138 | .stream_name = "TX_AIF1 Capture", | ||
| 1139 | .rates = TX_MACRO_RATES, | ||
| 1140 | .formats = TX_MACRO_FORMATS, | ||
| 1141 | .rate_max = 192000, | ||
| 1142 | .rate_min = 8000, | ||
| 1143 | .channels_min = 1, | ||
| 1144 | .channels_max = 8, | ||
| 1145 | }, | ||
| 1146 | .ops = &tx_macro_dai_ops, | ||
| 1147 | }, | ||
| 1148 | { | ||
| 1149 | .name = "tx_macro_tx2", | ||
| 1150 | .id = TX_MACRO_AIF2_CAP, | ||
| 1151 | .capture = { | ||
| 1152 | .stream_name = "TX_AIF2 Capture", | ||
| 1153 | .rates = TX_MACRO_RATES, | ||
| 1154 | .formats = TX_MACRO_FORMATS, | ||
| 1155 | .rate_max = 192000, | ||
| 1156 | .rate_min = 8000, | ||
| 1157 | .channels_min = 1, | ||
| 1158 | .channels_max = 8, | ||
| 1159 | }, | ||
| 1160 | .ops = &tx_macro_dai_ops, | ||
| 1161 | }, | ||
| 1162 | { | ||
| 1163 | .name = "tx_macro_tx3", | ||
| 1164 | .id = TX_MACRO_AIF3_CAP, | ||
| 1165 | .capture = { | ||
| 1166 | .stream_name = "TX_AIF3 Capture", | ||
| 1167 | .rates = TX_MACRO_RATES, | ||
| 1168 | .formats = TX_MACRO_FORMATS, | ||
| 1169 | .rate_max = 192000, | ||
| 1170 | .rate_min = 8000, | ||
| 1171 | .channels_min = 1, | ||
| 1172 | .channels_max = 8, | ||
| 1173 | }, | ||
| 1174 | .ops = &tx_macro_dai_ops, | ||
| 1175 | }, | ||
| 1176 | }; | ||
| 1177 | |||
| 1178 | static const char * const adc_mux_text[] = { | ||
| 1179 | "MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1" | ||
| 1180 | }; | ||
| 1181 | |||
| 1182 | static SOC_ENUM_SINGLE_DECL(tx_dec0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG1, | ||
| 1183 | 0, adc_mux_text); | ||
| 1184 | static SOC_ENUM_SINGLE_DECL(tx_dec1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG1, | ||
| 1185 | 0, adc_mux_text); | ||
| 1186 | static SOC_ENUM_SINGLE_DECL(tx_dec2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG1, | ||
| 1187 | 0, adc_mux_text); | ||
| 1188 | static SOC_ENUM_SINGLE_DECL(tx_dec3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG1, | ||
| 1189 | 0, adc_mux_text); | ||
| 1190 | static SOC_ENUM_SINGLE_DECL(tx_dec4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG1, | ||
| 1191 | 0, adc_mux_text); | ||
| 1192 | static SOC_ENUM_SINGLE_DECL(tx_dec5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG1, | ||
| 1193 | 0, adc_mux_text); | ||
| 1194 | static SOC_ENUM_SINGLE_DECL(tx_dec6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG1, | ||
| 1195 | 0, adc_mux_text); | ||
| 1196 | static SOC_ENUM_SINGLE_DECL(tx_dec7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG1, | ||
| 1197 | 0, adc_mux_text); | ||
| 1198 | |||
| 1199 | static const struct snd_kcontrol_new tx_dec0_mux = SOC_DAPM_ENUM("tx_dec0", tx_dec0_enum); | ||
| 1200 | static const struct snd_kcontrol_new tx_dec1_mux = SOC_DAPM_ENUM("tx_dec1", tx_dec1_enum); | ||
| 1201 | static const struct snd_kcontrol_new tx_dec2_mux = SOC_DAPM_ENUM("tx_dec2", tx_dec2_enum); | ||
| 1202 | static const struct snd_kcontrol_new tx_dec3_mux = SOC_DAPM_ENUM("tx_dec3", tx_dec3_enum); | ||
| 1203 | static const struct snd_kcontrol_new tx_dec4_mux = SOC_DAPM_ENUM("tx_dec4", tx_dec4_enum); | ||
| 1204 | static const struct snd_kcontrol_new tx_dec5_mux = SOC_DAPM_ENUM("tx_dec5", tx_dec5_enum); | ||
| 1205 | static const struct snd_kcontrol_new tx_dec6_mux = SOC_DAPM_ENUM("tx_dec6", tx_dec6_enum); | ||
| 1206 | static const struct snd_kcontrol_new tx_dec7_mux = SOC_DAPM_ENUM("tx_dec7", tx_dec7_enum); | ||
| 1207 | |||
| 1208 | static const char * const smic_mux_text[] = { | ||
| 1209 | "ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0", | ||
| 1210 | "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4", | ||
| 1211 | "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7" | ||
| 1212 | }; | ||
| 1213 | |||
| 1214 | static SOC_ENUM_SINGLE_DECL(tx_smic0_enum, CDC_TX_INP_MUX_ADC_MUX0_CFG0, | ||
| 1215 | 0, smic_mux_text); | ||
| 1216 | |||
| 1217 | static SOC_ENUM_SINGLE_DECL(tx_smic1_enum, CDC_TX_INP_MUX_ADC_MUX1_CFG0, | ||
| 1218 | 0, smic_mux_text); | ||
| 1219 | |||
| 1220 | static SOC_ENUM_SINGLE_DECL(tx_smic2_enum, CDC_TX_INP_MUX_ADC_MUX2_CFG0, | ||
| 1221 | 0, smic_mux_text); | ||
| 1222 | |||
| 1223 | static SOC_ENUM_SINGLE_DECL(tx_smic3_enum, CDC_TX_INP_MUX_ADC_MUX3_CFG0, | ||
| 1224 | 0, smic_mux_text); | ||
| 1225 | |||
| 1226 | static SOC_ENUM_SINGLE_DECL(tx_smic4_enum, CDC_TX_INP_MUX_ADC_MUX4_CFG0, | ||
| 1227 | 0, smic_mux_text); | ||
| 1228 | |||
| 1229 | static SOC_ENUM_SINGLE_DECL(tx_smic5_enum, CDC_TX_INP_MUX_ADC_MUX5_CFG0, | ||
| 1230 | 0, smic_mux_text); | ||
| 1231 | |||
| 1232 | static SOC_ENUM_SINGLE_DECL(tx_smic6_enum, CDC_TX_INP_MUX_ADC_MUX6_CFG0, | ||
| 1233 | 0, smic_mux_text); | ||
| 1234 | |||
| 1235 | static SOC_ENUM_SINGLE_DECL(tx_smic7_enum, CDC_TX_INP_MUX_ADC_MUX7_CFG0, | ||
| 1236 | 0, smic_mux_text); | ||
| 1237 | |||
| 1238 | static const struct snd_kcontrol_new tx_smic0_mux = SOC_DAPM_ENUM_EXT("tx_smic0", tx_smic0_enum, | ||
| 1239 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1240 | static const struct snd_kcontrol_new tx_smic1_mux = SOC_DAPM_ENUM_EXT("tx_smic1", tx_smic1_enum, | ||
| 1241 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1242 | static const struct snd_kcontrol_new tx_smic2_mux = SOC_DAPM_ENUM_EXT("tx_smic2", tx_smic2_enum, | ||
| 1243 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1244 | static const struct snd_kcontrol_new tx_smic3_mux = SOC_DAPM_ENUM_EXT("tx_smic3", tx_smic3_enum, | ||
| 1245 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1246 | static const struct snd_kcontrol_new tx_smic4_mux = SOC_DAPM_ENUM_EXT("tx_smic4", tx_smic4_enum, | ||
| 1247 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1248 | static const struct snd_kcontrol_new tx_smic5_mux = SOC_DAPM_ENUM_EXT("tx_smic5", tx_smic5_enum, | ||
| 1249 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1250 | static const struct snd_kcontrol_new tx_smic6_mux = SOC_DAPM_ENUM_EXT("tx_smic6", tx_smic6_enum, | ||
| 1251 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1252 | static const struct snd_kcontrol_new tx_smic7_mux = SOC_DAPM_ENUM_EXT("tx_smic7", tx_smic7_enum, | ||
| 1253 | snd_soc_dapm_get_enum_double, tx_macro_put_dec_enum); | ||
| 1254 | |||
| 1255 | static const char * const dec_mode_mux_text[] = { | ||
| 1256 | "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF", | ||
| 1257 | }; | ||
| 1258 | |||
| 1259 | static const struct soc_enum dec_mode_mux_enum[] = { | ||
| 1260 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1261 | dec_mode_mux_text), | ||
| 1262 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1263 | dec_mode_mux_text), | ||
| 1264 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1265 | dec_mode_mux_text), | ||
| 1266 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1267 | dec_mode_mux_text), | ||
| 1268 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 4, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1269 | dec_mode_mux_text), | ||
| 1270 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 5, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1271 | dec_mode_mux_text), | ||
| 1272 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 6, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1273 | dec_mode_mux_text), | ||
| 1274 | SOC_ENUM_SINGLE(SND_SOC_NOPM, 7, ARRAY_SIZE(dec_mode_mux_text), | ||
| 1275 | dec_mode_mux_text), | ||
| 1276 | }; | ||
| 1277 | |||
| 1278 | static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = { | ||
| 1279 | SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, | ||
| 1280 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1281 | SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, | ||
| 1282 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1283 | SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, | ||
| 1284 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1285 | SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, | ||
| 1286 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1287 | SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, | ||
| 1288 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1289 | SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, | ||
| 1290 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1291 | SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, | ||
| 1292 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1293 | SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, | ||
| 1294 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1295 | }; | ||
| 1296 | |||
| 1297 | static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = { | ||
| 1298 | SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, | ||
| 1299 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1300 | SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, | ||
| 1301 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1302 | SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, | ||
| 1303 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1304 | SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, | ||
| 1305 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1306 | SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, | ||
| 1307 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1308 | SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, | ||
| 1309 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1310 | SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, | ||
| 1311 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1312 | SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, | ||
| 1313 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1314 | }; | ||
| 1315 | |||
| 1316 | static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = { | ||
| 1317 | SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0, | ||
| 1318 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1319 | SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0, | ||
| 1320 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1321 | SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0, | ||
| 1322 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1323 | SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0, | ||
| 1324 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1325 | SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, TX_MACRO_DEC4, 1, 0, | ||
| 1326 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1327 | SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, TX_MACRO_DEC5, 1, 0, | ||
| 1328 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1329 | SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, TX_MACRO_DEC6, 1, 0, | ||
| 1330 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1331 | SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, TX_MACRO_DEC7, 1, 0, | ||
| 1332 | tx_macro_tx_mixer_get, tx_macro_tx_mixer_put), | ||
| 1333 | }; | ||
| 1334 | |||
| 1335 | static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = { | ||
| 1336 | SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0, | ||
| 1337 | SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0), | ||
| 1338 | |||
| 1339 | SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0, | ||
| 1340 | SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0), | ||
| 1341 | |||
| 1342 | SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0, | ||
| 1343 | SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0), | ||
| 1344 | |||
| 1345 | SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0, | ||
| 1346 | tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)), | ||
| 1347 | |||
| 1348 | SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0, | ||
| 1349 | tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)), | ||
| 1350 | |||
| 1351 | SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0, | ||
| 1352 | tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)), | ||
| 1353 | |||
| 1354 | SND_SOC_DAPM_MUX("TX SMIC MUX0", SND_SOC_NOPM, 0, 0, &tx_smic0_mux), | ||
| 1355 | SND_SOC_DAPM_MUX("TX SMIC MUX1", SND_SOC_NOPM, 0, 0, &tx_smic1_mux), | ||
| 1356 | SND_SOC_DAPM_MUX("TX SMIC MUX2", SND_SOC_NOPM, 0, 0, &tx_smic2_mux), | ||
| 1357 | SND_SOC_DAPM_MUX("TX SMIC MUX3", SND_SOC_NOPM, 0, 0, &tx_smic3_mux), | ||
| 1358 | SND_SOC_DAPM_MUX("TX SMIC MUX4", SND_SOC_NOPM, 0, 0, &tx_smic4_mux), | ||
| 1359 | SND_SOC_DAPM_MUX("TX SMIC MUX5", SND_SOC_NOPM, 0, 0, &tx_smic5_mux), | ||
| 1360 | SND_SOC_DAPM_MUX("TX SMIC MUX6", SND_SOC_NOPM, 0, 0, &tx_smic6_mux), | ||
| 1361 | SND_SOC_DAPM_MUX("TX SMIC MUX7", SND_SOC_NOPM, 0, 0, &tx_smic7_mux), | ||
| 1362 | |||
| 1363 | SND_SOC_DAPM_INPUT("TX SWR_ADC0"), | ||
| 1364 | SND_SOC_DAPM_INPUT("TX SWR_ADC1"), | ||
| 1365 | SND_SOC_DAPM_INPUT("TX SWR_ADC2"), | ||
| 1366 | SND_SOC_DAPM_INPUT("TX SWR_ADC3"), | ||
| 1367 | SND_SOC_DAPM_INPUT("TX SWR_DMIC0"), | ||
| 1368 | SND_SOC_DAPM_INPUT("TX SWR_DMIC1"), | ||
| 1369 | SND_SOC_DAPM_INPUT("TX SWR_DMIC2"), | ||
| 1370 | SND_SOC_DAPM_INPUT("TX SWR_DMIC3"), | ||
| 1371 | SND_SOC_DAPM_INPUT("TX SWR_DMIC4"), | ||
| 1372 | SND_SOC_DAPM_INPUT("TX SWR_DMIC5"), | ||
| 1373 | SND_SOC_DAPM_INPUT("TX SWR_DMIC6"), | ||
| 1374 | SND_SOC_DAPM_INPUT("TX SWR_DMIC7"), | ||
| 1375 | |||
| 1376 | SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM, | ||
| 1377 | TX_MACRO_DEC0, 0, | ||
| 1378 | &tx_dec0_mux, tx_macro_enable_dec, | ||
| 1379 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1380 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1381 | |||
| 1382 | SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM, | ||
| 1383 | TX_MACRO_DEC1, 0, | ||
| 1384 | &tx_dec1_mux, tx_macro_enable_dec, | ||
| 1385 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1386 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1387 | |||
| 1388 | SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM, | ||
| 1389 | TX_MACRO_DEC2, 0, | ||
| 1390 | &tx_dec2_mux, tx_macro_enable_dec, | ||
| 1391 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1392 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1393 | |||
| 1394 | SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM, | ||
| 1395 | TX_MACRO_DEC3, 0, | ||
| 1396 | &tx_dec3_mux, tx_macro_enable_dec, | ||
| 1397 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1398 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1399 | |||
| 1400 | SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM, | ||
| 1401 | TX_MACRO_DEC4, 0, | ||
| 1402 | &tx_dec4_mux, tx_macro_enable_dec, | ||
| 1403 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1404 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1405 | |||
| 1406 | SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM, | ||
| 1407 | TX_MACRO_DEC5, 0, | ||
| 1408 | &tx_dec5_mux, tx_macro_enable_dec, | ||
| 1409 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1410 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1411 | |||
| 1412 | SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM, | ||
| 1413 | TX_MACRO_DEC6, 0, | ||
| 1414 | &tx_dec6_mux, tx_macro_enable_dec, | ||
| 1415 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1416 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1417 | |||
| 1418 | SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM, | ||
| 1419 | TX_MACRO_DEC7, 0, | ||
| 1420 | &tx_dec7_mux, tx_macro_enable_dec, | ||
| 1421 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||
| 1422 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), | ||
| 1423 | |||
| 1424 | SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0, | ||
| 1425 | tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 1426 | |||
| 1427 | SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 1428 | |||
| 1429 | SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, | ||
| 1430 | NULL, 0), | ||
| 1431 | }; | ||
| 1432 | |||
| 1433 | static const struct snd_soc_dapm_route tx_audio_map[] = { | ||
| 1434 | {"TX_AIF1 CAP", NULL, "TX_MCLK"}, | ||
| 1435 | {"TX_AIF2 CAP", NULL, "TX_MCLK"}, | ||
| 1436 | {"TX_AIF3 CAP", NULL, "TX_MCLK"}, | ||
| 1437 | |||
| 1438 | {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"}, | ||
| 1439 | {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"}, | ||
| 1440 | {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"}, | ||
| 1441 | |||
| 1442 | {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"}, | ||
| 1443 | {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"}, | ||
| 1444 | {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"}, | ||
| 1445 | {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"}, | ||
| 1446 | {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"}, | ||
| 1447 | {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"}, | ||
| 1448 | {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"}, | ||
| 1449 | {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"}, | ||
| 1450 | |||
| 1451 | {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"}, | ||
| 1452 | {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"}, | ||
| 1453 | {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"}, | ||
| 1454 | {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"}, | ||
| 1455 | {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"}, | ||
| 1456 | {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"}, | ||
| 1457 | {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"}, | ||
| 1458 | {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"}, | ||
| 1459 | |||
| 1460 | {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"}, | ||
| 1461 | {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"}, | ||
| 1462 | {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"}, | ||
| 1463 | {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"}, | ||
| 1464 | {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"}, | ||
| 1465 | {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"}, | ||
| 1466 | {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"}, | ||
| 1467 | {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"}, | ||
| 1468 | |||
| 1469 | {"TX DEC0 MUX", NULL, "TX_MCLK"}, | ||
| 1470 | {"TX DEC1 MUX", NULL, "TX_MCLK"}, | ||
| 1471 | {"TX DEC2 MUX", NULL, "TX_MCLK"}, | ||
| 1472 | {"TX DEC3 MUX", NULL, "TX_MCLK"}, | ||
| 1473 | {"TX DEC4 MUX", NULL, "TX_MCLK"}, | ||
| 1474 | {"TX DEC5 MUX", NULL, "TX_MCLK"}, | ||
| 1475 | {"TX DEC6 MUX", NULL, "TX_MCLK"}, | ||
| 1476 | {"TX DEC7 MUX", NULL, "TX_MCLK"}, | ||
| 1477 | |||
| 1478 | {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"}, | ||
| 1479 | {"TX SMIC MUX0", NULL, "TX_SWR_CLK"}, | ||
| 1480 | {"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"}, | ||
| 1481 | {"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"}, | ||
| 1482 | {"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"}, | ||
| 1483 | {"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"}, | ||
| 1484 | {"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1485 | {"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1486 | {"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1487 | {"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1488 | {"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1489 | {"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1490 | {"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1491 | {"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1492 | |||
| 1493 | {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"}, | ||
| 1494 | {"TX SMIC MUX1", NULL, "TX_SWR_CLK"}, | ||
| 1495 | {"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"}, | ||
| 1496 | {"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"}, | ||
| 1497 | {"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"}, | ||
| 1498 | {"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"}, | ||
| 1499 | {"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1500 | {"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1501 | {"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1502 | {"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1503 | {"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1504 | {"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1505 | {"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1506 | {"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1507 | |||
| 1508 | {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"}, | ||
| 1509 | {"TX SMIC MUX2", NULL, "TX_SWR_CLK"}, | ||
| 1510 | {"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"}, | ||
| 1511 | {"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"}, | ||
| 1512 | {"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"}, | ||
| 1513 | {"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"}, | ||
| 1514 | {"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1515 | {"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1516 | {"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1517 | {"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1518 | {"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1519 | {"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1520 | {"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1521 | {"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1522 | |||
| 1523 | {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"}, | ||
| 1524 | {"TX SMIC MUX3", NULL, "TX_SWR_CLK"}, | ||
| 1525 | {"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"}, | ||
| 1526 | {"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"}, | ||
| 1527 | {"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"}, | ||
| 1528 | {"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"}, | ||
| 1529 | {"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1530 | {"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1531 | {"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1532 | {"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1533 | {"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1534 | {"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1535 | {"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1536 | {"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1537 | |||
| 1538 | {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"}, | ||
| 1539 | {"TX SMIC MUX4", NULL, "TX_SWR_CLK"}, | ||
| 1540 | {"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"}, | ||
| 1541 | {"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"}, | ||
| 1542 | {"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"}, | ||
| 1543 | {"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"}, | ||
| 1544 | {"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1545 | {"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1546 | {"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1547 | {"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1548 | {"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1549 | {"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1550 | {"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1551 | {"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1552 | |||
| 1553 | {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"}, | ||
| 1554 | {"TX SMIC MUX5", NULL, "TX_SWR_CLK"}, | ||
| 1555 | {"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"}, | ||
| 1556 | {"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"}, | ||
| 1557 | {"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"}, | ||
| 1558 | {"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"}, | ||
| 1559 | {"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1560 | {"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1561 | {"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1562 | {"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1563 | {"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1564 | {"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1565 | {"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1566 | {"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1567 | |||
| 1568 | {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"}, | ||
| 1569 | {"TX SMIC MUX6", NULL, "TX_SWR_CLK"}, | ||
| 1570 | {"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"}, | ||
| 1571 | {"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"}, | ||
| 1572 | {"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"}, | ||
| 1573 | {"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"}, | ||
| 1574 | {"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1575 | {"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1576 | {"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1577 | {"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1578 | {"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1579 | {"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1580 | {"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1581 | {"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1582 | |||
| 1583 | {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"}, | ||
| 1584 | {"TX SMIC MUX7", NULL, "TX_SWR_CLK"}, | ||
| 1585 | {"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"}, | ||
| 1586 | {"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"}, | ||
| 1587 | {"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"}, | ||
| 1588 | {"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"}, | ||
| 1589 | {"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"}, | ||
| 1590 | {"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"}, | ||
| 1591 | {"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"}, | ||
| 1592 | {"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"}, | ||
| 1593 | {"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"}, | ||
| 1594 | {"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"}, | ||
| 1595 | {"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"}, | ||
| 1596 | {"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"}, | ||
| 1597 | }; | ||
| 1598 | |||
| 1599 | static const struct snd_kcontrol_new tx_macro_snd_controls[] = { | ||
| 1600 | SOC_SINGLE_S8_TLV("TX_DEC0 Volume", | ||
| 1601 | CDC_TX0_TX_VOL_CTL, | ||
| 1602 | -84, 40, digital_gain), | ||
| 1603 | SOC_SINGLE_S8_TLV("TX_DEC1 Volume", | ||
| 1604 | CDC_TX1_TX_VOL_CTL, | ||
| 1605 | -84, 40, digital_gain), | ||
| 1606 | SOC_SINGLE_S8_TLV("TX_DEC2 Volume", | ||
| 1607 | CDC_TX2_TX_VOL_CTL, | ||
| 1608 | -84, 40, digital_gain), | ||
| 1609 | SOC_SINGLE_S8_TLV("TX_DEC3 Volume", | ||
| 1610 | CDC_TX3_TX_VOL_CTL, | ||
| 1611 | -84, 40, digital_gain), | ||
| 1612 | SOC_SINGLE_S8_TLV("TX_DEC4 Volume", | ||
| 1613 | CDC_TX4_TX_VOL_CTL, | ||
| 1614 | -84, 40, digital_gain), | ||
| 1615 | SOC_SINGLE_S8_TLV("TX_DEC5 Volume", | ||
| 1616 | CDC_TX5_TX_VOL_CTL, | ||
| 1617 | -84, 40, digital_gain), | ||
| 1618 | SOC_SINGLE_S8_TLV("TX_DEC6 Volume", | ||
| 1619 | CDC_TX6_TX_VOL_CTL, | ||
| 1620 | -84, 40, digital_gain), | ||
| 1621 | SOC_SINGLE_S8_TLV("TX_DEC7 Volume", | ||
| 1622 | CDC_TX7_TX_VOL_CTL, | ||
| 1623 | -84, 40, digital_gain), | ||
| 1624 | |||
| 1625 | SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum[0], | ||
| 1626 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1627 | |||
| 1628 | SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum[1], | ||
| 1629 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1630 | |||
| 1631 | SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum[2], | ||
| 1632 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1633 | |||
| 1634 | SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum[3], | ||
| 1635 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1636 | |||
| 1637 | SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum[4], | ||
| 1638 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1639 | |||
| 1640 | SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum[5], | ||
| 1641 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1642 | |||
| 1643 | SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum[6], | ||
| 1644 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1645 | |||
| 1646 | SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum[7], | ||
| 1647 | tx_macro_dec_mode_get, tx_macro_dec_mode_put), | ||
| 1648 | |||
| 1649 | SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0, | ||
| 1650 | tx_macro_get_bcs, tx_macro_set_bcs), | ||
| 1651 | }; | ||
| 1652 | |||
| 1653 | static int tx_macro_component_probe(struct snd_soc_component *comp) | ||
| 1654 | { | ||
| 1655 | struct tx_macro *tx = snd_soc_component_get_drvdata(comp); | ||
| 1656 | int i; | ||
| 1657 | |||
| 1658 | snd_soc_component_init_regmap(comp, tx->regmap); | ||
| 1659 | |||
| 1660 | for (i = 0; i < NUM_DECIMATORS; i++) { | ||
| 1661 | tx->tx_hpf_work[i].tx = tx; | ||
| 1662 | tx->tx_hpf_work[i].decimator = i; | ||
| 1663 | INIT_DELAYED_WORK(&tx->tx_hpf_work[i].dwork, | ||
| 1664 | tx_macro_tx_hpf_corner_freq_callback); | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | for (i = 0; i < NUM_DECIMATORS; i++) { | ||
| 1668 | tx->tx_mute_dwork[i].tx = tx; | ||
| 1669 | tx->tx_mute_dwork[i].decimator = i; | ||
| 1670 | INIT_DELAYED_WORK(&tx->tx_mute_dwork[i].dwork, | ||
| 1671 | tx_macro_mute_update_callback); | ||
| 1672 | } | ||
| 1673 | tx->component = comp; | ||
| 1674 | |||
| 1675 | snd_soc_component_update_bits(comp, CDC_TX0_TX_PATH_SEC7, 0x3F, | ||
| 1676 | 0x0A); | ||
| 1677 | |||
| 1678 | return 0; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | static int swclk_gate_enable(struct clk_hw *hw) | ||
| 1682 | { | ||
| 1683 | struct tx_macro *tx = to_tx_macro(hw); | ||
| 1684 | struct regmap *regmap = tx->regmap; | ||
| 1685 | |||
| 1686 | tx_macro_mclk_enable(tx, true); | ||
| 1687 | if (tx->reset_swr) | ||
| 1688 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 1689 | CDC_TX_SWR_RESET_MASK, | ||
| 1690 | CDC_TX_SWR_RESET_ENABLE); | ||
| 1691 | |||
| 1692 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 1693 | CDC_TX_SWR_CLK_EN_MASK, | ||
| 1694 | CDC_TX_SWR_CLK_ENABLE); | ||
| 1695 | if (tx->reset_swr) | ||
| 1696 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 1697 | CDC_TX_SWR_RESET_MASK, 0x0); | ||
| 1698 | tx->reset_swr = false; | ||
| 1699 | |||
| 1700 | return 0; | ||
| 1701 | } | ||
| 1702 | |||
| 1703 | static void swclk_gate_disable(struct clk_hw *hw) | ||
| 1704 | { | ||
| 1705 | struct tx_macro *tx = to_tx_macro(hw); | ||
| 1706 | struct regmap *regmap = tx->regmap; | ||
| 1707 | |||
| 1708 | regmap_update_bits(regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, | ||
| 1709 | CDC_TX_SWR_CLK_EN_MASK, 0x0); | ||
| 1710 | |||
| 1711 | tx_macro_mclk_enable(tx, false); | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | static int swclk_gate_is_enabled(struct clk_hw *hw) | ||
| 1715 | { | ||
| 1716 | struct tx_macro *tx = to_tx_macro(hw); | ||
| 1717 | int ret, val; | ||
| 1718 | |||
| 1719 | regmap_read(tx->regmap, CDC_TX_CLK_RST_CTRL_SWR_CONTROL, &val); | ||
| 1720 | ret = val & BIT(0); | ||
| 1721 | |||
| 1722 | return ret; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | static unsigned long swclk_recalc_rate(struct clk_hw *hw, | ||
| 1726 | unsigned long parent_rate) | ||
| 1727 | { | ||
| 1728 | return parent_rate / 2; | ||
| 1729 | } | ||
| 1730 | |||
| 1731 | static const struct clk_ops swclk_gate_ops = { | ||
| 1732 | .prepare = swclk_gate_enable, | ||
| 1733 | .unprepare = swclk_gate_disable, | ||
| 1734 | .is_enabled = swclk_gate_is_enabled, | ||
| 1735 | .recalc_rate = swclk_recalc_rate, | ||
| 1736 | |||
| 1737 | }; | ||
| 1738 | |||
| 1739 | static struct clk *tx_macro_register_mclk_output(struct tx_macro *tx) | ||
| 1740 | { | ||
| 1741 | struct device *dev = tx->dev; | ||
| 1742 | struct device_node *np = dev->of_node; | ||
| 1743 | const char *parent_clk_name = NULL; | ||
| 1744 | const char *clk_name = "lpass-tx-mclk"; | ||
| 1745 | struct clk_hw *hw; | ||
| 1746 | struct clk_init_data init; | ||
| 1747 | int ret; | ||
| 1748 | |||
| 1749 | parent_clk_name = __clk_get_name(tx->clks[2].clk); | ||
| 1750 | |||
| 1751 | init.name = clk_name; | ||
| 1752 | init.ops = &swclk_gate_ops; | ||
| 1753 | init.flags = 0; | ||
| 1754 | init.parent_names = &parent_clk_name; | ||
| 1755 | init.num_parents = 1; | ||
| 1756 | tx->hw.init = &init; | ||
| 1757 | hw = &tx->hw; | ||
| 1758 | ret = clk_hw_register(tx->dev, hw); | ||
| 1759 | if (ret) | ||
| 1760 | return ERR_PTR(ret); | ||
| 1761 | |||
| 1762 | of_clk_add_provider(np, of_clk_src_simple_get, hw->clk); | ||
| 1763 | |||
| 1764 | return NULL; | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | static const struct snd_soc_component_driver tx_macro_component_drv = { | ||
| 1768 | .name = "RX-MACRO", | ||
| 1769 | .probe = tx_macro_component_probe, | ||
| 1770 | .controls = tx_macro_snd_controls, | ||
| 1771 | .num_controls = ARRAY_SIZE(tx_macro_snd_controls), | ||
| 1772 | .dapm_widgets = tx_macro_dapm_widgets, | ||
| 1773 | .num_dapm_widgets = ARRAY_SIZE(tx_macro_dapm_widgets), | ||
| 1774 | .dapm_routes = tx_audio_map, | ||
| 1775 | .num_dapm_routes = ARRAY_SIZE(tx_audio_map), | ||
| 1776 | }; | ||
| 1777 | |||
| 1778 | static int tx_macro_probe(struct platform_device *pdev) | ||
| 1779 | { | ||
| 1780 | struct device *dev = &pdev->dev; | ||
| 1781 | struct tx_macro *tx; | ||
| 1782 | void __iomem *base; | ||
| 1783 | int ret; | ||
| 1784 | |||
| 1785 | tx = devm_kzalloc(dev, sizeof(*tx), GFP_KERNEL); | ||
| 1786 | if (!tx) | ||
| 1787 | return -ENOMEM; | ||
| 1788 | |||
| 1789 | tx->clks[0].id = "macro"; | ||
| 1790 | tx->clks[1].id = "dcodec"; | ||
| 1791 | tx->clks[2].id = "mclk"; | ||
| 1792 | tx->clks[3].id = "npl"; | ||
| 1793 | tx->clks[4].id = "fsgen"; | ||
| 1794 | |||
| 1795 | ret = devm_clk_bulk_get(dev, TX_NUM_CLKS_MAX, tx->clks); | ||
| 1796 | if (ret) { | ||
| 1797 | dev_err(dev, "Error getting RX Clocks (%d)\n", ret); | ||
| 1798 | return ret; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 1802 | if (IS_ERR(base)) | ||
| 1803 | return PTR_ERR(base); | ||
| 1804 | |||
| 1805 | tx->regmap = devm_regmap_init_mmio(dev, base, &tx_regmap_config); | ||
| 1806 | |||
| 1807 | dev_set_drvdata(dev, tx); | ||
| 1808 | |||
| 1809 | tx->reset_swr = true; | ||
| 1810 | tx->dev = dev; | ||
| 1811 | |||
| 1812 | /* set MCLK and NPL rates */ | ||
| 1813 | clk_set_rate(tx->clks[2].clk, MCLK_FREQ); | ||
| 1814 | clk_set_rate(tx->clks[3].clk, MCLK_FREQ); | ||
| 1815 | |||
| 1816 | ret = clk_bulk_prepare_enable(TX_NUM_CLKS_MAX, tx->clks); | ||
| 1817 | if (ret) | ||
| 1818 | return ret; | ||
| 1819 | |||
| 1820 | tx_macro_register_mclk_output(tx); | ||
| 1821 | |||
| 1822 | ret = devm_snd_soc_register_component(dev, &tx_macro_component_drv, | ||
| 1823 | tx_macro_dai, | ||
| 1824 | ARRAY_SIZE(tx_macro_dai)); | ||
| 1825 | if (ret) | ||
| 1826 | goto err; | ||
| 1827 | return ret; | ||
| 1828 | err: | ||
| 1829 | clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); | ||
| 1830 | |||
| 1831 | return ret; | ||
| 1832 | } | ||
| 1833 | |||
| 1834 | static int tx_macro_remove(struct platform_device *pdev) | ||
| 1835 | { | ||
| 1836 | struct tx_macro *tx = dev_get_drvdata(&pdev->dev); | ||
| 1837 | |||
| 1838 | of_clk_del_provider(pdev->dev.of_node); | ||
| 1839 | |||
| 1840 | clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks); | ||
| 1841 | |||
| 1842 | return 0; | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | static const struct of_device_id tx_macro_dt_match[] = { | ||
| 1846 | { .compatible = "qcom,sm8250-lpass-tx-macro" }, | ||
| 1847 | { } | ||
| 1848 | }; | ||
| 1849 | static struct platform_driver tx_macro_driver = { | ||
| 1850 | .driver = { | ||
| 1851 | .name = "tx_macro", | ||
| 1852 | .of_match_table = tx_macro_dt_match, | ||
| 1853 | .suppress_bind_attrs = true, | ||
| 1854 | }, | ||
| 1855 | .probe = tx_macro_probe, | ||
| 1856 | .remove = tx_macro_remove, | ||
| 1857 | }; | ||
| 1858 | |||
| 1859 | module_platform_driver(tx_macro_driver); | ||
| 1860 | |||
| 1861 | MODULE_DESCRIPTION("TX macro driver"); | ||
| 1862 | MODULE_LICENSE("GPL"); | ||
| @@ -40,9 +40,11 @@ · 39 unmodified lines | |||
| 40 | #define CDC_WSA_TOP_I2S_CLK (0x00A4) | 40 | #define CDC_WSA_TOP_I2S_CLK (0x00A4) |
| 41 | #define CDC_WSA_TOP_I2S_RESET (0x00A8) | 41 | #define CDC_WSA_TOP_I2S_RESET (0x00A8) |
| 42 | #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (0x0100) | 42 | #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (0x0100) |
| 43 | #define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3) | 43 | #define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(2, 0) |
| 44 | #define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) | 44 | #define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(5, 3) |
| 45 | #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (0x0104) | 45 | #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (0x0104) |
| 46 | #define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) | ||
| 47 | #define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3) | ||
| 46 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108) | 48 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108) |
| 47 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C) | 49 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C) |
| 48 | #define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110) | 50 | #define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110) |
| @@ -229,8 +231,6 @@ · 180 unmodified lines | |||
| 229 | #define NUM_INTERPOLATORS 2 | 231 | #define NUM_INTERPOLATORS 2 |
| 230 | #define WSA_NUM_CLKS_MAX 5 | 232 | #define WSA_NUM_CLKS_MAX 5 |
| 231 | #define WSA_MACRO_MCLK_FREQ 19200000 | 233 | #define WSA_MACRO_MCLK_FREQ 19200000 |
| 232 | #define WSA_MACRO_MUX_INP_SHFT 0x3 | ||
| 233 | #define WSA_MACRO_MUX_INP_MASK1 0x07 | ||
| 234 | #define WSA_MACRO_MUX_INP_MASK2 0x38 | 234 | #define WSA_MACRO_MUX_INP_MASK2 0x38 |
| 235 | #define WSA_MACRO_MUX_CFG_OFFSET 0x8 | 235 | #define WSA_MACRO_MUX_CFG_OFFSET 0x8 |
| 236 | #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 | 236 | #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 |
| @@ -843,7 +843,6 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, · 606 unmodified lines | |||
| 843 | u32 j, port; | 843 | u32 j, port; |
| 844 | u16 int_mux_cfg0, int_mux_cfg1; | 844 | u16 int_mux_cfg0, int_mux_cfg1; |
| 845 | u16 int_fs_reg; | 845 | u16 int_fs_reg; |
| 846 | u8 int_mux_cfg0_val, int_mux_cfg1_val; | ||
| 847 | u8 inp0_sel, inp1_sel, inp2_sel; | 846 | u8 inp0_sel, inp1_sel, inp2_sel; |
| 848 | struct snd_soc_component *component = dai->component; | 847 | struct snd_soc_component *component = dai->component; |
| 849 | struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); | 848 | struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); |
| @@ -865,15 +864,13 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai, · 15 unmodified lines | |||
| 865 | */ | 864 | */ |
| 866 | for (j = 0; j < NUM_INTERPOLATORS; j++) { | 865 | for (j = 0; j < NUM_INTERPOLATORS; j++) { |
| 867 | int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; | 866 | int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; |
| 868 | int_mux_cfg0_val = snd_soc_component_read(component, | 867 | inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, |
| 869 | int_mux_cfg0); | 868 | CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); |
| 870 | int_mux_cfg1_val = snd_soc_component_read(component, | 869 | inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, |
| 871 | int_mux_cfg1); | 870 | CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); |
| 872 | inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; | 871 | inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, |
| 873 | inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) & | 872 | CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); |
| 874 | WSA_MACRO_MUX_INP_MASK1; | 873 | |
| 875 | inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) & | ||
| 876 | WSA_MACRO_MUX_INP_MASK1; | ||
| 877 | if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || | 874 | if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || |
| 878 | (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || | 875 | (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || |
| 879 | (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { | 876 | (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { |
| @@ -912,9 +909,9 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, · 32 unmodified lines | |||
| 912 | 909 | ||
| 913 | int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; | 910 | int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; |
| 914 | for (j = 0; j < NUM_INTERPOLATORS; j++) { | 911 | for (j = 0; j < NUM_INTERPOLATORS; j++) { |
| 915 | int_mux_cfg1_val = snd_soc_component_read(component, | 912 | int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, |
| 916 | int_mux_cfg1) & | 913 | CDC_WSA_RX_INTX_2_SEL_MASK); |
| 917 | WSA_MACRO_MUX_INP_MASK1; | 914 | |
| 918 | if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { | 915 | if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { |
| 919 | int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + | 916 | int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + |
| 920 | WSA_MACRO_RX_PATH_OFFSET * j; | 917 | WSA_MACRO_RX_PATH_OFFSET * j; |
| @@ -1410,25 +1407,25 @@ static bool wsa_macro_adie_lb(struct snd_soc_component *component, · 489 unmodified lines | |||
| 1410 | int interp_idx) | 1407 | int interp_idx) |
| 1411 | { | 1408 | { |
| 1412 | u16 int_mux_cfg0, int_mux_cfg1; | 1409 | u16 int_mux_cfg0, int_mux_cfg1; |
| 1413 | u8 int_mux_cfg0_val, int_mux_cfg1_val; | ||
| 1414 | u8 int_n_inp0, int_n_inp1, int_n_inp2; | 1410 | u8 int_n_inp0, int_n_inp1, int_n_inp2; |
| 1415 | 1411 | ||
| 1416 | int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; | 1412 | int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; |
| 1417 | int_mux_cfg1 = int_mux_cfg0 + 4; | 1413 | int_mux_cfg1 = int_mux_cfg0 + 4; |
| 1418 | int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); | ||
| 1419 | int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1); | ||
| 1420 | 1414 | ||
| 1421 | int_n_inp0 = int_mux_cfg0_val & 0x0F; | 1415 | int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, |
| 1416 | CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); | ||
| 1422 | if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || | 1417 | if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || |
| 1423 | int_n_inp0 == INTn_1_INP_SEL_DEC1) | 1418 | int_n_inp0 == INTn_1_INP_SEL_DEC1) |
| 1424 | return true; | 1419 | return true; |
| 1425 | 1420 | ||
| 1426 | int_n_inp1 = int_mux_cfg0_val >> 4; | 1421 | int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, |
| 1422 | CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); | ||
| 1427 | if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || | 1423 | if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || |
| 1428 | int_n_inp1 == INTn_1_INP_SEL_DEC1) | 1424 | int_n_inp1 == INTn_1_INP_SEL_DEC1) |
| 1429 | return true; | 1425 | return true; |
| 1430 | 1426 | ||
| 1431 | int_n_inp2 = int_mux_cfg1_val >> 4; | 1427 | int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, |
| 1428 | CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); | ||
| 1432 | if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || | 1429 | if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || |
| 1433 | int_n_inp2 == INTn_1_INP_SEL_DEC1) | 1430 | int_n_inp2 == INTn_1_INP_SEL_DEC1) |
| 1434 | return true; | 1431 | return true; |
| @@ -262,6 +262,8 @@ static __maybe_unused int max98373_suspend(struct device *dev) · 261 unmodified lines | |||
| 262 | return 0; | 262 | return 0; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | #define MAX98373_PROBE_TIMEOUT 5000 | ||
| 266 | |||
| 265 | static __maybe_unused int max98373_resume(struct device *dev) | 267 | static __maybe_unused int max98373_resume(struct device *dev) |
| 266 | { | 268 | { |
| 267 | struct sdw_slave *slave = dev_to_sdw_dev(dev); | 269 | struct sdw_slave *slave = dev_to_sdw_dev(dev); |
| @@ -275,7 +277,7 @@ static __maybe_unused int max98373_resume(struct device *dev) · 7 unmodified lines | |||
| 275 | goto regmap_sync; | 277 | goto regmap_sync; |
| 276 | 278 | ||
| 277 | time = wait_for_completion_timeout(&slave->initialization_complete, | 279 | time = wait_for_completion_timeout(&slave->initialization_complete, |
| 278 | msecs_to_jiffies(2000)); | 280 | msecs_to_jiffies(MAX98373_PROBE_TIMEOUT)); |
| 279 | if (!time) { | 281 | if (!time) { |
| 280 | dev_err(dev, "Initialization not complete, timed out\n"); | 282 | dev_err(dev, "Initialization not complete, timed out\n"); |
| 281 | return -ETIMEDOUT; | 283 | return -ETIMEDOUT; |
| @@ -190,7 +190,7 @@ static int max98373_feedback_get(struct snd_kcontrol *kcontrol, · 189 unmodified lines | |||
| 190 | } | 190 | } |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | return snd_soc_put_volsw(kcontrol, ucontrol); | 193 | return snd_soc_get_volsw(kcontrol, ucontrol); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static const struct snd_kcontrol_new max98373_snd_controls[] = { | 196 | static const struct snd_kcontrol_new max98373_snd_controls[] = { |
| @@ -489,7 +489,7 @@ static struct snd_soc_dai_driver max9860_dai = { · 488 unmodified lines | |||
| 489 | SNDRV_PCM_FMTBIT_S32_LE, | 489 | SNDRV_PCM_FMTBIT_S32_LE, |
| 490 | }, | 490 | }, |
| 491 | .ops = &max9860_dai_ops, | 491 | .ops = &max9860_dai_ops, |
| 492 | .symmetric_rates = 1, | 492 | .symmetric_rate = 1, |
| 493 | }; | 493 | }; |
| 494 | 494 | ||
| 495 | static int max9860_set_bias_level(struct snd_soc_component *component, | 495 | static int max9860_set_bias_level(struct snd_soc_component *component, |
| @@ -520,7 +520,7 @@ static struct snd_soc_dai_driver max9867_dai[] = { · 519 unmodified lines | |||
| 520 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 520 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 521 | }, | 521 | }, |
| 522 | .ops = &max9867_dai_ops, | 522 | .ops = &max9867_dai_ops, |
| 523 | .symmetric_rates = 1, | 523 | .symmetric_rate = 1, |
| 524 | } | 524 | } |
| 525 | }; | 525 | }; |
| 526 | 526 | ||
| @@ -712,7 +712,7 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { · 711 unmodified lines | |||
| 712 | .formats = MC13783_FORMATS, | 712 | .formats = MC13783_FORMATS, |
| 713 | }, | 713 | }, |
| 714 | .ops = &mc13783_ops_sync, | 714 | .ops = &mc13783_ops_sync, |
| 715 | .symmetric_rates = 1, | 715 | .symmetric_rate = 1, |
| 716 | } | 716 | } |
| 717 | }; | 717 | }; |
| 718 | 718 | ||
| @@ -513,7 +513,7 @@ static struct snd_soc_dai_driver ml26124_dai = { · 512 unmodified lines | |||
| 513 | .rates = ML26124_RATES, | 513 | .rates = ML26124_RATES, |
| 514 | .formats = ML26124_FORMATS,}, | 514 | .formats = ML26124_FORMATS,}, |
| 515 | .ops = &ml26124_dai_ops, | 515 | .ops = &ml26124_dai_ops, |
| 516 | .symmetric_rates = 1, | 516 | .symmetric_rate = 1, |
| 517 | }; | 517 | }; |
| 518 | 518 | ||
| 519 | static int ml26124_probe(struct snd_soc_component *component) | 519 | static int ml26124_probe(struct snd_soc_component *component) |
| @@ -2754,7 +2754,8 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) · 2753 unmodified lines | |||
| 2754 | ret = of_property_read_u32(np, "mediatek,dmic-mode", | 2754 | ret = of_property_read_u32(np, "mediatek,dmic-mode", |
| 2755 | &priv->dmic_one_wire_mode); | 2755 | &priv->dmic_one_wire_mode); |
| 2756 | if (ret) { | 2756 | if (ret) { |
| 2757 | dev_warn(priv->dev, "%s() failed to read dmic-mode\n", | 2757 | dev_info(priv->dev, |
| 2758 | "%s() failed to read dmic-mode, use default (0)\n", | ||
| 2758 | __func__); | 2759 | __func__); |
| 2759 | priv->dmic_one_wire_mode = 0; | 2760 | priv->dmic_one_wire_mode = 0; |
| 2760 | } | 2761 | } |
| @@ -2762,24 +2763,27 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) · 1 unmodified line | |||
| 2762 | ret = of_property_read_u32(np, "mediatek,mic-type-0", | 2763 | ret = of_property_read_u32(np, "mediatek,mic-type-0", |
| 2763 | &priv->mux_select[MUX_MIC_TYPE_0]); | 2764 | &priv->mux_select[MUX_MIC_TYPE_0]); |
| 2764 | if (ret) { | 2765 | if (ret) { |
| 2765 | dev_warn(priv->dev, "%s() failed to read mic-type-0\n", | 2766 | dev_info(priv->dev, |
| 2766 | __func__); | 2767 | "%s() failed to read mic-type-0, use default (%d)\n", |
| 2768 | __func__, MIC_TYPE_MUX_IDLE); | ||
| 2767 | priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE; | 2769 | priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE; |
| 2768 | } | 2770 | } |
| 2769 | 2771 | ||
| 2770 | ret = of_property_read_u32(np, "mediatek,mic-type-1", | 2772 | ret = of_property_read_u32(np, "mediatek,mic-type-1", |
| 2771 | &priv->mux_select[MUX_MIC_TYPE_1]); | 2773 | &priv->mux_select[MUX_MIC_TYPE_1]); |
| 2772 | if (ret) { | 2774 | if (ret) { |
| 2773 | dev_warn(priv->dev, "%s() failed to read mic-type-1\n", | 2775 | dev_info(priv->dev, |
| 2774 | __func__); | 2776 | "%s() failed to read mic-type-1, use default (%d)\n", |
| 2777 | __func__, MIC_TYPE_MUX_IDLE); | ||
| 2775 | priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE; | 2778 | priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE; |
| 2776 | } | 2779 | } |
| 2777 | 2780 | ||
| 2778 | ret = of_property_read_u32(np, "mediatek,mic-type-2", | 2781 | ret = of_property_read_u32(np, "mediatek,mic-type-2", |
| 2779 | &priv->mux_select[MUX_MIC_TYPE_2]); | 2782 | &priv->mux_select[MUX_MIC_TYPE_2]); |
| 2780 | if (ret) { | 2783 | if (ret) { |
| 2781 | dev_warn(priv->dev, "%s() failed to read mic-type-2\n", | 2784 | dev_info(priv->dev, |
| 2782 | __func__); | 2785 | "%s() failed to read mic-type-2, use default (%d)\n", |
| 2786 | __func__, MIC_TYPE_MUX_IDLE); | ||
| 2783 | priv->mux_select[MUX_MIC_TYPE_2] = MIC_TYPE_MUX_IDLE; | 2787 | priv->mux_select[MUX_MIC_TYPE_2] = MIC_TYPE_MUX_IDLE; |
| 2784 | } | 2788 | } |
| 2785 | 2789 | ||
| @@ -404,9 +404,9 @@ static struct snd_soc_dai_driver mt6660_codec_dai = { · 403 unmodified lines | |||
| 404 | .formats = STUB_FORMATS, | 404 | .formats = STUB_FORMATS, |
| 405 | }, | 405 | }, |
| 406 | /* dai properties */ | 406 | /* dai properties */ |
| 407 | .symmetric_rates = 1, | 407 | .symmetric_rate = 1, |
| 408 | .symmetric_channels = 1, | 408 | .symmetric_channels = 1, |
| 409 | .symmetric_samplebits = 1, | 409 | .symmetric_sample_bits = 1, |
| 410 | /* dai operations */ | 410 | /* dai operations */ |
| 411 | .ops = &mt6660_component_aif_ops, | 411 | .ops = &mt6660_component_aif_ops, |
| 412 | }; | 412 | }; |
| @@ -837,7 +837,7 @@ static struct snd_soc_dai_driver nau8810_dai = { · 836 unmodified lines | |||
| 837 | .formats = NAU8810_FORMATS, | 837 | .formats = NAU8810_FORMATS, |
| 838 | }, | 838 | }, |
| 839 | .ops = &nau8810_ops, | 839 | .ops = &nau8810_ops, |
| 840 | .symmetric_rates = 1, | 840 | .symmetric_rate = 1, |
| 841 | }; | 841 | }; |
| 842 | 842 | ||
| 843 | static const struct regmap_config nau8810_regmap_config = { | 843 | static const struct regmap_config nau8810_regmap_config = { |
| @@ -991,7 +991,7 @@ static struct snd_soc_dai_driver nau8822_dai = { · 990 unmodified lines | |||
| 991 | .formats = NAU8822_FORMATS, | 991 | .formats = NAU8822_FORMATS, |
| 992 | }, | 992 | }, |
| 993 | .ops = &nau8822_dai_ops, | 993 | .ops = &nau8822_dai_ops, |
| 994 | .symmetric_rates = 1, | 994 | .symmetric_rate = 1, |
| 995 | }; | 995 | }; |
| 996 | 996 | ||
| 997 | static int nau8822_suspend(struct snd_soc_component *component) | 997 | static int nau8822_suspend(struct snd_soc_component *component) |
| @@ -24,10 +24,10 @@ · 23 unmodified lines | |||
| 24 | #include <sound/initval.h> | 24 | #include <sound/initval.h> |
| 25 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| 26 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
| 27 | #include <sound/rt1015.h> | ||
| 27 | #include <sound/soc-dapm.h> | 28 | #include <sound/soc-dapm.h> |
| 28 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
| 29 | #include <sound/tlv.h> | 30 | #include <sound/tlv.h> |
| 30 | #include <sound/rt1015.h> | ||
| 31 | 31 | ||
| 32 | #include "rl6231.h" | 32 | #include "rl6231.h" |
| 33 | #include "rt1015.h" | 33 | #include "rt1015.h" |
| @@ -444,10 +444,9 @@ static int rt1015_boost_mode_put(struct snd_kcontrol *kcontrol, · 410 unmodified lines | |||
| 444 | snd_soc_kcontrol_component(kcontrol); | 444 | snd_soc_kcontrol_component(kcontrol); |
| 445 | struct rt1015_priv *rt1015 = | 445 | struct rt1015_priv *rt1015 = |
| 446 | snd_soc_component_get_drvdata(component); | 446 | snd_soc_component_get_drvdata(component); |
| 447 | int boost_mode = ucontrol->value.integer.value[0]; | ||
| 447 | 448 | ||
| 448 | rt1015->boost_mode = ucontrol->value.integer.value[0]; | 449 | switch (boost_mode) { |
| 449 | |||
| 450 | switch (rt1015->boost_mode) { | ||
| 451 | case BYPASS: | 450 | case BYPASS: |
| 452 | snd_soc_component_update_bits(component, | 451 | snd_soc_component_update_bits(component, |
| 453 | RT1015_SMART_BST_CTRL1, RT1015_ABST_AUTO_EN_MASK | | 452 | RT1015_SMART_BST_CTRL1, RT1015_ABST_AUTO_EN_MASK | |
| @@ -471,8 +470,11 @@ static int rt1015_boost_mode_put(struct snd_kcontrol *kcontrol, · 17 unmodified lines | |||
| 471 | break; | 470 | break; |
| 472 | default: | 471 | default: |
| 473 | dev_err(component->dev, "Unknown boost control.\n"); | 472 | dev_err(component->dev, "Unknown boost control.\n"); |
| 473 | return -EINVAL; | ||
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | rt1015->boost_mode = boost_mode; | ||
| 477 | |||
| 476 | return 0; | 478 | return 0; |
| 477 | } | 479 | } |
| 478 | 480 | ||
| @@ -497,40 +499,20 @@ static void rt1015_calibrate(struct rt1015_priv *rt1015) · 18 unmodified lines | |||
| 497 | snd_soc_dapm_mutex_lock(&component->dapm); | 499 | snd_soc_dapm_mutex_lock(&component->dapm); |
| 498 | regcache_cache_bypass(regmap, true); | 500 | regcache_cache_bypass(regmap, true); |
| 499 | 501 | ||
| 500 | regmap_write(regmap, RT1015_PWR9, 0xAA60); | 502 | regmap_write(regmap, RT1015_CLK_DET, 0x0000); |
| 501 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0089); | ||
| 502 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008A); | ||
| 503 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008C); | ||
| 504 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008D); | ||
| 505 | regmap_write(regmap, RT1015_PWR4, 0x80B2); | ||
| 506 | regmap_write(regmap, RT1015_CLASSD_SEQ, 0x5797); | ||
| 507 | regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2100); | ||
| 508 | regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0100); | ||
| 509 | regmap_write(regmap, RT1015_PWR5, 0x2175); | ||
| 510 | regmap_write(regmap, RT1015_MIXER1, 0x005D); | ||
| 511 | regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1); | ||
| 512 | regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12F7); | ||
| 513 | regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x1205); | ||
| 514 | msleep(200); | ||
| 515 | regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2000); | ||
| 516 | regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0180); | ||
| 517 | regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x00A1); | ||
| 518 | regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x0A05); | ||
| 519 | msleep(200); | ||
| 520 | regmap_write(regmap, RT1015_PWR4, 0x00B2); | 503 | regmap_write(regmap, RT1015_PWR4, 0x00B2); |
| 504 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0009); | ||
| 505 | msleep(100); | ||
| 506 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000A); | ||
| 507 | msleep(100); | ||
| 508 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000C); | ||
| 509 | msleep(100); | ||
| 521 | regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2028); | 510 | regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2028); |
| 522 | regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140); | 511 | regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140); |
| 523 | regmap_write(regmap, RT1015_PWR5, 0x0175); | 512 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000D); |
| 524 | regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x1721); | 513 | msleep(300); |
| 525 | regmap_write(regmap, RT1015_CLASSD_SEQ, 0x570E); | 514 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0008); |
| 526 | regmap_write(regmap, RT1015_MIXER1, 0x203D); | ||
| 527 | regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5A01); | ||
| 528 | regmap_write(regmap, RT1015_CLSD_INTERNAL2, 0x12FF); | ||
| 529 | regmap_write(regmap, RT1015_GAT_BOOST, 0x0eFE); | ||
| 530 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x008E); | ||
| 531 | regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0088); | ||
| 532 | regmap_write(regmap, RT1015_SYS_RST1, 0x05F5); | 515 | regmap_write(regmap, RT1015_SYS_RST1, 0x05F5); |
| 533 | regmap_write(regmap, RT1015_SYS_RST2, 0x0b9a); | ||
| 534 | 516 | ||
| 535 | regcache_cache_bypass(regmap, false); | 517 | regcache_cache_bypass(regmap, false); |
| 536 | regcache_mark_dirty(regmap); | 518 | regcache_mark_dirty(regmap); |
| @@ -546,17 +528,19 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, · 9 unmodified lines | |||
| 546 | struct rt1015_priv *rt1015 = | 528 | struct rt1015_priv *rt1015 = |
| 547 | snd_soc_component_get_drvdata(component); | 529 | snd_soc_component_get_drvdata(component); |
| 548 | 530 | ||
| 549 | if (!rt1015->dac_is_used) { | 531 | if (rt1015->dac_is_used) { |
| 550 | rt1015->bypass_boost = ucontrol->value.integer.value[0]; | 532 | dev_err(component->dev, "DAC is being used!\n"); |
| 551 | if (rt1015->bypass_boost == RT1015_Bypass_Boost && | 533 | return -EBUSY; |
| 534 | } | ||
| 535 | |||
| 536 | rt1015->bypass_boost = ucontrol->value.integer.value[0]; | ||
| 537 | if (rt1015->bypass_boost == RT1015_Bypass_Boost && | ||
| 552 | !rt1015->cali_done) { | 538 | !rt1015->cali_done) { |
| 553 | rt1015_calibrate(rt1015); | 539 | rt1015_calibrate(rt1015); |
| 554 | rt1015->cali_done = 1; | 540 | rt1015->cali_done = 1; |
| 555 | 541 | ||
| 556 | regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); | 542 | regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); |
| 557 | } | 543 | } |
| 558 | } else | ||
| 559 | dev_err(component->dev, "DAC is being used!\n"); | ||
| 560 | 544 | ||
| 561 | return 0; | 545 | return 0; |
| 562 | } | 546 | } |
| @@ -566,15 +550,14 @@ static void rt1015_flush_work(struct work_struct *work) · 3 unmodified lines | |||
| 566 | struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, | 550 | struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, |
| 567 | flush_work.work); | 551 | flush_work.work); |
| 568 | struct snd_soc_component *component = rt1015->component; | 552 | struct snd_soc_component *component = rt1015->component; |
| 569 | unsigned int val, i = 0, count = 200; | 553 | unsigned int val, i; |
| 570 | 554 | ||
| 571 | while (i < count) { | 555 | for (i = 0; i < 200; ++i) { |
| 572 | usleep_range(1000, 1500); | 556 | usleep_range(1000, 1500); |
| 573 | dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i); | 557 | dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i); |
| 574 | regmap_read(rt1015->regmap, RT1015_CLK_DET, &val); | 558 | regmap_read(rt1015->regmap, RT1015_CLK_DET, &val); |
| 575 | if (val & 0x800) | 559 | if (val & 0x800) |
| 576 | break; | 560 | break; |
| 577 | i++; | ||
| 578 | } | 561 | } |
| 579 | 562 | ||
| 580 | regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597); | 563 | regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597); |
| @@ -721,11 +704,11 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, · 140 unmodified lines | |||
| 721 | { | 704 | { |
| 722 | struct snd_soc_component *component = dai->component; | 705 | struct snd_soc_component *component = dai->component; |
| 723 | struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); | 706 | struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); |
| 724 | int pre_div, bclk_ms, frame_size; | 707 | int pre_div, bclk_ms, frame_size, lrck; |
| 725 | unsigned int val_len = 0; | 708 | unsigned int val_len = 0; |
| 726 | 709 | ||
| 727 | rt1015->lrck = params_rate(params); | 710 | lrck = params_rate(params); |
| 728 | pre_div = rl6231_get_clk_info(rt1015->sysclk, rt1015->lrck); | 711 | pre_div = rl6231_get_clk_info(rt1015->sysclk, lrck); |
| 729 | if (pre_div < 0) { | 712 | if (pre_div < 0) { |
| 730 | dev_err(component->dev, "Unsupported clock rate\n"); | 713 | dev_err(component->dev, "Unsupported clock rate\n"); |
| 731 | return -EINVAL; | 714 | return -EINVAL; |
| @@ -739,13 +722,12 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, · 7 unmodified lines | |||
| 739 | } | 722 | } |
| 740 | 723 | ||
| 741 | bclk_ms = frame_size > 32; | 724 | bclk_ms = frame_size > 32; |
| 742 | rt1015->bclk = rt1015->lrck * (32 << bclk_ms); | ||
| 743 | 725 | ||
| 744 | dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | 726 | dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", |
| 745 | bclk_ms, pre_div, dai->id); | 727 | bclk_ms, pre_div, dai->id); |
| 746 | 728 | ||
| 747 | dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n", | 729 | dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n", |
| 748 | rt1015->lrck, pre_div, dai->id); | 730 | lrck, pre_div, dai->id); |
| 749 | 731 | ||
| 750 | switch (params_width(params)) { | 732 | switch (params_width(params)) { |
| 751 | case 16: | 733 | case 16: |
| @@ -882,14 +864,6 @@ static int rt1015_set_component_pll(struct snd_soc_component *component, · 130 unmodified lines | |||
| 882 | freq_out == rt1015->pll_out) | 864 | freq_out == rt1015->pll_out) |
| 883 | return 0; | 865 | return 0; |
| 884 | 866 | ||
| 885 | if (source == RT1015_PLL_S_BCLK) { | ||
| 886 | if (rt1015->bclk_ratio == 0) { | ||
| 887 | dev_err(component->dev, | ||
| 888 | "Can not support bclk ratio as 0.\n"); | ||
| 889 | return -EINVAL; | ||
| 890 | } | ||
| 891 | } | ||
| 892 | |||
| 893 | switch (source) { | 867 | switch (source) { |
| 894 | case RT1015_PLL_S_MCLK: | 868 | case RT1015_PLL_S_MCLK: |
| 895 | snd_soc_component_update_bits(component, RT1015_CLK2, | 869 | snd_soc_component_update_bits(component, RT1015_CLK2, |
| @@ -929,23 +903,6 @@ static int rt1015_set_component_pll(struct snd_soc_component *component, · 33 unmodified lines | |||
| 929 | return 0; | 903 | return 0; |
| 930 | } | 904 | } |
| 931 | 905 | ||
| 932 | static int rt1015_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | ||
| 933 | { | ||
| 934 | struct snd_soc_component *component = dai->component; | ||
| 935 | struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component); | ||
| 936 | |||
| 937 | dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio); | ||
| 938 | |||
| 939 | rt1015->bclk_ratio = ratio; | ||
| 940 | |||
| 941 | if (ratio == 50) { | ||
| 942 | dev_dbg(component->dev, "Unsupport bclk ratio\n"); | ||
| 943 | return -EINVAL; | ||
| 944 | } | ||
| 945 | |||
| 946 | return 0; | ||
| 947 | } | ||
| 948 | |||
| 949 | static int rt1015_set_tdm_slot(struct snd_soc_dai *dai, | 906 | static int rt1015_set_tdm_slot(struct snd_soc_dai *dai, |
| 950 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) | 907 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
| 951 | { | 908 | { |
| @@ -1052,9 +1009,6 @@ static int rt1015_probe(struct snd_soc_component *component) · 100 unmodified lines | |||
| 1052 | snd_soc_component_get_drvdata(component); | 1009 | snd_soc_component_get_drvdata(component); |
| 1053 | 1010 | ||
| 1054 | rt1015->component = component; | 1011 | rt1015->component = component; |
| 1055 | rt1015->bclk_ratio = 0; | ||
| 1056 | rt1015->cali_done = 0; | ||
| 1057 | |||
| 1058 | INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); | 1012 | INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); |
| 1059 | 1013 | ||
| 1060 | return 0; | 1014 | return 0; |
| @@ -1075,7 +1029,6 @@ static void rt1015_remove(struct snd_soc_component *component) · 14 unmodified lines | |||
| 1075 | static struct snd_soc_dai_ops rt1015_aif_dai_ops = { | 1029 | static struct snd_soc_dai_ops rt1015_aif_dai_ops = { |
| 1076 | .hw_params = rt1015_hw_params, | 1030 | .hw_params = rt1015_hw_params, |
| 1077 | .set_fmt = rt1015_set_dai_fmt, | 1031 | .set_fmt = rt1015_set_dai_fmt, |
| 1078 | .set_bclk_ratio = rt1015_set_bclk_ratio, | ||
| 1079 | .set_tdm_slot = rt1015_set_tdm_slot, | 1032 | .set_tdm_slot = rt1015_set_tdm_slot, |
| 1080 | }; | 1033 | }; |
| 1081 | 1034 | ||
| @@ -1111,6 +1064,10 @@ static int rt1015_resume(struct snd_soc_component *component) · 29 unmodified lines | |||
| 1111 | 1064 | ||
| 1112 | regcache_cache_only(rt1015->regmap, false); | 1065 | regcache_cache_only(rt1015->regmap, false); |
| 1113 | regcache_sync(rt1015->regmap); | 1066 | regcache_sync(rt1015->regmap); |
| 1067 | |||
| 1068 | if (rt1015->cali_done) | ||
| 1069 | rt1015_calibrate(rt1015); | ||
| 1070 | |||
| 1114 | return 0; | 1071 | return 0; |
| 1115 | } | 1072 | } |
| 1116 | #else | 1073 | #else |
| @@ -1183,9 +1140,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, · 66 unmodified lines | |||
| 1183 | int ret; | 1140 | int ret; |
| 1184 | unsigned int val; | 1141 | unsigned int val; |
| 1185 | 1142 | ||
| 1186 | rt1015 = devm_kzalloc(&i2c->dev, sizeof(struct rt1015_priv), | 1143 | rt1015 = devm_kzalloc(&i2c->dev, sizeof(*rt1015), GFP_KERNEL); |
| 1187 | GFP_KERNEL); | 1144 | if (!rt1015) |
| 1188 | if (rt1015 == NULL) | ||
| 1189 | return -ENOMEM; | 1145 | return -ENOMEM; |
| 1190 | 1146 | ||
| 1191 | i2c_set_clientdata(i2c, rt1015); | 1147 | i2c_set_clientdata(i2c, rt1015); |
| @@ -427,16 +427,11 @@ struct rt1015_priv { · 426 unmodified lines | |||
| 427 | struct regmap *regmap; | 427 | struct regmap *regmap; |
| 428 | int sysclk; | 428 | int sysclk; |
| 429 | int sysclk_src; | 429 | int sysclk_src; |
| 430 | int lrck; | ||
| 431 | int bclk; | ||
| 432 | int bclk_ratio; | ||
| 433 | int id; | ||
| 434 | int pll_src; | 430 | int pll_src; |
| 435 | int pll_in; | 431 | int pll_in; |
| 436 | int pll_out; | 432 | int pll_out; |
| 437 | int boost_mode; | 433 | int boost_mode; |
| 438 | int bypass_boost; | 434 | int bypass_boost; |
| 439 | int amp_ver; | ||
| 440 | int dac_is_used; | 435 | int dac_is_used; |
| 441 | int cali_done; | 436 | int cali_done; |
| 442 | int hw_config; | 437 | int hw_config; |
| @@ -701,7 +701,7 @@ static int __maybe_unused rt1308_dev_suspend(struct device *dev) · 700 unmodified lines | |||
| 701 | return 0; | 701 | return 0; |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | #define RT1308_PROBE_TIMEOUT 2000 | 704 | #define RT1308_PROBE_TIMEOUT 5000 |
| 705 | 705 | ||
| 706 | static int __maybe_unused rt1308_dev_resume(struct device *dev) | 706 | static int __maybe_unused rt1308_dev_resume(struct device *dev) |
| 707 | { | 707 | { |
| @@ -1056,7 +1056,7 @@ static struct snd_soc_dai_driver rt274_dai[] = { · 1055 unmodified lines | |||
| 1056 | .formats = RT274_FORMATS, | 1056 | .formats = RT274_FORMATS, |
| 1057 | }, | 1057 | }, |
| 1058 | .ops = &rt274_aif_dai_ops, | 1058 | .ops = &rt274_aif_dai_ops, |
| 1059 | .symmetric_rates = 1, | 1059 | .symmetric_rate = 1, |
| 1060 | }, | 1060 | }, |
| 1061 | }; | 1061 | }; |
| 1062 | 1062 | ||
| @@ -1017,7 +1017,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { · 1016 unmodified lines | |||
| 1017 | .formats = RT286_FORMATS, | 1017 | .formats = RT286_FORMATS, |
| 1018 | }, | 1018 | }, |
| 1019 | .ops = &rt286_aif_dai_ops, | 1019 | .ops = &rt286_aif_dai_ops, |
| 1020 | .symmetric_rates = 1, | 1020 | .symmetric_rate = 1, |
| 1021 | }, | 1021 | }, |
| 1022 | { | 1022 | { |
| 1023 | .name = "rt286-aif2", | 1023 | .name = "rt286-aif2", |
| @@ -1037,7 +1037,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { · 13 unmodified lines | |||
| 1037 | .formats = RT286_FORMATS, | 1037 | .formats = RT286_FORMATS, |
| 1038 | }, | 1038 | }, |
| 1039 | .ops = &rt286_aif_dai_ops, | 1039 | .ops = &rt286_aif_dai_ops, |
| 1040 | .symmetric_rates = 1, | 1040 | .symmetric_rate = 1, |
| 1041 | }, | 1041 | }, |
| 1042 | 1042 | ||
| 1043 | }; | 1043 | }; |
| @@ -1084,7 +1084,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { · 1083 unmodified lines | |||
| 1084 | .formats = RT298_FORMATS, | 1084 | .formats = RT298_FORMATS, |
| 1085 | }, | 1085 | }, |
| 1086 | .ops = &rt298_aif_dai_ops, | 1086 | .ops = &rt298_aif_dai_ops, |
| 1087 | .symmetric_rates = 1, | 1087 | .symmetric_rate = 1, |
| 1088 | }, | 1088 | }, |
| 1089 | { | 1089 | { |
| 1090 | .name = "rt298-aif2", | 1090 | .name = "rt298-aif2", |
| @@ -1104,7 +1104,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { · 13 unmodified lines | |||
| 1104 | .formats = RT298_FORMATS, | 1104 | .formats = RT298_FORMATS, |
| 1105 | }, | 1105 | }, |
| 1106 | .ops = &rt298_aif_dai_ops, | 1106 | .ops = &rt298_aif_dai_ops, |
| 1107 | .symmetric_rates = 1, | 1107 | .symmetric_rate = 1, |
| 1108 | }, | 1108 | }, |
| 1109 | 1109 | ||
| 1110 | }; | 1110 | }; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #define QUIRK_INV_JD1_1(q) ((q) & 1) | 34 | #define QUIRK_INV_JD1_1(q) ((q) & 1) |
| 35 | #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1) | 35 | #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1) |
| 36 | #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1) | 36 | #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1) |
| 37 | #define QUIRK_INV_HP_POL(q) (((q) >> 3) & 1) | ||
| 37 | #define QUIRK_JD_MODE(q) (((q) >> 4) & 7) | 38 | #define QUIRK_JD_MODE(q) (((q) >> 4) & 7) |
| 38 | #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3) | 39 | #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3) |
| 39 | #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3) | 40 | #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3) |
| @@ -42,6 +43,8 @@ static unsigned int quirk = -1; · 2 unmodified lines | |||
| 42 | module_param(quirk, uint, 0444); | 43 | module_param(quirk, uint, 0444); |
| 43 | MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override"); | 44 | MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override"); |
| 44 | 45 | ||
| 46 | static const struct acpi_gpio_mapping *cht_rt5645_gpios; | ||
| 47 | |||
| 45 | #define RT5645_DEVICE_ID 0x6308 | 48 | #define RT5645_DEVICE_ID 0x6308 |
| 46 | #define RT5650_DEVICE_ID 0x6419 | 49 | #define RT5650_DEVICE_ID 0x6419 |
| 47 | 50 | ||
| @@ -435,7 +438,6 @@ struct rt5645_priv { · 387 unmodified lines | |||
| 435 | 438 | ||
| 436 | int jack_type; | 439 | int jack_type; |
| 437 | bool en_button_func; | 440 | bool en_button_func; |
| 438 | bool hp_on; | ||
| 439 | int v_id; | 441 | int v_id; |
| 440 | }; | 442 | }; |
| 441 | 443 | ||
| @@ -1645,6 +1647,7 @@ static void hp_amp_power(struct snd_soc_component *component, int on) · 1203 unmodified lines | |||
| 1645 | { | 1647 | { |
| 1646 | static int hp_amp_power_count; | 1648 | static int hp_amp_power_count; |
| 1647 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); | 1649 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); |
| 1650 | int i, val; | ||
| 1648 | 1651 | ||
| 1649 | if (on) { | 1652 | if (on) { |
| 1650 | if (hp_amp_power_count <= 0) { | 1653 | if (hp_amp_power_count <= 0) { |
| @@ -1655,7 +1658,13 @@ static void hp_amp_power(struct snd_soc_component *component, int on) · 4 unmodified lines | |||
| 1655 | snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d); | 1658 | snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d); |
| 1656 | regmap_write(rt5645->regmap, RT5645_PR_BASE + | 1659 | regmap_write(rt5645->regmap, RT5645_PR_BASE + |
| 1657 | RT5645_HP_DCC_INT1, 0x9f01); | 1660 | RT5645_HP_DCC_INT1, 0x9f01); |
| 1658 | msleep(20); | 1661 | for (i = 0; i < 20; i++) { |
| 1662 | usleep_range(1000, 1500); | ||
| 1663 | regmap_read(rt5645->regmap, RT5645_PR_BASE + | ||
| 1664 | RT5645_HP_DCC_INT1, &val); | ||
| 1665 | if (!(val & 0x8000)) | ||
| 1666 | break; | ||
| 1667 | } | ||
| 1659 | snd_soc_component_update_bits(component, RT5645_DEPOP_M1, | 1668 | snd_soc_component_update_bits(component, RT5645_DEPOP_M1, |
| 1660 | RT5645_HP_CO_MASK, RT5645_HP_CO_EN); | 1669 | RT5645_HP_CO_MASK, RT5645_HP_CO_EN); |
| 1661 | regmap_write(rt5645->regmap, RT5645_PR_BASE + | 1670 | regmap_write(rt5645->regmap, RT5645_PR_BASE + |
| @@ -1665,7 +1674,6 @@ static void hp_amp_power(struct snd_soc_component *component, int on) · 3 unmodified lines | |||
| 1665 | RT5645_MAMP_INT_REG2, 0xfc00); | 1674 | RT5645_MAMP_INT_REG2, 0xfc00); |
| 1666 | snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140); | 1675 | snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140); |
| 1667 | msleep(90); | 1676 | msleep(90); |
| 1668 | rt5645->hp_on = true; | ||
| 1669 | } else { | 1677 | } else { |
| 1670 | /* depop parameters */ | 1678 | /* depop parameters */ |
| 1671 | snd_soc_component_update_bits(component, RT5645_DEPOP_M2, | 1679 | snd_soc_component_update_bits(component, RT5645_DEPOP_M2, |
| @@ -1885,27 +1893,6 @@ static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, · 213 unmodified lines | |||
| 1885 | return 0; | 1893 | return 0; |
| 1886 | } | 1894 | } |
| 1887 | 1895 | ||
| 1888 | static int rt5650_hp_event(struct snd_soc_dapm_widget *w, | ||
| 1889 | struct snd_kcontrol *k, int event) | ||
| 1890 | { | ||
| 1891 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 1892 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); | ||
| 1893 | |||
| 1894 | switch (event) { | ||
| 1895 | case SND_SOC_DAPM_POST_PMU: | ||
| 1896 | if (rt5645->hp_on) { | ||
| 1897 | msleep(100); | ||
| 1898 | rt5645->hp_on = false; | ||
| 1899 | } | ||
| 1900 | break; | ||
| 1901 | |||
| 1902 | default: | ||
| 1903 | return 0; | ||
| 1904 | } | ||
| 1905 | |||
| 1906 | return 0; | ||
| 1907 | } | ||
| 1908 | |||
| 1909 | static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, | 1896 | static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, |
| 1910 | struct snd_kcontrol *k, int event) | 1897 | struct snd_kcontrol *k, int event) |
| 1911 | { | 1898 | { |
| @@ -2242,7 +2229,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { · 330 unmodified lines | |||
| 2242 | SND_SOC_DAPM_OUTPUT("PDM1R"), | 2229 | SND_SOC_DAPM_OUTPUT("PDM1R"), |
| 2243 | SND_SOC_DAPM_OUTPUT("SPOL"), | 2230 | SND_SOC_DAPM_OUTPUT("SPOL"), |
| 2244 | SND_SOC_DAPM_OUTPUT("SPOR"), | 2231 | SND_SOC_DAPM_OUTPUT("SPOR"), |
| 2245 | SND_SOC_DAPM_POST("DAPM_POST", rt5650_hp_event), | ||
| 2246 | }; | 2232 | }; |
| 2247 | 2233 | ||
| 2248 | static const struct snd_soc_dapm_widget rt5645_specific_dapm_widgets[] = { | 2234 | static const struct snd_soc_dapm_widget rt5645_specific_dapm_widgets[] = { |
| @@ -3261,6 +3247,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) · 1012 unmodified lines | |||
| 3261 | case 0: /* Not using rt5645 JD */ | 3247 | case 0: /* Not using rt5645 JD */ |
| 3262 | if (rt5645->gpiod_hp_det) { | 3248 | if (rt5645->gpiod_hp_det) { |
| 3263 | gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); | 3249 | gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); |
| 3250 | if (rt5645->pdata.inv_hp_pol) | ||
| 3251 | gpio_state ^= 1; | ||
| 3264 | dev_dbg(rt5645->component->dev, "gpio_state = %d\n", | 3252 | dev_dbg(rt5645->component->dev, "gpio_state = %d\n", |
| 3265 | gpio_state); | 3253 | gpio_state); |
| 3266 | report = rt5645_jack_detect(rt5645->component, gpio_state); | 3254 | report = rt5645_jack_detect(rt5645->component, gpio_state); |
| @@ -3651,6 +3639,25 @@ static const struct rt5645_platform_data kahlee_platform_data = { · 384 unmodified lines | |||
| 3651 | .jd_mode = 3, | 3639 | .jd_mode = 3, |
| 3652 | }; | 3640 | }; |
| 3653 | 3641 | ||
| 3642 | static const struct rt5645_platform_data ecs_ef20_platform_data = { | ||
| 3643 | .dmic1_data_pin = RT5645_DMIC1_DISABLE, | ||
| 3644 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | ||
| 3645 | .inv_hp_pol = 1, | ||
| 3646 | }; | ||
| 3647 | |||
| 3648 | static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false }; | ||
| 3649 | |||
| 3650 | static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = { | ||
| 3651 | { "hp-detect-gpios", &ef20_hp_detect, 1 }, | ||
| 3652 | { }, | ||
| 3653 | }; | ||
| 3654 | |||
| 3655 | static int cht_rt5645_ef20_quirk_cb(const struct dmi_system_id *id) | ||
| 3656 | { | ||
| 3657 | cht_rt5645_gpios = cht_rt5645_ef20_gpios; | ||
| 3658 | return 1; | ||
| 3659 | } | ||
| 3660 | |||
| 3654 | static const struct dmi_system_id dmi_platform_data[] = { | 3661 | static const struct dmi_system_id dmi_platform_data[] = { |
| 3655 | { | 3662 | { |
| 3656 | .ident = "Chrome Buddy", | 3663 | .ident = "Chrome Buddy", |
| @@ -3780,6 +3787,22 @@ static const struct dmi_system_id dmi_platform_data[] = { · 123 unmodified lines | |||
| 3780 | }, | 3787 | }, |
| 3781 | .driver_data = (void *)&intel_braswell_platform_data, | 3788 | .driver_data = (void *)&intel_braswell_platform_data, |
| 3782 | }, | 3789 | }, |
| 3790 | { | ||
| 3791 | .ident = "EF20", | ||
| 3792 | .callback = cht_rt5645_ef20_quirk_cb, | ||
| 3793 | .matches = { | ||
| 3794 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20"), | ||
| 3795 | }, | ||
| 3796 | .driver_data = (void *)&ecs_ef20_platform_data, | ||
| 3797 | }, | ||
| 3798 | { | ||
| 3799 | .ident = "EF20EA", | ||
| 3800 | .callback = cht_rt5645_ef20_quirk_cb, | ||
| 3801 | .matches = { | ||
| 3802 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | ||
| 3803 | }, | ||
| 3804 | .driver_data = (void *)&ecs_ef20_platform_data, | ||
| 3805 | }, | ||
| 3783 | { } | 3806 | { } |
| 3784 | }; | 3807 | }; |
| 3785 | 3808 | ||
| @@ -3843,11 +3866,16 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, · 57 unmodified lines | |||
| 3843 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); | 3866 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); |
| 3844 | rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); | 3867 | rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); |
| 3845 | rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); | 3868 | rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); |
| 3869 | rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk); | ||
| 3846 | rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); | 3870 | rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); |
| 3847 | rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); | 3871 | rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); |
| 3848 | rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); | 3872 | rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk); |
| 3849 | } | 3873 | } |
| 3850 | 3874 | ||
| 3875 | if (cht_rt5645_gpios && has_acpi_companion(&i2c->dev)) | ||
| 3876 | if (devm_acpi_dev_add_driver_gpios(&i2c->dev, cht_rt5645_gpios)) | ||
| 3877 | dev_dbg(&i2c->dev, "Failed to add driver gpios\n"); | ||
| 3878 | |||
| 3851 | rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", | 3879 | rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", |
| 3852 | GPIOD_IN); | 3880 | GPIOD_IN); |
| 3853 | 3881 | ||
| @@ -2741,7 +2741,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { · 2740 unmodified lines | |||
| 2741 | .formats = RT5670_FORMATS, | 2741 | .formats = RT5670_FORMATS, |
| 2742 | }, | 2742 | }, |
| 2743 | .ops = &rt5670_aif_dai_ops, | 2743 | .ops = &rt5670_aif_dai_ops, |
| 2744 | .symmetric_rates = 1, | 2744 | .symmetric_rate = 1, |
| 2745 | }, | 2745 | }, |
| 2746 | { | 2746 | { |
| 2747 | .name = "rt5670-aif2", | 2747 | .name = "rt5670-aif2", |
| @@ -2761,7 +2761,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { · 13 unmodified lines | |||
| 2761 | .formats = RT5670_FORMATS, | 2761 | .formats = RT5670_FORMATS, |
| 2762 | }, | 2762 | }, |
| 2763 | .ops = &rt5670_aif_dai_ops, | 2763 | .ops = &rt5670_aif_dai_ops, |
| 2764 | .symmetric_rates = 1, | 2764 | .symmetric_rate = 1, |
| 2765 | }, | 2765 | }, |
| 2766 | }; | 2766 | }; |
| 2767 | 2767 | ||
| @@ -273,6 +273,9 @@ static void rt5682_i2c_shutdown(struct i2c_client *client) · 272 unmodified lines | |||
| 273 | { | 273 | { |
| 274 | struct rt5682_priv *rt5682 = i2c_get_clientdata(client); | 274 | struct rt5682_priv *rt5682 = i2c_get_clientdata(client); |
| 275 | 275 | ||
| 276 | cancel_delayed_work_sync(&rt5682->jack_detect_work); | ||
| 277 | cancel_delayed_work_sync(&rt5682->jd_check_work); | ||
| 278 | |||
| 276 | rt5682_reset(rt5682); | 279 | rt5682_reset(rt5682); |
| 277 | } | 280 | } |
| 278 | 281 | ||
| @@ -375,18 +375,12 @@ static int rt5682_sdw_init(struct device *dev, struct regmap *regmap, · 374 unmodified lines | |||
| 375 | static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) | 375 | static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) |
| 376 | { | 376 | { |
| 377 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); | 377 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
| 378 | int ret = 0; | 378 | int ret = 0, loop = 10; |
| 379 | unsigned int val; | 379 | unsigned int val; |
| 380 | 380 | ||
| 381 | if (rt5682->hw_init) | 381 | if (rt5682->hw_init) |
| 382 | return 0; | 382 | return 0; |
| 383 | 383 | ||
| 384 | regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val); | ||
| 385 | if (val != DEVICE_ID) { | ||
| 386 | dev_err(dev, "Device with ID register %x is not rt5682\n", val); | ||
| 387 | return -ENODEV; | ||
| 388 | } | ||
| 389 | |||
| 390 | /* | 384 | /* |
| 391 | * PM runtime is only enabled when a Slave reports as Attached | 385 | * PM runtime is only enabled when a Slave reports as Attached |
| 392 | */ | 386 | */ |
| @@ -406,6 +400,19 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) · 13 unmodified lines | |||
| 406 | 400 | ||
| 407 | pm_runtime_get_noresume(&slave->dev); | 401 | pm_runtime_get_noresume(&slave->dev); |
| 408 | 402 | ||
| 403 | while (loop > 0) { | ||
| 404 | regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val); | ||
| 405 | if (val == DEVICE_ID) | ||
| 406 | break; | ||
| 407 | dev_warn(dev, "Device with ID register %x is not rt5682\n", val); | ||
| 408 | usleep_range(30000, 30005); | ||
| 409 | loop--; | ||
| 410 | } | ||
| 411 | if (val != DEVICE_ID) { | ||
| 412 | dev_err(dev, "Device with ID register %x is not rt5682\n", val); | ||
| 413 | return -ENODEV; | ||
| 414 | } | ||
| 415 | |||
| 409 | if (rt5682->first_hw_init) { | 416 | if (rt5682->first_hw_init) { |
| 410 | regcache_cache_only(rt5682->regmap, false); | 417 | regcache_cache_only(rt5682->regmap, false); |
| 411 | regcache_cache_bypass(rt5682->regmap, true); | 418 | regcache_cache_bypass(rt5682->regmap, true); |
| @@ -703,7 +710,7 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) · 291 unmodified lines | |||
| 703 | struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); | 710 | struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); |
| 704 | 711 | ||
| 705 | if (rt5682 && rt5682->hw_init) | 712 | if (rt5682 && rt5682->hw_init) |
| 706 | cancel_delayed_work(&rt5682->jack_detect_work); | 713 | cancel_delayed_work_sync(&rt5682->jack_detect_work); |
| 707 | 714 | ||
| 708 | return 0; | 715 | return 0; |
| 709 | } | 716 | } |
| @@ -721,6 +728,8 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev) · 11 unmodified lines | |||
| 721 | if (!rt5682->hw_init) | 728 | if (!rt5682->hw_init) |
| 722 | return 0; | 729 | return 0; |
| 723 | 730 | ||
| 731 | cancel_delayed_work_sync(&rt5682->jack_detect_work); | ||
| 732 | |||
| 724 | regcache_cache_only(rt5682->regmap, true); | 733 | regcache_cache_only(rt5682->regmap, true); |
| 725 | regcache_mark_dirty(rt5682->regmap); | 734 | regcache_mark_dirty(rt5682->regmap); |
| 726 | 735 | ||
| @@ -953,6 +953,8 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) · 952 unmodified lines | |||
| 953 | case 0x1: | 953 | case 0x1: |
| 954 | case 0x2: | 954 | case 0x2: |
| 955 | rt5682->jack_type = SND_JACK_HEADSET; | 955 | rt5682->jack_type = SND_JACK_HEADSET; |
| 956 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | ||
| 957 | RT5682_FAST_OFF_MASK, RT5682_FAST_OFF_EN); | ||
| 956 | rt5682_enable_push_button_irq(component, true); | 958 | rt5682_enable_push_button_irq(component, true); |
| 957 | break; | 959 | break; |
| 958 | default: | 960 | default: |
| @@ -982,6 +984,8 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) · 23 unmodified lines | |||
| 982 | snd_soc_component_update_bits(component, RT5682_MICBIAS_2, | 984 | snd_soc_component_update_bits(component, RT5682_MICBIAS_2, |
| 983 | RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK, | 985 | RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK, |
| 984 | RT5682_PWR_CLK25M_PD | RT5682_PWR_CLK1M_PD); | 986 | RT5682_PWR_CLK25M_PD | RT5682_PWR_CLK1M_PD); |
| 987 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | ||
| 988 | RT5682_FAST_OFF_MASK, RT5682_FAST_OFF_DIS); | ||
| 985 | 989 | ||
| 986 | rt5682->jack_type = 0; | 990 | rt5682->jack_type = 0; |
| 987 | } | 991 | } |
| @@ -1011,11 +1015,13 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, · 23 unmodified lines | |||
| 1011 | if (!rt5682->is_sdw) { | 1015 | if (!rt5682->is_sdw) { |
| 1012 | switch (rt5682->pdata.jd_src) { | 1016 | switch (rt5682->pdata.jd_src) { |
| 1013 | case RT5682_JD1: | 1017 | case RT5682_JD1: |
| 1018 | snd_soc_component_update_bits(component, | ||
| 1019 | RT5682_CBJ_CTRL_5, 0x0700, 0x0600); | ||
| 1014 | snd_soc_component_update_bits(component, | 1020 | snd_soc_component_update_bits(component, |
| 1015 | RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, | 1021 | RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, |
| 1016 | RT5682_EXT_JD_SRC_MANUAL); | 1022 | RT5682_EXT_JD_SRC_MANUAL); |
| 1017 | snd_soc_component_write(component, RT5682_CBJ_CTRL_1, | 1023 | snd_soc_component_write(component, RT5682_CBJ_CTRL_1, |
| 1018 | 0xd042); | 1024 | 0xd142); |
| 1019 | snd_soc_component_update_bits(component, | 1025 | snd_soc_component_update_bits(component, |
| 1020 | RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, | 1026 | RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, |
| 1021 | RT5682_CBJ_IN_BUF_EN); | 1027 | RT5682_CBJ_IN_BUF_EN); |
| @@ -1848,8 +1854,6 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { · 826 unmodified lines | |||
| 1848 | 1854 | ||
| 1849 | {"CLKDET SYS", NULL, "CLKDET"}, | 1855 | {"CLKDET SYS", NULL, "CLKDET"}, |
| 1850 | 1856 | ||
| 1851 | {"IN1P", NULL, "LDO2"}, | ||
| 1852 | |||
| 1853 | {"BST1 CBJ", NULL, "IN1P"}, | 1857 | {"BST1 CBJ", NULL, "IN1P"}, |
| 1854 | 1858 | ||
| 1855 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, | 1859 | {"RECMIX1L", "CBJ Switch", "BST1 CBJ"}, |
| @@ -2906,6 +2910,9 @@ static int rt5682_suspend(struct snd_soc_component *component) · 1050 unmodified lines | |||
| 2906 | { | 2910 | { |
| 2907 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 2911 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 2908 | 2912 | ||
| 2913 | if (rt5682->is_sdw) | ||
| 2914 | return 0; | ||
| 2915 | |||
| 2909 | regcache_cache_only(rt5682->regmap, true); | 2916 | regcache_cache_only(rt5682->regmap, true); |
| 2910 | regcache_mark_dirty(rt5682->regmap); | 2917 | regcache_mark_dirty(rt5682->regmap); |
| 2911 | return 0; | 2918 | return 0; |
| @@ -2915,6 +2922,9 @@ static int rt5682_resume(struct snd_soc_component *component) · 3 unmodified lines | |||
| 2915 | { | 2922 | { |
| 2916 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); | 2923 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 2917 | 2924 | ||
| 2925 | if (rt5682->is_sdw) | ||
| 2926 | return 0; | ||
| 2927 | |||
| 2918 | regcache_cache_only(rt5682->regmap, false); | 2928 | regcache_cache_only(rt5682->regmap, false); |
| 2919 | regcache_sync(rt5682->regmap); | 2929 | regcache_sync(rt5682->regmap); |
| 2920 | 2930 | ||
| @@ -1356,7 +1356,7 @@ · 1355 unmodified lines | |||
| 1356 | #define RT5682_SAR_SOUR_TYPE (0x0) | 1356 | #define RT5682_SAR_SOUR_TYPE (0x0) |
| 1357 | 1357 | ||
| 1358 | /* soundwire timeout */ | 1358 | /* soundwire timeout */ |
| 1359 | #define RT5682_PROBE_TIMEOUT 2000 | 1359 | #define RT5682_PROBE_TIMEOUT 5000 |
| 1360 | 1360 | ||
| 1361 | 1361 | ||
| 1362 | #define RT5682_STEREO_RATES SNDRV_PCM_RATE_8000_192000 | 1362 | #define RT5682_STEREO_RATES SNDRV_PCM_RATE_8000_192000 |
| @@ -462,8 +462,8 @@ static int rt700_sdw_remove(struct sdw_slave *slave) · 461 unmodified lines | |||
| 462 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); | 462 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); |
| 463 | 463 | ||
| 464 | if (rt700 && rt700->hw_init) { | 464 | if (rt700 && rt700->hw_init) { |
| 465 | cancel_delayed_work(&rt700->jack_detect_work); | 465 | cancel_delayed_work_sync(&rt700->jack_detect_work); |
| 466 | cancel_delayed_work(&rt700->jack_btn_check_work); | 466 | cancel_delayed_work_sync(&rt700->jack_btn_check_work); |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | return 0; | 469 | return 0; |
| @@ -490,7 +490,7 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev) · 20 unmodified lines | |||
| 490 | return 0; | 490 | return 0; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | #define RT700_PROBE_TIMEOUT 2000 | 493 | #define RT700_PROBE_TIMEOUT 5000 |
| 494 | 494 | ||
| 495 | static int __maybe_unused rt700_dev_resume(struct device *dev) | 495 | static int __maybe_unused rt700_dev_resume(struct device *dev) |
| 496 | { | 496 | { |
| @@ -463,8 +463,8 @@ static int rt711_sdw_remove(struct sdw_slave *slave) · 462 unmodified lines | |||
| 463 | struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); | 463 | struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); |
| 464 | 464 | ||
| 465 | if (rt711 && rt711->hw_init) { | 465 | if (rt711 && rt711->hw_init) { |
| 466 | cancel_delayed_work(&rt711->jack_detect_work); | 466 | cancel_delayed_work_sync(&rt711->jack_detect_work); |
| 467 | cancel_delayed_work(&rt711->jack_btn_check_work); | 467 | cancel_delayed_work_sync(&rt711->jack_btn_check_work); |
| 468 | cancel_work_sync(&rt711->calibration_work); | 468 | cancel_work_sync(&rt711->calibration_work); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| @@ -493,7 +493,7 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev) · 22 unmodified lines | |||
| 493 | return 0; | 493 | return 0; |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | #define RT711_PROBE_TIMEOUT 2000 | 496 | #define RT711_PROBE_TIMEOUT 5000 |
| 497 | 497 | ||
| 498 | static int __maybe_unused rt711_dev_resume(struct device *dev) | 498 | static int __maybe_unused rt711_dev_resume(struct device *dev) |
| 499 | { | 499 | { |
| @@ -533,7 +533,7 @@ static int __maybe_unused rt715_dev_suspend(struct device *dev) · 532 unmodified lines | |||
| 533 | return 0; | 533 | return 0; |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | #define RT715_PROBE_TIMEOUT 2000 | 536 | #define RT715_PROBE_TIMEOUT 5000 |
| 537 | 537 | ||
| 538 | static int __maybe_unused rt715_dev_resume(struct device *dev) | 538 | static int __maybe_unused rt715_dev_resume(struct device *dev) |
| 539 | { | 539 | { |
| @@ -1187,7 +1187,7 @@ static struct snd_soc_dai_driver sgtl5000_dai = { · 1186 unmodified lines | |||
| 1187 | .formats = SGTL5000_FORMATS, | 1187 | .formats = SGTL5000_FORMATS, |
| 1188 | }, | 1188 | }, |
| 1189 | .ops = &sgtl5000_ops, | 1189 | .ops = &sgtl5000_ops, |
| 1190 | .symmetric_rates = 1, | 1190 | .symmetric_rate = 1, |
| 1191 | }; | 1191 | }; |
| 1192 | 1192 | ||
| 1193 | static bool sgtl5000_volatile(struct device *dev, unsigned int reg) | 1193 | static bool sgtl5000_volatile(struct device *dev, unsigned int reg) |
| @@ -1,575 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | /* | ||
| 3 | * SiRF audio codec driver | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/platform_device.h> | ||
| 10 | #include <linux/pm_runtime.h> | ||
| 11 | #include <linux/of.h> | ||
| 12 | #include <linux/of_device.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/io.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/initval.h> | ||
| 21 | #include <sound/tlv.h> | ||
| 22 | #include <sound/soc.h> | ||
| 23 | #include <sound/dmaengine_pcm.h> | ||
| 24 | |||
| 25 | #include "sirf-audio-codec.h" | ||
| 26 | |||
| 27 | struct sirf_audio_codec { | ||
| 28 | struct clk *clk; | ||
| 29 | struct regmap *regmap; | ||
| 30 | u32 reg_ctrl0, reg_ctrl1; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const char * const input_mode_mux[] = {"Single-ended", | ||
| 34 | "Differential"}; | ||
| 35 | |||
| 36 | static const struct soc_enum input_mode_mux_enum = | ||
| 37 | SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux); | ||
| 38 | |||
| 39 | static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control = | ||
| 40 | SOC_DAPM_ENUM("Route", input_mode_mux_enum); | ||
| 41 | |||
| 42 | static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0); | ||
| 43 | static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0); | ||
| 44 | static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6, | ||
| 45 | 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0), | ||
| 46 | 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0), | ||
| 47 | ); | ||
| 48 | |||
| 49 | static struct snd_kcontrol_new volume_controls_atlas6[] = { | ||
| 50 | SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, | ||
| 51 | 0x7F, 0, playback_vol_tlv), | ||
| 52 | SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10, | ||
| 53 | 0x3F, 0, capture_vol_tlv_atlas6), | ||
| 54 | }; | ||
| 55 | |||
| 56 | static struct snd_kcontrol_new volume_controls_prima2[] = { | ||
| 57 | SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, | ||
| 58 | 0x7F, 0, playback_vol_tlv), | ||
| 59 | SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10, | ||
| 60 | 0x1F, 0, capture_vol_tlv_prima2), | ||
| 61 | }; | ||
| 62 | |||
| 63 | static struct snd_kcontrol_new left_input_path_controls[] = { | ||
| 64 | SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0), | ||
| 65 | SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0), | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct snd_kcontrol_new right_input_path_controls[] = { | ||
| 69 | SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0), | ||
| 70 | SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0), | ||
| 71 | }; | ||
| 72 | |||
| 73 | static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control = | ||
| 74 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0); | ||
| 75 | |||
| 76 | static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control = | ||
| 77 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0); | ||
| 78 | |||
| 79 | static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control = | ||
| 80 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0); | ||
| 81 | |||
| 82 | static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control = | ||
| 83 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0); | ||
| 84 | |||
| 85 | static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control = | ||
| 86 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0); | ||
| 87 | |||
| 88 | static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control = | ||
| 89 | SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0); | ||
| 90 | |||
| 91 | /* After enable adc, Delay 200ms to avoid pop noise */ | ||
| 92 | static int adc_enable_delay_event(struct snd_soc_dapm_widget *w, | ||
| 93 | struct snd_kcontrol *kcontrol, int event) | ||
| 94 | { | ||
| 95 | switch (event) { | ||
| 96 | case SND_SOC_DAPM_POST_PMU: | ||
| 97 | msleep(200); | ||
| 98 | break; | ||
| 99 | default: | ||
| 100 | break; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static void enable_and_reset_codec(struct regmap *regmap, | ||
| 107 | u32 codec_enable_bits, u32 codec_reset_bits) | ||
| 108 | { | ||
| 109 | regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, | ||
| 110 | codec_enable_bits | codec_reset_bits, | ||
| 111 | codec_enable_bits); | ||
| 112 | msleep(20); | ||
| 113 | regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, | ||
| 114 | codec_reset_bits, codec_reset_bits); | ||
| 115 | } | ||
| 116 | |||
| 117 | static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, | ||
| 118 | struct snd_kcontrol *kcontrol, int event) | ||
| 119 | { | ||
| 120 | #define ATLAS6_CODEC_ENABLE_BITS (1 << 29) | ||
| 121 | #define ATLAS6_CODEC_RESET_BITS (1 << 28) | ||
| 122 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 123 | struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); | ||
| 124 | switch (event) { | ||
| 125 | case SND_SOC_DAPM_PRE_PMU: | ||
| 126 | enable_and_reset_codec(sirf_audio_codec->regmap, | ||
| 127 | ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS); | ||
| 128 | break; | ||
| 129 | case SND_SOC_DAPM_POST_PMD: | ||
| 130 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 131 | AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 0); | ||
| 132 | break; | ||
| 133 | default: | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, | ||
| 141 | struct snd_kcontrol *kcontrol, int event) | ||
| 142 | { | ||
| 143 | #define PRIMA2_CODEC_ENABLE_BITS (1 << 27) | ||
| 144 | #define PRIMA2_CODEC_RESET_BITS (1 << 26) | ||
| 145 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 146 | struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); | ||
| 147 | switch (event) { | ||
| 148 | case SND_SOC_DAPM_POST_PMU: | ||
| 149 | enable_and_reset_codec(sirf_audio_codec->regmap, | ||
| 150 | PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS); | ||
| 151 | break; | ||
| 152 | case SND_SOC_DAPM_POST_PMD: | ||
| 153 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 154 | AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 0); | ||
| 155 | break; | ||
| 156 | default: | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = { | ||
| 164 | SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 165 | 25, 0, NULL, 0), | ||
| 166 | SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 167 | 26, 0, NULL, 0), | ||
| 168 | SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 169 | 27, 0, NULL, 0), | ||
| 170 | }; | ||
| 171 | |||
| 172 | static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = { | ||
| 173 | SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 174 | 23, 0, NULL, 0), | ||
| 175 | SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 176 | 24, 0, NULL, 0), | ||
| 177 | SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, | ||
| 178 | 25, 0, NULL, 0), | ||
| 179 | }; | ||
| 180 | |||
| 181 | static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget = | ||
| 182 | SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, | ||
| 183 | atlas6_codec_enable_and_reset_event, | ||
| 184 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); | ||
| 185 | |||
| 186 | static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget = | ||
| 187 | SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, | ||
| 188 | prima2_codec_enable_and_reset_event, | ||
| 189 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); | ||
| 190 | |||
| 191 | static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = { | ||
| 192 | SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0), | ||
| 193 | SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0), | ||
| 194 | SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0, | ||
| 195 | &left_dac_to_hp_left_amp_switch_control), | ||
| 196 | SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0, | ||
| 197 | &left_dac_to_hp_right_amp_switch_control), | ||
| 198 | SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0, | ||
| 199 | &right_dac_to_hp_left_amp_switch_control), | ||
| 200 | SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0, | ||
| 201 | &right_dac_to_hp_right_amp_switch_control), | ||
| 202 | SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0, | ||
| 203 | NULL, 0), | ||
| 204 | SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0, | ||
| 205 | NULL, 0), | ||
| 206 | |||
| 207 | SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0, | ||
| 208 | &left_dac_to_speaker_lineout_switch_control), | ||
| 209 | SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0, | ||
| 210 | &right_dac_to_speaker_lineout_switch_control), | ||
| 211 | SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0, | ||
| 212 | NULL, 0), | ||
| 213 | |||
| 214 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | ||
| 215 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | ||
| 216 | SND_SOC_DAPM_OUTPUT("SPKOUT"), | ||
| 217 | |||
| 218 | SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0, | ||
| 219 | adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), | ||
| 220 | SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0, | ||
| 221 | adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), | ||
| 222 | SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0, | ||
| 223 | &left_input_path_controls[0], | ||
| 224 | ARRAY_SIZE(left_input_path_controls)), | ||
| 225 | SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0, | ||
| 226 | &right_input_path_controls[0], | ||
| 227 | ARRAY_SIZE(right_input_path_controls)), | ||
| 228 | |||
| 229 | SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0, | ||
| 230 | &sirf_audio_codec_input_mode_control), | ||
| 231 | SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0), | ||
| 232 | SND_SOC_DAPM_INPUT("MICIN1"), | ||
| 233 | SND_SOC_DAPM_INPUT("MICIN2"), | ||
| 234 | SND_SOC_DAPM_INPUT("LINEIN1"), | ||
| 235 | SND_SOC_DAPM_INPUT("LINEIN2"), | ||
| 236 | |||
| 237 | SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0, | ||
| 238 | 30, 0, NULL, 0), | ||
| 239 | }; | ||
| 240 | |||
| 241 | static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { | ||
| 242 | {"SPKOUT", NULL, "Speaker Driver"}, | ||
| 243 | {"Speaker Driver", NULL, "Speaker amp driver"}, | ||
| 244 | {"Speaker amp driver", NULL, "Left dac to speaker lineout"}, | ||
| 245 | {"Speaker amp driver", NULL, "Right dac to speaker lineout"}, | ||
| 246 | {"Left dac to speaker lineout", "Switch", "DAC left"}, | ||
| 247 | {"Right dac to speaker lineout", "Switch", "DAC right"}, | ||
| 248 | {"HPOUTL", NULL, "HP Left Driver"}, | ||
| 249 | {"HPOUTR", NULL, "HP Right Driver"}, | ||
| 250 | {"HP Left Driver", NULL, "HP amp left driver"}, | ||
| 251 | {"HP Right Driver", NULL, "HP amp right driver"}, | ||
| 252 | {"HP amp left driver", NULL, "Right dac to hp left amp"}, | ||
| 253 | {"HP amp right driver", NULL , "Right dac to hp right amp"}, | ||
| 254 | {"HP amp left driver", NULL, "Left dac to hp left amp"}, | ||
| 255 | {"HP amp right driver", NULL , "Right dac to hp right amp"}, | ||
| 256 | {"Right dac to hp left amp", "Switch", "DAC left"}, | ||
| 257 | {"Right dac to hp right amp", "Switch", "DAC right"}, | ||
| 258 | {"Left dac to hp left amp", "Switch", "DAC left"}, | ||
| 259 | {"Left dac to hp right amp", "Switch", "DAC right"}, | ||
| 260 | {"DAC left", NULL, "codecclk"}, | ||
| 261 | {"DAC right", NULL, "codecclk"}, | ||
| 262 | {"DAC left", NULL, "Playback"}, | ||
| 263 | {"DAC right", NULL, "Playback"}, | ||
| 264 | {"DAC left", NULL, "HSL Phase Opposite"}, | ||
| 265 | {"DAC right", NULL, "HSL Phase Opposite"}, | ||
| 266 | |||
| 267 | {"Capture", NULL, "ADC left"}, | ||
| 268 | {"Capture", NULL, "ADC right"}, | ||
| 269 | {"ADC left", NULL, "codecclk"}, | ||
| 270 | {"ADC right", NULL, "codecclk"}, | ||
| 271 | {"ADC left", NULL, "Left PGA mixer"}, | ||
| 272 | {"ADC right", NULL, "Right PGA mixer"}, | ||
| 273 | {"Left PGA mixer", "Line Left Switch", "LINEIN2"}, | ||
| 274 | {"Right PGA mixer", "Line Right Switch", "LINEIN1"}, | ||
| 275 | {"Left PGA mixer", "Mic Left Switch", "MICIN2"}, | ||
| 276 | {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"}, | ||
| 277 | {"Mic input mode mux", "Single-ended", "MICIN1"}, | ||
| 278 | {"Mic input mode mux", "Differential", "MICIN1"}, | ||
| 279 | }; | ||
| 280 | |||
| 281 | static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) | ||
| 282 | { | ||
| 283 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
| 284 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
| 285 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
| 286 | AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); | ||
| 287 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); | ||
| 288 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
| 289 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
| 290 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
| 291 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 292 | AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); | ||
| 293 | } | ||
| 294 | |||
| 295 | static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) | ||
| 296 | { | ||
| 297 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
| 298 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 299 | AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); | ||
| 300 | } | ||
| 301 | |||
| 302 | static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, | ||
| 303 | int channels) | ||
| 304 | { | ||
| 305 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
| 306 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
| 307 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
| 308 | AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); | ||
| 309 | regmap_write(sirf_audio_codec->regmap, | ||
| 310 | AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); | ||
| 311 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); | ||
| 312 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
| 313 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
| 314 | if (channels == 1) | ||
| 315 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 316 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
| 317 | IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); | ||
| 318 | else | ||
| 319 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 320 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
| 321 | IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); | ||
| 322 | } | ||
| 323 | |||
| 324 | static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) | ||
| 325 | { | ||
| 326 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 327 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
| 328 | IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); | ||
| 329 | } | ||
| 330 | |||
| 331 | static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, | ||
| 332 | int cmd, | ||
| 333 | struct snd_soc_dai *dai) | ||
| 334 | { | ||
| 335 | struct snd_soc_component *component = dai->component; | ||
| 336 | struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component); | ||
| 337 | int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
| 338 | |||
| 339 | /* | ||
| 340 | * This is a workaround, When stop playback, | ||
| 341 | * need disable HP amp, avoid the current noise. | ||
| 342 | */ | ||
| 343 | switch (cmd) { | ||
| 344 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 345 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 346 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 347 | if (playback) { | ||
| 348 | snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, | ||
| 349 | IC_HSLEN | IC_HSREN, 0); | ||
| 350 | sirf_audio_codec_tx_disable(sirf_audio_codec); | ||
| 351 | } else | ||
| 352 | sirf_audio_codec_rx_disable(sirf_audio_codec); | ||
| 353 | break; | ||
| 354 | case SNDRV_PCM_TRIGGER_START: | ||
| 355 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 356 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 357 | if (playback) { | ||
| 358 | sirf_audio_codec_tx_enable(sirf_audio_codec); | ||
| 359 | snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0, | ||
| 360 | IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); | ||
| 361 | } else | ||
| 362 | sirf_audio_codec_rx_enable(sirf_audio_codec, | ||
| 363 | substream->runtime->channels); | ||
| 364 | break; | ||
| 365 | default: | ||
| 366 | return -EINVAL; | ||
| 367 | } | ||
| 368 | |||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | |||
| 372 | static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { | ||
| 373 | .trigger = sirf_audio_codec_trigger, | ||
| 374 | }; | ||
| 375 | |||
| 376 | static struct snd_soc_dai_driver sirf_audio_codec_dai = { | ||
| 377 | .name = "sirf-audio-codec", | ||
| 378 | .playback = { | ||
| 379 | .stream_name = "Playback", | ||
| 380 | .channels_min = 2, | ||
| 381 | .channels_max = 2, | ||
| 382 | .rates = SNDRV_PCM_RATE_48000, | ||
| 383 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 384 | }, | ||
| 385 | .capture = { | ||
| 386 | .stream_name = "Capture", | ||
| 387 | .channels_min = 1, | ||
| 388 | .channels_max = 2, | ||
| 389 | .rates = SNDRV_PCM_RATE_48000, | ||
| 390 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 391 | }, | ||
| 392 | .ops = &sirf_audio_codec_dai_ops, | ||
| 393 | }; | ||
| 394 | |||
| 395 | static int sirf_audio_codec_probe(struct snd_soc_component *component) | ||
| 396 | { | ||
| 397 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); | ||
| 398 | |||
| 399 | pm_runtime_enable(component->dev); | ||
| 400 | |||
| 401 | if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) { | ||
| 402 | snd_soc_dapm_new_controls(dapm, | ||
| 403 | prima2_output_driver_dapm_widgets, | ||
| 404 | ARRAY_SIZE(prima2_output_driver_dapm_widgets)); | ||
| 405 | snd_soc_dapm_new_controls(dapm, | ||
| 406 | &prima2_codec_clock_dapm_widget, 1); | ||
| 407 | return snd_soc_add_component_controls(component, | ||
| 408 | volume_controls_prima2, | ||
| 409 | ARRAY_SIZE(volume_controls_prima2)); | ||
| 410 | } | ||
| 411 | if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) { | ||
| 412 | snd_soc_dapm_new_controls(dapm, | ||
| 413 | atlas6_output_driver_dapm_widgets, | ||
| 414 | ARRAY_SIZE(atlas6_output_driver_dapm_widgets)); | ||
| 415 | snd_soc_dapm_new_controls(dapm, | ||
| 416 | &atlas6_codec_clock_dapm_widget, 1); | ||
| 417 | return snd_soc_add_component_controls(component, | ||
| 418 | volume_controls_atlas6, | ||
| 419 | ARRAY_SIZE(volume_controls_atlas6)); | ||
| 420 | } | ||
| 421 | |||
| 422 | return -EINVAL; | ||
| 423 | } | ||
| 424 | |||
| 425 | static void sirf_audio_codec_remove(struct snd_soc_component *component) | ||
| 426 | { | ||
| 427 | pm_runtime_disable(component->dev); | ||
| 428 | } | ||
| 429 | |||
| 430 | static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = { | ||
| 431 | .probe = sirf_audio_codec_probe, | ||
| 432 | .remove = sirf_audio_codec_remove, | ||
| 433 | .dapm_widgets = sirf_audio_codec_dapm_widgets, | ||
| 434 | .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), | ||
| 435 | .dapm_routes = sirf_audio_codec_map, | ||
| 436 | .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), | ||
| 437 | .use_pmdown_time = 1, | ||
| 438 | .endianness = 1, | ||
| 439 | .non_legacy_dai_naming = 1, | ||
| 440 | }; | ||
| 441 | |||
| 442 | static const struct of_device_id sirf_audio_codec_of_match[] = { | ||
| 443 | { .compatible = "sirf,prima2-audio-codec" }, | ||
| 444 | { .compatible = "sirf,atlas6-audio-codec" }, | ||
| 445 | {} | ||
| 446 | }; | ||
| 447 | MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match); | ||
| 448 | |||
| 449 | static const struct regmap_config sirf_audio_codec_regmap_config = { | ||
| 450 | .reg_bits = 32, | ||
| 451 | .reg_stride = 4, | ||
| 452 | .val_bits = 32, | ||
| 453 | .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, | ||
| 454 | .cache_type = REGCACHE_NONE, | ||
| 455 | }; | ||
| 456 | |||
| 457 | static int sirf_audio_codec_driver_probe(struct platform_device *pdev) | ||
| 458 | { | ||
| 459 | int ret; | ||
| 460 | struct sirf_audio_codec *sirf_audio_codec; | ||
| 461 | void __iomem *base; | ||
| 462 | |||
| 463 | sirf_audio_codec = devm_kzalloc(&pdev->dev, | ||
| 464 | sizeof(struct sirf_audio_codec), GFP_KERNEL); | ||
| 465 | if (!sirf_audio_codec) | ||
| 466 | return -ENOMEM; | ||
| 467 | |||
| 468 | platform_set_drvdata(pdev, sirf_audio_codec); | ||
| 469 | |||
| 470 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 471 | if (IS_ERR(base)) | ||
| 472 | return PTR_ERR(base); | ||
| 473 | |||
| 474 | sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | ||
| 475 | &sirf_audio_codec_regmap_config); | ||
| 476 | if (IS_ERR(sirf_audio_codec->regmap)) | ||
| 477 | return PTR_ERR(sirf_audio_codec->regmap); | ||
| 478 | |||
| 479 | sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 480 | if (IS_ERR(sirf_audio_codec->clk)) { | ||
| 481 | dev_err(&pdev->dev, "Get clock failed.\n"); | ||
| 482 | return PTR_ERR(sirf_audio_codec->clk); | ||
| 483 | } | ||
| 484 | |||
| 485 | ret = clk_prepare_enable(sirf_audio_codec->clk); | ||
| 486 | if (ret) { | ||
| 487 | dev_err(&pdev->dev, "Enable clock failed.\n"); | ||
| 488 | return ret; | ||
| 489 | } | ||
| 490 | |||
| 491 | ret = devm_snd_soc_register_component(&(pdev->dev), | ||
| 492 | &soc_codec_device_sirf_audio_codec, | ||
| 493 | &sirf_audio_codec_dai, 1); | ||
| 494 | if (ret) { | ||
| 495 | dev_err(&pdev->dev, "Register Audio Codec dai failed.\n"); | ||
| 496 | goto err_clk_put; | ||
| 497 | } | ||
| 498 | |||
| 499 | /* | ||
| 500 | * Always open charge pump, if not, when the charge pump closed the | ||
| 501 | * adc will not stable | ||
| 502 | */ | ||
| 503 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
| 504 | IC_CPFREQ, IC_CPFREQ); | ||
| 505 | |||
| 506 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec")) | ||
| 507 | regmap_update_bits(sirf_audio_codec->regmap, | ||
| 508 | AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN); | ||
| 509 | return 0; | ||
| 510 | |||
| 511 | err_clk_put: | ||
| 512 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
| 513 | return ret; | ||
| 514 | } | ||
| 515 | |||
| 516 | static int sirf_audio_codec_driver_remove(struct platform_device *pdev) | ||
| 517 | { | ||
| 518 | struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev); | ||
| 519 | |||
| 520 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
| 521 | |||
| 522 | return 0; | ||
| 523 | } | ||
| 524 | |||
| 525 | #ifdef CONFIG_PM_SLEEP | ||
| 526 | static int sirf_audio_codec_suspend(struct device *dev) | ||
| 527 | { | ||
| 528 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); | ||
| 529 | |||
| 530 | regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
| 531 | &sirf_audio_codec->reg_ctrl0); | ||
| 532 | regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, | ||
| 533 | &sirf_audio_codec->reg_ctrl1); | ||
| 534 | clk_disable_unprepare(sirf_audio_codec->clk); | ||
| 535 | |||
| 536 | return 0; | ||
| 537 | } | ||
| 538 | |||
| 539 | static int sirf_audio_codec_resume(struct device *dev) | ||
| 540 | { | ||
| 541 | struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); | ||
| 542 | int ret; | ||
| 543 | |||
| 544 | ret = clk_prepare_enable(sirf_audio_codec->clk); | ||
| 545 | if (ret) | ||
| 546 | return ret; | ||
| 547 | |||
| 548 | regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, | ||
| 549 | sirf_audio_codec->reg_ctrl0); | ||
| 550 | regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, | ||
| 551 | sirf_audio_codec->reg_ctrl1); | ||
| 552 | |||
| 553 | return 0; | ||
| 554 | } | ||
| 555 | #endif | ||
| 556 | |||
| 557 | static const struct dev_pm_ops sirf_audio_codec_pm_ops = { | ||
| 558 | SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume) | ||
| 559 | }; | ||
| 560 | |||
| 561 | static struct platform_driver sirf_audio_codec_driver = { | ||
| 562 | .driver = { | ||
| 563 | .name = "sirf-audio-codec", | ||
| 564 | .of_match_table = sirf_audio_codec_of_match, | ||
| 565 | .pm = &sirf_audio_codec_pm_ops, | ||
| 566 | }, | ||
| 567 | .probe = sirf_audio_codec_driver_probe, | ||
| 568 | .remove = sirf_audio_codec_driver_remove, | ||
| 569 | }; | ||
| 570 | |||
| 571 | module_platform_driver(sirf_audio_codec_driver); | ||
| 572 | |||
| 573 | MODULE_DESCRIPTION("SiRF audio codec driver"); | ||
| 574 | MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); | ||
| 575 | MODULE_LICENSE("GPL v2"); | ||
| @@ -526,8 +526,8 @@ static struct snd_soc_dai_driver ssm2602_dai = { · 525 unmodified lines | |||
| 526 | .rates = SSM2602_RATES, | 526 | .rates = SSM2602_RATES, |
| 527 | .formats = SSM2602_FORMATS,}, | 527 | .formats = SSM2602_FORMATS,}, |
| 528 | .ops = &ssm2602_dai_ops, | 528 | .ops = &ssm2602_dai_ops, |
| 529 | .symmetric_rates = 1, | 529 | .symmetric_rate = 1, |
| 530 | .symmetric_samplebits = 1, | 530 | .symmetric_sample_bits = 1, |
| 531 | }; | 531 | }; |
| 532 | 532 | ||
| 533 | static int ssm2602_resume(struct snd_soc_component *component) | 533 | static int ssm2602_resume(struct snd_soc_component *component) |
| @@ -490,7 +490,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { · 489 unmodified lines | |||
| 490 | .formats = TAS2764_FORMATS, | 490 | .formats = TAS2764_FORMATS, |
| 491 | }, | 491 | }, |
| 492 | .ops = &tas2764_dai_ops, | 492 | .ops = &tas2764_dai_ops, |
| 493 | .symmetric_rates = 1, | 493 | .symmetric_rate = 1, |
| 494 | }, | 494 | }, |
| 495 | }; | 495 | }; |
| 496 | 496 | ||
| @@ -499,7 +499,7 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = { · 498 unmodified lines | |||
| 499 | .formats = TAS2770_FORMATS, | 499 | .formats = TAS2770_FORMATS, |
| 500 | }, | 500 | }, |
| 501 | .ops = &tas2770_dai_ops, | 501 | .ops = &tas2770_dai_ops, |
| 502 | .symmetric_rates = 1, | 502 | .symmetric_rate = 1, |
| 503 | }, | 503 | }, |
| 504 | }; | 504 | }; |
| 505 | 505 | ||
| @@ -1069,7 +1069,7 @@ static struct snd_soc_dai_driver adcx140_dai_driver[] = { · 1068 unmodified lines | |||
| 1069 | .formats = ADCX140_FORMATS, | 1069 | .formats = ADCX140_FORMATS, |
| 1070 | }, | 1070 | }, |
| 1071 | .ops = &adcx140_dai_ops, | 1071 | .ops = &adcx140_dai_ops, |
| 1072 | .symmetric_rates = 1, | 1072 | .symmetric_rate = 1, |
| 1073 | } | 1073 | } |
| 1074 | }; | 1074 | }; |
| 1075 | 1075 | ||
| @@ -1395,7 +1395,7 @@ static struct snd_soc_dai_driver dac31xx_dai_driver[] = { · 1394 unmodified lines | |||
| 1395 | .formats = AIC31XX_FORMATS, | 1395 | .formats = AIC31XX_FORMATS, |
| 1396 | }, | 1396 | }, |
| 1397 | .ops = &aic31xx_dai_ops, | 1397 | .ops = &aic31xx_dai_ops, |
| 1398 | .symmetric_rates = 1, | 1398 | .symmetric_rate = 1, |
| 1399 | } | 1399 | } |
| 1400 | }; | 1400 | }; |
| 1401 | 1401 | ||
| @@ -1417,7 +1417,7 @@ static struct snd_soc_dai_driver aic31xx_dai_driver[] = { · 15 unmodified lines | |||
| 1417 | .formats = AIC31XX_FORMATS, | 1417 | .formats = AIC31XX_FORMATS, |
| 1418 | }, | 1418 | }, |
| 1419 | .ops = &aic31xx_dai_ops, | 1419 | .ops = &aic31xx_dai_ops, |
| 1420 | .symmetric_rates = 1, | 1420 | .symmetric_rate = 1, |
| 1421 | } | 1421 | } |
| 1422 | }; | 1422 | }; |
| 1423 | 1423 | ||
| @@ -916,7 +916,7 @@ static struct snd_soc_dai_driver aic32x4_dai = { · 915 unmodified lines | |||
| 916 | .rates = AIC32X4_RATES, | 916 | .rates = AIC32X4_RATES, |
| 917 | .formats = AIC32X4_FORMATS,}, | 917 | .formats = AIC32X4_FORMATS,}, |
| 918 | .ops = &aic32x4_ops, | 918 | .ops = &aic32x4_ops, |
| 919 | .symmetric_rates = 1, | 919 | .symmetric_rate = 1, |
| 920 | }; | 920 | }; |
| 921 | 921 | ||
| 922 | static void aic32x4_setup_gpios(struct snd_soc_component *component) | 922 | static void aic32x4_setup_gpios(struct snd_soc_component *component) |
| @@ -1503,7 +1503,7 @@ static struct snd_soc_dai_driver aic3x_dai = { · 1502 unmodified lines | |||
| 1503 | .rates = AIC3X_RATES, | 1503 | .rates = AIC3X_RATES, |
| 1504 | .formats = AIC3X_FORMATS,}, | 1504 | .formats = AIC3X_FORMATS,}, |
| 1505 | .ops = &aic3x_dai_ops, | 1505 | .ops = &aic3x_dai_ops, |
| 1506 | .symmetric_rates = 1, | 1506 | .symmetric_rate = 1, |
| 1507 | }; | 1507 | }; |
| 1508 | 1508 | ||
| 1509 | static void aic3x_mono_init(struct snd_soc_component *component) | 1509 | static void aic3x_mono_init(struct snd_soc_component *component) |
| @@ -1397,9 +1397,9 @@ static struct snd_soc_dai_driver tscs42xx_dai = { · 1396 unmodified lines | |||
| 1397 | .rates = TSCS42XX_RATES, | 1397 | .rates = TSCS42XX_RATES, |
| 1398 | .formats = TSCS42XX_FORMATS,}, | 1398 | .formats = TSCS42XX_FORMATS,}, |
| 1399 | .ops = &tscs42xx_dai_ops, | 1399 | .ops = &tscs42xx_dai_ops, |
| 1400 | .symmetric_rates = 1, | 1400 | .symmetric_rate = 1, |
| 1401 | .symmetric_channels = 1, | 1401 | .symmetric_channels = 1, |
| 1402 | .symmetric_samplebits = 1, | 1402 | .symmetric_sample_bits = 1, |
| 1403 | }; | 1403 | }; |
| 1404 | 1404 | ||
| 1405 | static const struct reg_sequence tscs42xx_patch[] = { | 1405 | static const struct reg_sequence tscs42xx_patch[] = { |
| @@ -3346,9 +3346,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 3345 unmodified lines | |||
| 3346 | .rates = TSCS454_RATES, | 3346 | .rates = TSCS454_RATES, |
| 3347 | .formats = TSCS454_FORMATS,}, | 3347 | .formats = TSCS454_FORMATS,}, |
| 3348 | .ops = &tscs454_dai1_ops, | 3348 | .ops = &tscs454_dai1_ops, |
| 3349 | .symmetric_rates = 1, | 3349 | .symmetric_rate = 1, |
| 3350 | .symmetric_channels = 1, | 3350 | .symmetric_channels = 1, |
| 3351 | .symmetric_samplebits = 1, | 3351 | .symmetric_sample_bits = 1, |
| 3352 | }, | 3352 | }, |
| 3353 | { | 3353 | { |
| 3354 | .name = "tscs454-dai2", | 3354 | .name = "tscs454-dai2", |
| @@ -3366,9 +3366,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 11 unmodified lines | |||
| 3366 | .rates = TSCS454_RATES, | 3366 | .rates = TSCS454_RATES, |
| 3367 | .formats = TSCS454_FORMATS,}, | 3367 | .formats = TSCS454_FORMATS,}, |
| 3368 | .ops = &tscs454_dai23_ops, | 3368 | .ops = &tscs454_dai23_ops, |
| 3369 | .symmetric_rates = 1, | 3369 | .symmetric_rate = 1, |
| 3370 | .symmetric_channels = 1, | 3370 | .symmetric_channels = 1, |
| 3371 | .symmetric_samplebits = 1, | 3371 | .symmetric_sample_bits = 1, |
| 3372 | }, | 3372 | }, |
| 3373 | { | 3373 | { |
| 3374 | .name = "tscs454-dai3", | 3374 | .name = "tscs454-dai3", |
| @@ -3386,9 +3386,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 11 unmodified lines | |||
| 3386 | .rates = TSCS454_RATES, | 3386 | .rates = TSCS454_RATES, |
| 3387 | .formats = TSCS454_FORMATS,}, | 3387 | .formats = TSCS454_FORMATS,}, |
| 3388 | .ops = &tscs454_dai23_ops, | 3388 | .ops = &tscs454_dai23_ops, |
| 3389 | .symmetric_rates = 1, | 3389 | .symmetric_rate = 1, |
| 3390 | .symmetric_channels = 1, | 3390 | .symmetric_channels = 1, |
| 3391 | .symmetric_samplebits = 1, | 3391 | .symmetric_sample_bits = 1, |
| 3392 | }, | 3392 | }, |
| 3393 | }; | 3393 | }; |
| 3394 | 3394 | ||
| @@ -1780,8 +1780,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 1779 unmodified lines | |||
| 1780 | .formats = WM5102_FORMATS, | 1780 | .formats = WM5102_FORMATS, |
| 1781 | }, | 1781 | }, |
| 1782 | .ops = &arizona_dai_ops, | 1782 | .ops = &arizona_dai_ops, |
| 1783 | .symmetric_rates = 1, | 1783 | .symmetric_rate = 1, |
| 1784 | .symmetric_samplebits = 1, | 1784 | .symmetric_sample_bits = 1, |
| 1785 | }, | 1785 | }, |
| 1786 | { | 1786 | { |
| 1787 | .name = "wm5102-aif2", | 1787 | .name = "wm5102-aif2", |
| @@ -1802,8 +1802,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 14 unmodified lines | |||
| 1802 | .formats = WM5102_FORMATS, | 1802 | .formats = WM5102_FORMATS, |
| 1803 | }, | 1803 | }, |
| 1804 | .ops = &arizona_dai_ops, | 1804 | .ops = &arizona_dai_ops, |
| 1805 | .symmetric_rates = 1, | 1805 | .symmetric_rate = 1, |
| 1806 | .symmetric_samplebits = 1, | 1806 | .symmetric_sample_bits = 1, |
| 1807 | }, | 1807 | }, |
| 1808 | { | 1808 | { |
| 1809 | .name = "wm5102-aif3", | 1809 | .name = "wm5102-aif3", |
| @@ -1824,8 +1824,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 14 unmodified lines | |||
| 1824 | .formats = WM5102_FORMATS, | 1824 | .formats = WM5102_FORMATS, |
| 1825 | }, | 1825 | }, |
| 1826 | .ops = &arizona_dai_ops, | 1826 | .ops = &arizona_dai_ops, |
| 1827 | .symmetric_rates = 1, | 1827 | .symmetric_rate = 1, |
| 1828 | .symmetric_samplebits = 1, | 1828 | .symmetric_sample_bits = 1, |
| 1829 | }, | 1829 | }, |
| 1830 | { | 1830 | { |
| 1831 | .name = "wm5102-slim1", | 1831 | .name = "wm5102-slim1", |
| @@ -2089,8 +2089,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 2088 unmodified lines | |||
| 2089 | .formats = WM5110_FORMATS, | 2089 | .formats = WM5110_FORMATS, |
| 2090 | }, | 2090 | }, |
| 2091 | .ops = &arizona_dai_ops, | 2091 | .ops = &arizona_dai_ops, |
| 2092 | .symmetric_rates = 1, | 2092 | .symmetric_rate = 1, |
| 2093 | .symmetric_samplebits = 1, | 2093 | .symmetric_sample_bits = 1, |
| 2094 | }, | 2094 | }, |
| 2095 | { | 2095 | { |
| 2096 | .name = "wm5110-aif2", | 2096 | .name = "wm5110-aif2", |
| @@ -2111,8 +2111,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 14 unmodified lines | |||
| 2111 | .formats = WM5110_FORMATS, | 2111 | .formats = WM5110_FORMATS, |
| 2112 | }, | 2112 | }, |
| 2113 | .ops = &arizona_dai_ops, | 2113 | .ops = &arizona_dai_ops, |
| 2114 | .symmetric_rates = 1, | 2114 | .symmetric_rate = 1, |
| 2115 | .symmetric_samplebits = 1, | 2115 | .symmetric_sample_bits = 1, |
| 2116 | }, | 2116 | }, |
| 2117 | { | 2117 | { |
| 2118 | .name = "wm5110-aif3", | 2118 | .name = "wm5110-aif3", |
| @@ -2133,8 +2133,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 14 unmodified lines | |||
| 2133 | .formats = WM5110_FORMATS, | 2133 | .formats = WM5110_FORMATS, |
| 2134 | }, | 2134 | }, |
| 2135 | .ops = &arizona_dai_ops, | 2135 | .ops = &arizona_dai_ops, |
| 2136 | .symmetric_rates = 1, | 2136 | .symmetric_rate = 1, |
| 2137 | .symmetric_samplebits = 1, | 2137 | .symmetric_sample_bits = 1, |
| 2138 | }, | 2138 | }, |
| 2139 | { | 2139 | { |
| 2140 | .name = "wm5110-slim1", | 2140 | .name = "wm5110-slim1", |
| @@ -569,7 +569,7 @@ static struct snd_soc_dai_driver wm8510_dai = { · 568 unmodified lines | |||
| 569 | .rates = WM8510_RATES, | 569 | .rates = WM8510_RATES, |
| 570 | .formats = WM8510_FORMATS,}, | 570 | .formats = WM8510_FORMATS,}, |
| 571 | .ops = &wm8510_dai_ops, | 571 | .ops = &wm8510_dai_ops, |
| 572 | .symmetric_rates = 1, | 572 | .symmetric_rate = 1, |
| 573 | }; | 573 | }; |
| 574 | 574 | ||
| 575 | static int wm8510_probe(struct snd_soc_component *component) | 575 | static int wm8510_probe(struct snd_soc_component *component) |
| @@ -567,7 +567,7 @@ static struct snd_soc_dai_driver wm8731_dai = { · 566 unmodified lines | |||
| 567 | .rates = WM8731_RATES, | 567 | .rates = WM8731_RATES, |
| 568 | .formats = WM8731_FORMATS,}, | 568 | .formats = WM8731_FORMATS,}, |
| 569 | .ops = &wm8731_dai_ops, | 569 | .ops = &wm8731_dai_ops, |
| 570 | .symmetric_rates = 1, | 570 | .symmetric_rate = 1, |
| 571 | }; | 571 | }; |
| 572 | 572 | ||
| 573 | static int wm8731_request_supplies(struct device *dev, | 573 | static int wm8731_request_supplies(struct device *dev, |
| @@ -562,7 +562,7 @@ static struct snd_soc_dai_driver wm8770_dai = { · 561 unmodified lines | |||
| 562 | .formats = WM8770_FORMATS | 562 | .formats = WM8770_FORMATS |
| 563 | }, | 563 | }, |
| 564 | .ops = &wm8770_dai_ops, | 564 | .ops = &wm8770_dai_ops, |
| 565 | .symmetric_rates = 1 | 565 | .symmetric_rate = 1 |
| 566 | }; | 566 | }; |
| 567 | 567 | ||
| 568 | static int wm8770_probe(struct snd_soc_component *component) | 568 | static int wm8770_probe(struct snd_soc_component *component) |
| @@ -536,7 +536,7 @@ static struct snd_soc_dai_driver wm8804_dai = { · 535 unmodified lines | |||
| 536 | .formats = WM8804_FORMATS, | 536 | .formats = WM8804_FORMATS, |
| 537 | }, | 537 | }, |
| 538 | .ops = &wm8804_dai_ops, | 538 | .ops = &wm8804_dai_ops, |
| 539 | .symmetric_rates = 1 | 539 | .symmetric_rate = 1 |
| 540 | }; | 540 | }; |
| 541 | 541 | ||
| 542 | static const struct snd_soc_component_driver soc_component_dev_wm8804 = { | 542 | static const struct snd_soc_component_driver soc_component_dev_wm8804 = { |
| @@ -1760,7 +1760,7 @@ static struct snd_soc_dai_driver wm8903_dai = { · 1759 unmodified lines | |||
| 1760 | .formats = WM8903_FORMATS, | 1760 | .formats = WM8903_FORMATS, |
| 1761 | }, | 1761 | }, |
| 1762 | .ops = &wm8903_dai_ops, | 1762 | .ops = &wm8903_dai_ops, |
| 1763 | .symmetric_rates = 1, | 1763 | .symmetric_rate = 1, |
| 1764 | }; | 1764 | }; |
| 1765 | 1765 | ||
| 1766 | static int wm8903_resume(struct snd_soc_component *component) | 1766 | static int wm8903_resume(struct snd_soc_component *component) |
| @@ -1983,7 +1983,7 @@ static struct snd_soc_dai_driver wm8904_dai = { · 1982 unmodified lines | |||
| 1983 | .formats = WM8904_FORMATS, | 1983 | .formats = WM8904_FORMATS, |
| 1984 | }, | 1984 | }, |
| 1985 | .ops = &wm8904_dai_ops, | 1985 | .ops = &wm8904_dai_ops, |
| 1986 | .symmetric_rates = 1, | 1986 | .symmetric_rate = 1, |
| 1987 | }; | 1987 | }; |
| 1988 | 1988 | ||
| 1989 | static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *component) | 1989 | static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *component) |
| @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver wm8940_dai = { · 687 unmodified lines | |||
| 688 | .formats = WM8940_FORMATS, | 688 | .formats = WM8940_FORMATS, |
| 689 | }, | 689 | }, |
| 690 | .ops = &wm8940_dai_ops, | 690 | .ops = &wm8940_dai_ops, |
| 691 | .symmetric_rates = 1, | 691 | .symmetric_rate = 1, |
| 692 | }; | 692 | }; |
| 693 | 693 | ||
| 694 | static int wm8940_probe(struct snd_soc_component *component) | 694 | static int wm8940_probe(struct snd_soc_component *component) |
| @@ -1338,7 +1338,7 @@ static struct snd_soc_dai_driver wm8960_dai = { · 1337 unmodified lines | |||
| 1338 | .rates = WM8960_RATES, | 1338 | .rates = WM8960_RATES, |
| 1339 | .formats = WM8960_FORMATS,}, | 1339 | .formats = WM8960_FORMATS,}, |
| 1340 | .ops = &wm8960_dai_ops, | 1340 | .ops = &wm8960_dai_ops, |
| 1341 | .symmetric_rates = 1, | 1341 | .symmetric_rate = 1, |
| 1342 | }; | 1342 | }; |
| 1343 | 1343 | ||
| 1344 | static int wm8960_probe(struct snd_soc_component *component) | 1344 | static int wm8960_probe(struct snd_soc_component *component) |
| @@ -2973,7 +2973,7 @@ static struct snd_soc_dai_driver wm8962_dai = { · 2972 unmodified lines | |||
| 2973 | .formats = WM8962_FORMATS, | 2973 | .formats = WM8962_FORMATS, |
| 2974 | }, | 2974 | }, |
| 2975 | .ops = &wm8962_dai_ops, | 2975 | .ops = &wm8962_dai_ops, |
| 2976 | .symmetric_rates = 1, | 2976 | .symmetric_rate = 1, |
| 2977 | }; | 2977 | }; |
| 2978 | 2978 | ||
| 2979 | static void wm8962_mic_work(struct work_struct *work) | 2979 | static void wm8962_mic_work(struct work_struct *work) |
| @@ -643,7 +643,7 @@ static struct snd_soc_dai_driver wm8974_dai = { · 642 unmodified lines | |||
| 643 | .rates = WM8974_RATES, | 643 | .rates = WM8974_RATES, |
| 644 | .formats = WM8974_FORMATS,}, | 644 | .formats = WM8974_FORMATS,}, |
| 645 | .ops = &wm8974_ops, | 645 | .ops = &wm8974_ops, |
| 646 | .symmetric_rates = 1, | 646 | .symmetric_rate = 1, |
| 647 | }; | 647 | }; |
| 648 | 648 | ||
| 649 | static const struct regmap_config wm8974_regmap = { | 649 | static const struct regmap_config wm8974_regmap = { |
| @@ -918,7 +918,7 @@ static struct snd_soc_dai_driver wm8978_dai = { · 917 unmodified lines | |||
| 918 | .formats = WM8978_FORMATS, | 918 | .formats = WM8978_FORMATS, |
| 919 | }, | 919 | }, |
| 920 | .ops = &wm8978_dai_ops, | 920 | .ops = &wm8978_dai_ops, |
| 921 | .symmetric_rates = 1, | 921 | .symmetric_rate = 1, |
| 922 | }; | 922 | }; |
| 923 | 923 | ||
| 924 | static int wm8978_suspend(struct snd_soc_component *component) | 924 | static int wm8978_suspend(struct snd_soc_component *component) |
| @@ -971,7 +971,7 @@ static struct snd_soc_dai_driver wm8983_dai = { · 970 unmodified lines | |||
| 971 | .formats = WM8983_FORMATS, | 971 | .formats = WM8983_FORMATS, |
| 972 | }, | 972 | }, |
| 973 | .ops = &wm8983_dai_ops, | 973 | .ops = &wm8983_dai_ops, |
| 974 | .symmetric_rates = 1 | 974 | .symmetric_rate = 1 |
| 975 | }; | 975 | }; |
| 976 | 976 | ||
| 977 | static const struct snd_soc_component_driver soc_component_dev_wm8983 = { | 977 | static const struct snd_soc_component_driver soc_component_dev_wm8983 = { |
| @@ -1100,7 +1100,7 @@ static struct snd_soc_dai_driver wm8985_dai = { · 1099 unmodified lines | |||
| 1100 | .formats = WM8985_FORMATS, | 1100 | .formats = WM8985_FORMATS, |
| 1101 | }, | 1101 | }, |
| 1102 | .ops = &wm8985_dai_ops, | 1102 | .ops = &wm8985_dai_ops, |
| 1103 | .symmetric_rates = 1 | 1103 | .symmetric_rate = 1 |
| 1104 | }; | 1104 | }; |
| 1105 | 1105 | ||
| 1106 | static const struct snd_soc_component_driver soc_component_dev_wm8985 = { | 1106 | static const struct snd_soc_component_driver soc_component_dev_wm8985 = { |
| @@ -787,7 +787,7 @@ static struct snd_soc_dai_driver wm8988_dai = { · 786 unmodified lines | |||
| 787 | .formats = WM8988_FORMATS, | 787 | .formats = WM8988_FORMATS, |
| 788 | }, | 788 | }, |
| 789 | .ops = &wm8988_ops, | 789 | .ops = &wm8988_ops, |
| 790 | .symmetric_rates = 1, | 790 | .symmetric_rate = 1, |
| 791 | }; | 791 | }; |
| 792 | 792 | ||
| 793 | static int wm8988_probe(struct snd_soc_component *component) | 793 | static int wm8988_probe(struct snd_soc_component *component) |
| @@ -1476,7 +1476,7 @@ static struct snd_soc_dai_driver wm8993_dai = { · 1475 unmodified lines | |||
| 1476 | .sig_bits = 24, | 1476 | .sig_bits = 24, |
| 1477 | }, | 1477 | }, |
| 1478 | .ops = &wm8993_ops, | 1478 | .ops = &wm8993_ops, |
| 1479 | .symmetric_rates = 1, | 1479 | .symmetric_rate = 1, |
| 1480 | }; | 1480 | }; |
| 1481 | 1481 | ||
| 1482 | static int wm8993_probe(struct snd_soc_component *component) | 1482 | static int wm8993_probe(struct snd_soc_component *component) |
| @@ -4351,7 +4351,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) · 4350 unmodified lines | |||
| 4351 | } | 4351 | } |
| 4352 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 4352 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
| 4353 | wm8994->lrclk_shared[0] = 1; | 4353 | wm8994->lrclk_shared[0] = 1; |
| 4354 | wm8994_dai[0].symmetric_rates = 1; | 4354 | wm8994_dai[0].symmetric_rate = 1; |
| 4355 | } else { | 4355 | } else { |
| 4356 | wm8994->lrclk_shared[0] = 0; | 4356 | wm8994->lrclk_shared[0] = 0; |
| 4357 | } | 4357 | } |
| @@ -4363,7 +4363,7 @@ static int wm8994_component_probe(struct snd_soc_component *component) · 5 unmodified lines | |||
| 4363 | } | 4363 | } |
| 4364 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { | 4364 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
| 4365 | wm8994->lrclk_shared[1] = 1; | 4365 | wm8994->lrclk_shared[1] = 1; |
| 4366 | wm8994_dai[1].symmetric_rates = 1; | 4366 | wm8994_dai[1].symmetric_rate = 1; |
| 4367 | } else { | 4367 | } else { |
| 4368 | wm8994->lrclk_shared[1] = 0; | 4368 | wm8994->lrclk_shared[1] = 0; |
| 4369 | } | 4369 | } |
| @@ -969,8 +969,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { · 968 unmodified lines | |||
| 969 | .formats = WM8997_FORMATS, | 969 | .formats = WM8997_FORMATS, |
| 970 | }, | 970 | }, |
| 971 | .ops = &arizona_dai_ops, | 971 | .ops = &arizona_dai_ops, |
| 972 | .symmetric_rates = 1, | 972 | .symmetric_rate = 1, |
| 973 | .symmetric_samplebits = 1, | 973 | .symmetric_sample_bits = 1, |
| 974 | }, | 974 | }, |
| 975 | { | 975 | { |
| 976 | .name = "wm8997-aif2", | 976 | .name = "wm8997-aif2", |
| @@ -991,8 +991,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { · 14 unmodified lines | |||
| 991 | .formats = WM8997_FORMATS, | 991 | .formats = WM8997_FORMATS, |
| 992 | }, | 992 | }, |
| 993 | .ops = &arizona_dai_ops, | 993 | .ops = &arizona_dai_ops, |
| 994 | .symmetric_rates = 1, | 994 | .symmetric_rate = 1, |
| 995 | .symmetric_samplebits = 1, | 995 | .symmetric_sample_bits = 1, |
| 996 | }, | 996 | }, |
| 997 | { | 997 | { |
| 998 | .name = "wm8997-slim1", | 998 | .name = "wm8997-slim1", |
| @@ -1161,8 +1161,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 1160 unmodified lines | |||
| 1161 | .formats = WM8998_FORMATS, | 1161 | .formats = WM8998_FORMATS, |
| 1162 | }, | 1162 | }, |
| 1163 | .ops = &arizona_dai_ops, | 1163 | .ops = &arizona_dai_ops, |
| 1164 | .symmetric_rates = 1, | 1164 | .symmetric_rate = 1, |
| 1165 | .symmetric_samplebits = 1, | 1165 | .symmetric_sample_bits = 1, |
| 1166 | }, | 1166 | }, |
| 1167 | { | 1167 | { |
| 1168 | .name = "wm8998-aif2", | 1168 | .name = "wm8998-aif2", |
| @@ -1183,8 +1183,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 14 unmodified lines | |||
| 1183 | .formats = WM8998_FORMATS, | 1183 | .formats = WM8998_FORMATS, |
| 1184 | }, | 1184 | }, |
| 1185 | .ops = &arizona_dai_ops, | 1185 | .ops = &arizona_dai_ops, |
| 1186 | .symmetric_rates = 1, | 1186 | .symmetric_rate = 1, |
| 1187 | .symmetric_samplebits = 1, | 1187 | .symmetric_sample_bits = 1, |
| 1188 | }, | 1188 | }, |
| 1189 | { | 1189 | { |
| 1190 | .name = "wm8998-aif3", | 1190 | .name = "wm8998-aif3", |
| @@ -1205,8 +1205,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 14 unmodified lines | |||
| 1205 | .formats = WM8998_FORMATS, | 1205 | .formats = WM8998_FORMATS, |
| 1206 | }, | 1206 | }, |
| 1207 | .ops = &arizona_dai_ops, | 1207 | .ops = &arizona_dai_ops, |
| 1208 | .symmetric_rates = 1, | 1208 | .symmetric_rate = 1, |
| 1209 | .symmetric_samplebits = 1, | 1209 | .symmetric_sample_bits = 1, |
| 1210 | }, | 1210 | }, |
| 1211 | { | 1211 | { |
| 1212 | .name = "wm8998-slim1", | 1212 | .name = "wm8998-slim1", |
| @@ -1134,7 +1134,7 @@ static struct snd_soc_dai_driver wm9713_dai[] = { · 1133 unmodified lines | |||
| 1134 | .rates = WM9713_PCM_RATES, | 1134 | .rates = WM9713_PCM_RATES, |
| 1135 | .formats = WM9713_PCM_FORMATS,}, | 1135 | .formats = WM9713_PCM_FORMATS,}, |
| 1136 | .ops = &wm9713_dai_ops_voice, | 1136 | .ops = &wm9713_dai_ops_voice, |
| 1137 | .symmetric_rates = 1, | 1137 | .symmetric_rate = 1, |
| 1138 | }, | 1138 | }, |
| 1139 | }; | 1139 | }; |
| 1140 | 1140 | ||
| @@ -595,13 +595,6 @@ static const struct { · 594 unmodified lines | |||
| 595 | [WM_ADSP_FW_MISC] = { .file = "misc" }, | 595 | [WM_ADSP_FW_MISC] = { .file = "misc" }, |
| 596 | }; | 596 | }; |
| 597 | 597 | ||
| 598 | struct wm_coeff_ctl_ops { | ||
| 599 | int (*xget)(struct snd_kcontrol *kcontrol, | ||
| 600 | struct snd_ctl_elem_value *ucontrol); | ||
| 601 | int (*xput)(struct snd_kcontrol *kcontrol, | ||
| 602 | struct snd_ctl_elem_value *ucontrol); | ||
| 603 | }; | ||
| 604 | |||
| 605 | struct wm_coeff_ctl { | 598 | struct wm_coeff_ctl { |
| 606 | const char *name; | 599 | const char *name; |
| 607 | const char *fw_name; | 600 | const char *fw_name; |
| @@ -609,7 +602,6 @@ struct wm_coeff_ctl { · 1 unmodified line | |||
| 609 | const char *subname; | 602 | const char *subname; |
| 610 | unsigned int subname_len; | 603 | unsigned int subname_len; |
| 611 | struct wm_adsp_alg_region alg_region; | 604 | struct wm_adsp_alg_region alg_region; |
| 612 | struct wm_coeff_ctl_ops ops; | ||
| 613 | struct wm_adsp *dsp; | 605 | struct wm_adsp *dsp; |
| 614 | unsigned int enabled:1; | 606 | unsigned int enabled:1; |
| 615 | struct list_head list; | 607 | struct list_head list; |
| @@ -619,7 +611,7 @@ struct wm_coeff_ctl { · 3 unmodified lines | |||
| 619 | unsigned int set:1; | 611 | unsigned int set:1; |
| 620 | struct soc_bytes_ext bytes_ext; | 612 | struct soc_bytes_ext bytes_ext; |
| 621 | unsigned int flags; | 613 | unsigned int flags; |
| 622 | unsigned int type; | 614 | snd_ctl_elem_type_t type; |
| 623 | }; | 615 | }; |
| 624 | 616 | ||
| 625 | static const char *wm_adsp_mem_region_name(unsigned int type) | 617 | static const char *wm_adsp_mem_region_name(unsigned int type) |
| @@ -980,7 +972,7 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, · 354 unmodified lines | |||
| 980 | unsigned int event_id) | 972 | unsigned int event_id) |
| 981 | { | 973 | { |
| 982 | struct wm_adsp *dsp = ctl->dsp; | 974 | struct wm_adsp *dsp = ctl->dsp; |
| 983 | u32 val = cpu_to_be32(event_id); | 975 | __be32 val = cpu_to_be32(event_id); |
| 984 | unsigned int reg; | 976 | unsigned int reg; |
| 985 | int i, ret; | 977 | int i, ret; |
| 986 | 978 | ||
| @@ -1420,7 +1412,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, · 433 unmodified lines | |||
| 1420 | const struct wm_adsp_alg_region *alg_region, | 1412 | const struct wm_adsp_alg_region *alg_region, |
| 1421 | unsigned int offset, unsigned int len, | 1413 | unsigned int offset, unsigned int len, |
| 1422 | const char *subname, unsigned int subname_len, | 1414 | const char *subname, unsigned int subname_len, |
| 1423 | unsigned int flags, unsigned int type) | 1415 | unsigned int flags, snd_ctl_elem_type_t type) |
| 1424 | { | 1416 | { |
| 1425 | struct wm_coeff_ctl *ctl; | 1417 | struct wm_coeff_ctl *ctl; |
| 1426 | struct wmfw_ctl_work *ctl_work; | 1418 | struct wmfw_ctl_work *ctl_work; |
| @@ -1497,8 +1489,6 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, · 70 unmodified lines | |||
| 1497 | } | 1489 | } |
| 1498 | ctl->enabled = 1; | 1490 | ctl->enabled = 1; |
| 1499 | ctl->set = 0; | 1491 | ctl->set = 0; |
| 1500 | ctl->ops.xget = wm_coeff_get; | ||
| 1501 | ctl->ops.xput = wm_coeff_put; | ||
| 1502 | ctl->dsp = dsp; | 1492 | ctl->dsp = dsp; |
| 1503 | 1493 | ||
| 1504 | ctl->flags = flags; | 1494 | ctl->flags = flags; |
| @@ -1554,7 +1544,7 @@ struct wm_coeff_parsed_coeff { · 49 unmodified lines | |||
| 1554 | int mem_type; | 1544 | int mem_type; |
| 1555 | const u8 *name; | 1545 | const u8 *name; |
| 1556 | int name_len; | 1546 | int name_len; |
| 1557 | int ctl_type; | 1547 | snd_ctl_elem_type_t ctl_type; |
| 1558 | int flags; | 1548 | int flags; |
| 1559 | int len; | 1549 | int len; |
| 1560 | }; | 1550 | }; |
| @@ -1649,7 +1639,7 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, · 88 unmodified lines | |||
| 1649 | blk->mem_type = le16_to_cpu(raw->hdr.type); | 1639 | blk->mem_type = le16_to_cpu(raw->hdr.type); |
| 1650 | blk->name = raw->name; | 1640 | blk->name = raw->name; |
| 1651 | blk->name_len = strlen(raw->name); | 1641 | blk->name_len = strlen(raw->name); |
| 1652 | blk->ctl_type = le16_to_cpu(raw->ctl_type); | 1642 | blk->ctl_type = (__force snd_ctl_elem_type_t)le16_to_cpu(raw->ctl_type); |
| 1653 | blk->flags = le16_to_cpu(raw->flags); | 1643 | blk->flags = le16_to_cpu(raw->flags); |
| 1654 | blk->len = le32_to_cpu(raw->len); | 1644 | blk->len = le32_to_cpu(raw->len); |
| 1655 | break; | 1645 | break; |
| @@ -1662,7 +1652,9 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, · 6 unmodified lines | |||
| 1662 | &blk->name); | 1652 | &blk->name); |
| 1663 | wm_coeff_parse_string(sizeof(u8), &tmp, NULL); | 1653 | wm_coeff_parse_string(sizeof(u8), &tmp, NULL); |
| 1664 | wm_coeff_parse_string(sizeof(u16), &tmp, NULL); | 1654 | wm_coeff_parse_string(sizeof(u16), &tmp, NULL); |
| 1665 | blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); | 1655 | blk->ctl_type = |
| 1656 | (__force snd_ctl_elem_type_t)wm_coeff_parse_int(sizeof(raw->ctl_type), | ||
| 1657 | &tmp); | ||
| 1666 | blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); | 1658 | blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); |
| 1667 | blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); | 1659 | blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); |
| 1668 | 1660 | ||
| @@ -3667,12 +3659,12 @@ int wm_adsp_compr_get_caps(struct snd_soc_component *component, · 1998 unmodified lines | |||
| 3667 | } | 3659 | } |
| 3668 | EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); | 3660 | EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); |
| 3669 | 3661 | ||
| 3670 | static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, | 3662 | static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, |
| 3671 | unsigned int mem_addr, | 3663 | unsigned int mem_addr, |
| 3672 | unsigned int num_words, u32 *data) | 3664 | unsigned int num_words, __be32 *data) |
| 3673 | { | 3665 | { |
| 3674 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); | 3666 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); |
| 3675 | unsigned int i, reg; | 3667 | unsigned int reg; |
| 3676 | int ret; | 3668 | int ret; |
| 3677 | 3669 | ||
| 3678 | if (!mem) | 3670 | if (!mem) |
| @@ -3685,22 +3677,29 @@ static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, · 6 unmodified lines | |||
| 3685 | if (ret < 0) | 3677 | if (ret < 0) |
| 3686 | return ret; | 3678 | return ret; |
| 3687 | 3679 | ||
| 3688 | for (i = 0; i < num_words; ++i) | ||
| 3689 | data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; | ||
| 3690 | |||
| 3691 | return 0; | 3680 | return 0; |
| 3692 | } | 3681 | } |
| 3693 | 3682 | ||
| 3694 | static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, | 3683 | static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, |
| 3695 | unsigned int mem_addr, u32 *data) | 3684 | unsigned int mem_addr, u32 *data) |
| 3696 | { | 3685 | { |
| 3697 | return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); | 3686 | __be32 raw; |
| 3687 | int ret; | ||
| 3688 | |||
| 3689 | ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); | ||
| 3690 | if (ret < 0) | ||
| 3691 | return ret; | ||
| 3692 | |||
| 3693 | *data = be32_to_cpu(raw) & 0x00ffffffu; | ||
| 3694 | |||
| 3695 | return 0; | ||
| 3698 | } | 3696 | } |
| 3699 | 3697 | ||
| 3700 | static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, | 3698 | static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, |
| 3701 | unsigned int mem_addr, u32 data) | 3699 | unsigned int mem_addr, u32 data) |
| 3702 | { | 3700 | { |
| 3703 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); | 3701 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); |
| 3702 | __be32 val = cpu_to_be32(data & 0x00ffffffu); | ||
| 3704 | unsigned int reg; | 3703 | unsigned int reg; |
| 3705 | 3704 | ||
| 3706 | if (!mem) | 3705 | if (!mem) |
| @@ -3708,9 +3707,7 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, · 1 unmodified line | |||
| 3708 | 3707 | ||
| 3709 | reg = dsp->ops->region_to_reg(mem, mem_addr); | 3708 | reg = dsp->ops->region_to_reg(mem, mem_addr); |
| 3710 | 3709 | ||
| 3711 | data = cpu_to_be32(data & 0x00ffffffu); | 3710 | return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); |
| 3712 | |||
| 3713 | return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); | ||
| 3714 | } | 3711 | } |
| 3715 | 3712 | ||
| 3716 | static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, | 3713 | static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, |
| @@ -3727,18 +3724,22 @@ static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, · 10 unmodified lines | |||
| 3727 | buf->host_buf_ptr + field_offset, data); | 3724 | buf->host_buf_ptr + field_offset, data); |
| 3728 | } | 3725 | } |
| 3729 | 3726 | ||
| 3730 | static void wm_adsp_remove_padding(u32 *buf, int nwords, int data_word_size) | 3727 | static void wm_adsp_remove_padding(u32 *buf, int nwords) |
| 3731 | { | 3728 | { |
| 3732 | u8 *pack_in = (u8 *)buf; | 3729 | const __be32 *pack_in = (__be32 *)buf; |
| 3733 | u8 *pack_out = (u8 *)buf; | 3730 | u8 *pack_out = (u8 *)buf; |
| 3734 | int i, j; | 3731 | int i; |
| 3735 | 3732 | ||
| 3736 | /* Remove the padding bytes from the data read from the DSP */ | 3733 | /* |
| 3734 | * DSP words from the register map have pad bytes and the data bytes | ||
| 3735 | * are in swapped order. This swaps back to the original little-endian | ||
| 3736 | * order and strips the pad bytes. | ||
| 3737 | */ | ||
| 3737 | for (i = 0; i < nwords; i++) { | 3738 | for (i = 0; i < nwords; i++) { |
| 3738 | for (j = 0; j < data_word_size; j++) | 3739 | u32 word = be32_to_cpu(*pack_in++); |
| 3739 | *pack_out++ = *pack_in++; | 3740 | *pack_out++ = (u8)word; |
| 3740 | 3741 | *pack_out++ = (u8)(word >> 8); | |
| 3741 | pack_in += sizeof(*buf) - data_word_size; | 3742 | *pack_out++ = (u8)(word >> 16); |
| 3742 | } | 3743 | } |
| 3743 | } | 3744 | } |
| 3744 | 3745 | ||
| @@ -3863,7 +3864,8 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) · 118 unmodified lines | |||
| 3863 | { | 3864 | { |
| 3864 | struct wm_adsp_host_buf_coeff_v1 coeff_v1; | 3865 | struct wm_adsp_host_buf_coeff_v1 coeff_v1; |
| 3865 | struct wm_adsp_compr_buf *buf; | 3866 | struct wm_adsp_compr_buf *buf; |
| 3866 | unsigned int val, reg; | 3867 | unsigned int reg, version; |
| 3868 | __be32 bufp; | ||
| 3867 | int ret, i; | 3869 | int ret, i; |
| 3868 | 3870 | ||
| 3869 | ret = wm_coeff_base_reg(ctl, ®); | 3871 | ret = wm_coeff_base_reg(ctl, ®); |
| @@ -3871,17 +3873,17 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) · 1 unmodified line | |||
| 3871 | return ret; | 3873 | return ret; |
| 3872 | 3874 | ||
| 3873 | for (i = 0; i < 5; ++i) { | 3875 | for (i = 0; i < 5; ++i) { |
| 3874 | ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val)); | 3876 | ret = regmap_raw_read(ctl->dsp->regmap, reg, &bufp, sizeof(bufp)); |
| 3875 | if (ret < 0) | 3877 | if (ret < 0) |
| 3876 | return ret; | 3878 | return ret; |
| 3877 | 3879 | ||
| 3878 | if (val) | 3880 | if (bufp) |
| 3879 | break; | 3881 | break; |
| 3880 | 3882 | ||
| 3881 | usleep_range(1000, 2000); | 3883 | usleep_range(1000, 2000); |
| 3882 | } | 3884 | } |
| 3883 | 3885 | ||
| 3884 | if (!val) { | 3886 | if (!bufp) { |
| 3885 | adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); | 3887 | adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); |
| 3886 | return -EIO; | 3888 | return -EIO; |
| 3887 | } | 3889 | } |
| @@ -3891,7 +3893,7 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) · 3 unmodified lines | |||
| 3891 | return -ENOMEM; | 3893 | return -ENOMEM; |
| 3892 | 3894 | ||
| 3893 | buf->host_buf_mem_type = ctl->alg_region.type; | 3895 | buf->host_buf_mem_type = ctl->alg_region.type; |
| 3894 | buf->host_buf_ptr = be32_to_cpu(val); | 3896 | buf->host_buf_ptr = be32_to_cpu(bufp); |
| 3895 | 3897 | ||
| 3896 | ret = wm_adsp_buffer_populate(buf); | 3898 | ret = wm_adsp_buffer_populate(buf); |
| 3897 | if (ret < 0) | 3899 | if (ret < 0) |
| @@ -3911,31 +3913,25 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) · 13 unmodified lines | |||
| 3911 | if (ret < 0) | 3913 | if (ret < 0) |
| 3912 | return ret; | 3914 | return ret; |
| 3913 | 3915 | ||
| 3914 | coeff_v1.versions = be32_to_cpu(coeff_v1.versions); | 3916 | version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; |
| 3915 | val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; | 3917 | version >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; |
| 3916 | val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; | ||
| 3917 | 3918 | ||
| 3918 | if (val > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { | 3919 | if (version > HOST_BUF_COEFF_SUPPORTED_COMPAT_VER) { |
| 3919 | adsp_err(ctl->dsp, | 3920 | adsp_err(ctl->dsp, |
| 3920 | "Host buffer coeff ver %u > supported version %u\n", | 3921 | "Host buffer coeff ver %u > supported version %u\n", |
| 3921 | val, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); | 3922 | version, HOST_BUF_COEFF_SUPPORTED_COMPAT_VER); |
| 3922 | return -EINVAL; | 3923 | return -EINVAL; |
| 3923 | } | 3924 | } |
| 3924 | 3925 | ||
| 3925 | for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) | 3926 | wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); |
| 3926 | coeff_v1.name[i] = be32_to_cpu(coeff_v1.name[i]); | ||
| 3927 | |||
| 3928 | wm_adsp_remove_padding((u32 *)&coeff_v1.name, | ||
| 3929 | ARRAY_SIZE(coeff_v1.name), | ||
| 3930 | WM_ADSP_DATA_WORD_SIZE); | ||
| 3931 | 3927 | ||
| 3932 | buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, | 3928 | buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, |
| 3933 | (char *)&coeff_v1.name); | 3929 | (char *)&coeff_v1.name); |
| 3934 | 3930 | ||
| 3935 | compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", | 3931 | compr_dbg(buf, "host_buf_ptr=%x coeff version %u\n", |
| 3936 | buf->host_buf_ptr, val); | 3932 | buf->host_buf_ptr, version); |
| 3937 | 3933 | ||
| 3938 | return val; | 3934 | return version; |
| 3939 | } | 3935 | } |
| 3940 | 3936 | ||
| 3941 | static int wm_adsp_buffer_init(struct wm_adsp *dsp) | 3937 | static int wm_adsp_buffer_init(struct wm_adsp *dsp) |
| @@ -4266,12 +4262,12 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) · 324 unmodified lines | |||
| 4266 | return 0; | 4262 | return 0; |
| 4267 | 4263 | ||
| 4268 | /* Read data from DSP */ | 4264 | /* Read data from DSP */ |
| 4269 | ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, | 4265 | ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, |
| 4270 | nwords, compr->raw_buf); | 4266 | nwords, (__be32 *)compr->raw_buf); |
| 4271 | if (ret < 0) | 4267 | if (ret < 0) |
| 4272 | return ret; | 4268 | return ret; |
| 4273 | 4269 | ||
| 4274 | wm_adsp_remove_padding(compr->raw_buf, nwords, WM_ADSP_DATA_WORD_SIZE); | 4270 | wm_adsp_remove_padding(compr->raw_buf, nwords); |
| 4275 | 4271 | ||
| 4276 | /* update read index to account for words read */ | 4272 | /* update read index to account for words read */ |
| 4277 | buf->read_index += nwords; | 4273 | buf->read_index += nwords; |
| @@ -24,9 +24,9 @@ · 23 unmodified lines | |||
| 24 | #define WMFW_CTL_FLAG_READABLE 0x0001 | 24 | #define WMFW_CTL_FLAG_READABLE 0x0001 |
| 25 | 25 | ||
| 26 | /* Non-ALSA coefficient types start at 0x1000 */ | 26 | /* Non-ALSA coefficient types start at 0x1000 */ |
| 27 | #define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ | 27 | #define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */ |
| 28 | #define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ | 28 | #define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */ |
| 29 | #define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ | 29 | #define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */ |
| 30 | 30 | ||
| 31 | struct wmfw_header { | 31 | struct wmfw_header { |
| 32 | char magic[4]; | 32 | char magic[4]; |
| @@ -640,6 +640,7 @@ static struct regmap_config wsa881x_regmap_config = { · 639 unmodified lines | |||
| 640 | .val_bits = 8, | 640 | .val_bits = 8, |
| 641 | .cache_type = REGCACHE_RBTREE, | 641 | .cache_type = REGCACHE_RBTREE, |
| 642 | .reg_defaults = wsa881x_defaults, | 642 | .reg_defaults = wsa881x_defaults, |
| 643 | .max_register = WSA881X_SPKR_STATUS3, | ||
| 643 | .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults), | 644 | .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults), |
| 644 | .volatile_reg = wsa881x_volatile_register, | 645 | .volatile_reg = wsa881x_volatile_register, |
| 645 | .readable_reg = wsa881x_readable_register, | 646 | .readable_reg = wsa881x_readable_register, |
| @@ -360,8 +360,8 @@ static struct snd_soc_dai_driver zl38_dai = { · 359 unmodified lines | |||
| 360 | .formats = ZL38_FORMATS, | 360 | .formats = ZL38_FORMATS, |
| 361 | }, | 361 | }, |
| 362 | .ops = &zl38_dai_ops, | 362 | .ops = &zl38_dai_ops, |
| 363 | .symmetric_rates = 1, | 363 | .symmetric_rate = 1, |
| 364 | .symmetric_samplebits = 1, | 364 | .symmetric_sample_bits = 1, |
| 365 | .symmetric_channels = 1, | 365 | .symmetric_channels = 1, |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| @@ -1,401 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2017 Sanechips Technology Co., Ltd. | ||
| 4 | * Copyright 2017 Linaro Ltd. | ||
| 5 | * | ||
| 6 | * Author: Baoyou Xie <baoyou.xie@linaro.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/gpio/consumer.h> | ||
| 10 | #include <linux/i2c.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/regmap.h> | ||
| 13 | #include <sound/pcm.h> | ||
| 14 | #include <sound/pcm_params.h> | ||
| 15 | #include <sound/soc.h> | ||
| 16 | #include <sound/soc-dai.h> | ||
| 17 | #include <sound/tlv.h> | ||
| 18 | |||
| 19 | #define AUD96P22_RESET 0x00 | ||
| 20 | #define RST_DAC_DPZ BIT(0) | ||
| 21 | #define RST_ADC_DPZ BIT(1) | ||
| 22 | #define AUD96P22_I2S1_CONFIG_0 0x03 | ||
| 23 | #define I2S1_MS_MODE BIT(3) | ||
| 24 | #define I2S1_MODE_MASK 0x7 | ||
| 25 | #define I2S1_MODE_RIGHT_J 0x0 | ||
| 26 | #define I2S1_MODE_I2S 0x1 | ||
| 27 | #define I2S1_MODE_LEFT_J 0x2 | ||
| 28 | #define AUD96P22_PD_0 0x15 | ||
| 29 | #define AUD96P22_PD_1 0x16 | ||
| 30 | #define AUD96P22_PD_3 0x18 | ||
| 31 | #define AUD96P22_PD_4 0x19 | ||
| 32 | #define AUD96P22_MUTE_0 0x1d | ||
| 33 | #define AUD96P22_MUTE_2 0x1f | ||
| 34 | #define AUD96P22_MUTE_4 0x21 | ||
| 35 | #define AUD96P22_RECVOL_0 0x24 | ||
| 36 | #define AUD96P22_RECVOL_1 0x25 | ||
| 37 | #define AUD96P22_PGA1VOL_0 0x26 | ||
| 38 | #define AUD96P22_PGA1VOL_1 0x27 | ||
| 39 | #define AUD96P22_LMVOL_0 0x34 | ||
| 40 | #define AUD96P22_LMVOL_1 0x35 | ||
| 41 | #define AUD96P22_HS1VOL_0 0x38 | ||
| 42 | #define AUD96P22_HS1VOL_1 0x39 | ||
| 43 | #define AUD96P22_PGA1SEL_0 0x47 | ||
| 44 | #define AUD96P22_PGA1SEL_1 0x48 | ||
| 45 | #define AUD96P22_LDR1SEL_0 0x59 | ||
| 46 | #define AUD96P22_LDR1SEL_1 0x60 | ||
| 47 | #define AUD96P22_LDR2SEL_0 0x5d | ||
| 48 | #define AUD96P22_REG_MAX 0xfb | ||
| 49 | |||
| 50 | struct aud96p22_priv { | ||
| 51 | struct regmap *regmap; | ||
| 52 | }; | ||
| 53 | |||
| 54 | static int aud96p22_adc_event(struct snd_soc_dapm_widget *w, | ||
| 55 | struct snd_kcontrol *kcontrol, int event) | ||
| 56 | { | ||
| 57 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 58 | struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); | ||
| 59 | struct regmap *regmap = priv->regmap; | ||
| 60 | |||
| 61 | if (event != SND_SOC_DAPM_POST_PMU) | ||
| 62 | return -EINVAL; | ||
| 63 | |||
| 64 | /* Assert/de-assert the bit to reset ADC data path */ | ||
| 65 | regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, 0); | ||
| 66 | regmap_update_bits(regmap, AUD96P22_RESET, RST_ADC_DPZ, RST_ADC_DPZ); | ||
| 67 | |||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int aud96p22_dac_event(struct snd_soc_dapm_widget *w, | ||
| 72 | struct snd_kcontrol *kcontrol, int event) | ||
| 73 | { | ||
| 74 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 75 | struct aud96p22_priv *priv = snd_soc_component_get_drvdata(component); | ||
| 76 | struct regmap *regmap = priv->regmap; | ||
| 77 | |||
| 78 | if (event != SND_SOC_DAPM_POST_PMU) | ||
| 79 | return -EINVAL; | ||
| 80 | |||
| 81 | /* Assert/de-assert the bit to reset DAC data path */ | ||
| 82 | regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, 0); | ||
| 83 | regmap_update_bits(regmap, AUD96P22_RESET, RST_DAC_DPZ, RST_DAC_DPZ); | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static const DECLARE_TLV_DB_SCALE(lm_tlv, -11550, 50, 0); | ||
| 89 | static const DECLARE_TLV_DB_SCALE(hs_tlv, -3900, 300, 0); | ||
| 90 | static const DECLARE_TLV_DB_SCALE(rec_tlv, -9550, 50, 0); | ||
| 91 | static const DECLARE_TLV_DB_SCALE(pga_tlv, -1800, 100, 0); | ||
| 92 | |||
| 93 | static const struct snd_kcontrol_new aud96p22_snd_controls[] = { | ||
| 94 | /* Volume control */ | ||
| 95 | SOC_DOUBLE_R_TLV("Master Playback Volume", AUD96P22_LMVOL_0, | ||
| 96 | AUD96P22_LMVOL_1, 0, 0xff, 0, lm_tlv), | ||
| 97 | SOC_DOUBLE_R_TLV("Headphone Volume", AUD96P22_HS1VOL_0, | ||
| 98 | AUD96P22_HS1VOL_1, 0, 0xf, 0, hs_tlv), | ||
| 99 | SOC_DOUBLE_R_TLV("Master Capture Volume", AUD96P22_RECVOL_0, | ||
| 100 | AUD96P22_RECVOL_1, 0, 0xff, 0, rec_tlv), | ||
| 101 | SOC_DOUBLE_R_TLV("Analogue Capture Volume", AUD96P22_PGA1VOL_0, | ||
| 102 | AUD96P22_PGA1VOL_1, 0, 0x37, 0, pga_tlv), | ||
| 103 | |||
| 104 | /* Mute control */ | ||
| 105 | SOC_DOUBLE("Master Playback Switch", AUD96P22_MUTE_2, 0, 1, 1, 1), | ||
| 106 | SOC_DOUBLE("Headphone Switch", AUD96P22_MUTE_2, 4, 5, 1, 1), | ||
| 107 | SOC_DOUBLE("Line Out Switch", AUD96P22_MUTE_4, 0, 1, 1, 1), | ||
| 108 | SOC_DOUBLE("Speaker Switch", AUD96P22_MUTE_4, 2, 3, 1, 1), | ||
| 109 | SOC_DOUBLE("Master Capture Switch", AUD96P22_MUTE_0, 0, 1, 1, 1), | ||
| 110 | SOC_DOUBLE("Analogue Capture Switch", AUD96P22_MUTE_0, 2, 3, 1, 1), | ||
| 111 | }; | ||
| 112 | |||
| 113 | /* Input mux kcontrols */ | ||
| 114 | static const unsigned int ain_mux_values[] = { | ||
| 115 | 0, 1, 3, 4, 5, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static const char * const ainl_mux_texts[] = { | ||
| 119 | "AINL1 differential", | ||
| 120 | "AINL1 single-ended", | ||
| 121 | "AINL3 single-ended", | ||
| 122 | "AINL2 differential", | ||
| 123 | "AINL2 single-ended", | ||
| 124 | }; | ||
| 125 | |||
| 126 | static const char * const ainr_mux_texts[] = { | ||
| 127 | "AINR1 differential", | ||
| 128 | "AINR1 single-ended", | ||
| 129 | "AINR3 single-ended", | ||
| 130 | "AINR2 differential", | ||
| 131 | "AINR2 single-ended", | ||
| 132 | }; | ||
| 133 | |||
| 134 | static SOC_VALUE_ENUM_SINGLE_DECL(ainl_mux_enum, AUD96P22_PGA1SEL_0, | ||
| 135 | 0, 0x7, ainl_mux_texts, ain_mux_values); | ||
| 136 | static SOC_VALUE_ENUM_SINGLE_DECL(ainr_mux_enum, AUD96P22_PGA1SEL_1, | ||
| 137 | 0, 0x7, ainr_mux_texts, ain_mux_values); | ||
| 138 | |||
| 139 | static const struct snd_kcontrol_new ainl_mux_kcontrol = | ||
| 140 | SOC_DAPM_ENUM("AINL Mux", ainl_mux_enum); | ||
| 141 | static const struct snd_kcontrol_new ainr_mux_kcontrol = | ||
| 142 | SOC_DAPM_ENUM("AINR Mux", ainr_mux_enum); | ||
| 143 | |||
| 144 | /* Output mixer kcontrols */ | ||
| 145 | static const struct snd_kcontrol_new ld1_left_kcontrols[] = { | ||
| 146 | SOC_DAPM_SINGLE("DACL LD1L Switch", AUD96P22_LDR1SEL_0, 0, 1, 0), | ||
| 147 | SOC_DAPM_SINGLE("AINL LD1L Switch", AUD96P22_LDR1SEL_0, 1, 1, 0), | ||
| 148 | SOC_DAPM_SINGLE("AINR LD1L Switch", AUD96P22_LDR1SEL_0, 2, 1, 0), | ||
| 149 | }; | ||
| 150 | |||
| 151 | static const struct snd_kcontrol_new ld1_right_kcontrols[] = { | ||
| 152 | SOC_DAPM_SINGLE("DACR LD1R Switch", AUD96P22_LDR1SEL_1, 8, 1, 0), | ||
| 153 | SOC_DAPM_SINGLE("AINR LD1R Switch", AUD96P22_LDR1SEL_1, 9, 1, 0), | ||
| 154 | SOC_DAPM_SINGLE("AINL LD1R Switch", AUD96P22_LDR1SEL_1, 10, 1, 0), | ||
| 155 | }; | ||
| 156 | |||
| 157 | static const struct snd_kcontrol_new ld2_kcontrols[] = { | ||
| 158 | SOC_DAPM_SINGLE("DACL LD2 Switch", AUD96P22_LDR2SEL_0, 0, 1, 0), | ||
| 159 | SOC_DAPM_SINGLE("AINL LD2 Switch", AUD96P22_LDR2SEL_0, 1, 1, 0), | ||
| 160 | SOC_DAPM_SINGLE("DACR LD2 Switch", AUD96P22_LDR2SEL_0, 2, 1, 0), | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const struct snd_soc_dapm_widget aud96p22_dapm_widgets[] = { | ||
| 164 | /* Overall power bit */ | ||
| 165 | SND_SOC_DAPM_SUPPLY("POWER", AUD96P22_PD_0, 0, 0, NULL, 0), | ||
| 166 | |||
| 167 | /* Input pins */ | ||
| 168 | SND_SOC_DAPM_INPUT("AINL1P"), | ||
| 169 | SND_SOC_DAPM_INPUT("AINL2P"), | ||
| 170 | SND_SOC_DAPM_INPUT("AINL3"), | ||
| 171 | SND_SOC_DAPM_INPUT("AINL1N"), | ||
| 172 | SND_SOC_DAPM_INPUT("AINL2N"), | ||
| 173 | SND_SOC_DAPM_INPUT("AINR2N"), | ||
| 174 | SND_SOC_DAPM_INPUT("AINR1N"), | ||
| 175 | SND_SOC_DAPM_INPUT("AINR3"), | ||
| 176 | SND_SOC_DAPM_INPUT("AINR2P"), | ||
| 177 | SND_SOC_DAPM_INPUT("AINR1P"), | ||
| 178 | |||
| 179 | /* Input muxes */ | ||
| 180 | SND_SOC_DAPM_MUX("AINLMUX", AUD96P22_PD_1, 2, 0, &ainl_mux_kcontrol), | ||
| 181 | SND_SOC_DAPM_MUX("AINRMUX", AUD96P22_PD_1, 3, 0, &ainr_mux_kcontrol), | ||
| 182 | |||
| 183 | /* ADCs */ | ||
| 184 | SND_SOC_DAPM_ADC_E("ADCL", "Capture Left", AUD96P22_PD_1, 0, 0, | ||
| 185 | aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), | ||
| 186 | SND_SOC_DAPM_ADC_E("ADCR", "Capture Right", AUD96P22_PD_1, 1, 0, | ||
| 187 | aud96p22_adc_event, SND_SOC_DAPM_POST_PMU), | ||
| 188 | |||
| 189 | /* DACs */ | ||
| 190 | SND_SOC_DAPM_DAC_E("DACL", "Playback Left", AUD96P22_PD_3, 0, 0, | ||
| 191 | aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), | ||
| 192 | SND_SOC_DAPM_DAC_E("DACR", "Playback Right", AUD96P22_PD_3, 1, 0, | ||
| 193 | aud96p22_dac_event, SND_SOC_DAPM_POST_PMU), | ||
| 194 | |||
| 195 | /* Output mixers */ | ||
| 196 | SND_SOC_DAPM_MIXER("LD1L", AUD96P22_PD_3, 6, 0, ld1_left_kcontrols, | ||
| 197 | ARRAY_SIZE(ld1_left_kcontrols)), | ||
| 198 | SND_SOC_DAPM_MIXER("LD1R", AUD96P22_PD_3, 7, 0, ld1_right_kcontrols, | ||
| 199 | ARRAY_SIZE(ld1_right_kcontrols)), | ||
| 200 | SND_SOC_DAPM_MIXER("LD2", AUD96P22_PD_4, 2, 0, ld2_kcontrols, | ||
| 201 | ARRAY_SIZE(ld2_kcontrols)), | ||
| 202 | |||
| 203 | /* Headset power switch */ | ||
| 204 | SND_SOC_DAPM_SUPPLY("HS1L", AUD96P22_PD_3, 4, 0, NULL, 0), | ||
| 205 | SND_SOC_DAPM_SUPPLY("HS1R", AUD96P22_PD_3, 5, 0, NULL, 0), | ||
| 206 | |||
| 207 | /* Output pins */ | ||
| 208 | SND_SOC_DAPM_OUTPUT("HSOUTL"), | ||
| 209 | SND_SOC_DAPM_OUTPUT("LINEOUTL"), | ||
| 210 | SND_SOC_DAPM_OUTPUT("LINEOUTMP"), | ||
| 211 | SND_SOC_DAPM_OUTPUT("LINEOUTMN"), | ||
| 212 | SND_SOC_DAPM_OUTPUT("LINEOUTR"), | ||
| 213 | SND_SOC_DAPM_OUTPUT("HSOUTR"), | ||
| 214 | }; | ||
| 215 | |||
| 216 | static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = { | ||
| 217 | { "AINLMUX", "AINL1 differential", "AINL1N" }, | ||
| 218 | { "AINLMUX", "AINL1 single-ended", "AINL1P" }, | ||
| 219 | { "AINLMUX", "AINL3 single-ended", "AINL3" }, | ||
| 220 | { "AINLMUX", "AINL2 differential", "AINL2N" }, | ||
| 221 | { "AINLMUX", "AINL2 single-ended", "AINL2P" }, | ||
| 222 | |||
| 223 | { "AINRMUX", "AINR1 differential", "AINR1N" }, | ||
| 224 | { "AINRMUX", "AINR1 single-ended", "AINR1P" }, | ||
| 225 | { "AINRMUX", "AINR3 single-ended", "AINR3" }, | ||
| 226 | { "AINRMUX", "AINR2 differential", "AINR2N" }, | ||
| 227 | { "AINRMUX", "AINR2 single-ended", "AINR2P" }, | ||
| 228 | |||
| 229 | { "ADCL", NULL, "AINLMUX" }, | ||
| 230 | { "ADCR", NULL, "AINRMUX" }, | ||
| 231 | |||
| 232 | { "ADCL", NULL, "POWER" }, | ||
| 233 | { "ADCR", NULL, "POWER" }, | ||
| 234 | { "DACL", NULL, "POWER" }, | ||
| 235 | { "DACR", NULL, "POWER" }, | ||
| 236 | |||
| 237 | { "LD1L", "DACL LD1L Switch", "DACL" }, | ||
| 238 | { "LD1L", "AINL LD1L Switch", "AINLMUX" }, | ||
| 239 | { "LD1L", "AINR LD1L Switch", "AINRMUX" }, | ||
| 240 | |||
| 241 | { "LD1R", "DACR LD1R Switch", "DACR" }, | ||
| 242 | { "LD1R", "AINR LD1R Switch", "AINRMUX" }, | ||
| 243 | { "LD1R", "AINL LD1R Switch", "AINLMUX" }, | ||
| 244 | |||
| 245 | { "LD2", "DACL LD2 Switch", "DACL" }, | ||
| 246 | { "LD2", "AINL LD2 Switch", "AINLMUX" }, | ||
| 247 | { "LD2", "DACR LD2 Switch", "DACR" }, | ||
| 248 | |||
| 249 | { "HSOUTL", NULL, "LD1L" }, | ||
| 250 | { "HSOUTR", NULL, "LD1R" }, | ||
| 251 | { "HSOUTL", NULL, "HS1L" }, | ||
| 252 | { "HSOUTR", NULL, "HS1R" }, | ||
| 253 | |||
| 254 | { "LINEOUTL", NULL, "LD1L" }, | ||
| 255 | { "LINEOUTR", NULL, "LD1R" }, | ||
| 256 | |||
| 257 | { "LINEOUTMP", NULL, "LD2" }, | ||
| 258 | { "LINEOUTMN", NULL, "LD2" }, | ||
| 259 | }; | ||
| 260 | |||
| 261 | static const struct snd_soc_component_driver aud96p22_driver = { | ||
| 262 | .controls = aud96p22_snd_controls, | ||
| 263 | .num_controls = ARRAY_SIZE(aud96p22_snd_controls), | ||
| 264 | .dapm_widgets = aud96p22_dapm_widgets, | ||
| 265 | .num_dapm_widgets = ARRAY_SIZE(aud96p22_dapm_widgets), | ||
| 266 | .dapm_routes = aud96p22_dapm_routes, | ||
| 267 | .num_dapm_routes = ARRAY_SIZE(aud96p22_dapm_routes), | ||
| 268 | .idle_bias_on = 1, | ||
| 269 | .use_pmdown_time = 1, | ||
| 270 | .endianness = 1, | ||
| 271 | .non_legacy_dai_naming = 1, | ||
| 272 | }; | ||
| 273 | |||
| 274 | static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
| 275 | { | ||
| 276 | struct aud96p22_priv *priv = snd_soc_component_get_drvdata(dai->component); | ||
| 277 | struct regmap *regmap = priv->regmap; | ||
| 278 | unsigned int val; | ||
| 279 | |||
| 280 | /* Master/slave mode */ | ||
| 281 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 282 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 283 | val = 0; | ||
| 284 | break; | ||
| 285 | case SND_SOC_DAIFMT_CBM_CFM: | ||
| 286 | val = I2S1_MS_MODE; | ||
| 287 | break; | ||
| 288 | default: | ||
| 289 | return -EINVAL; | ||
| 290 | } | ||
| 291 | |||
| 292 | regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MS_MODE, val); | ||
| 293 | |||
| 294 | /* Audio format */ | ||
| 295 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 296 | case SND_SOC_DAIFMT_RIGHT_J: | ||
| 297 | val = I2S1_MODE_RIGHT_J; | ||
| 298 | break; | ||
| 299 | case SND_SOC_DAIFMT_I2S: | ||
| 300 | val = I2S1_MODE_I2S; | ||
| 301 | break; | ||
| 302 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 303 | val = I2S1_MODE_LEFT_J; | ||
| 304 | break; | ||
| 305 | default: | ||
| 306 | return -EINVAL; | ||
| 307 | } | ||
| 308 | |||
| 309 | regmap_update_bits(regmap, AUD96P22_I2S1_CONFIG_0, I2S1_MODE_MASK, val); | ||
| 310 | |||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | |||
| 314 | static const struct snd_soc_dai_ops aud96p22_dai_ops = { | ||
| 315 | .set_fmt = aud96p22_set_fmt, | ||
| 316 | }; | ||
| 317 | |||
| 318 | #define AUD96P22_RATES SNDRV_PCM_RATE_8000_192000 | ||
| 319 | #define AUD96P22_FORMATS (\ | ||
| 320 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ | ||
| 321 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) | ||
| 322 | |||
| 323 | static struct snd_soc_dai_driver aud96p22_dai = { | ||
| 324 | .name = "aud96p22-dai", | ||
| 325 | .playback = { | ||
| 326 | .stream_name = "Playback", | ||
| 327 | .channels_min = 1, | ||
| 328 | .channels_max = 2, | ||
| 329 | .rates = AUD96P22_RATES, | ||
| 330 | .formats = AUD96P22_FORMATS, | ||
| 331 | }, | ||
| 332 | .capture = { | ||
| 333 | .stream_name = "Capture", | ||
| 334 | .channels_min = 1, | ||
| 335 | .channels_max = 2, | ||
| 336 | .rates = AUD96P22_RATES, | ||
| 337 | .formats = AUD96P22_FORMATS, | ||
| 338 | }, | ||
| 339 | .ops = &aud96p22_dai_ops, | ||
| 340 | }; | ||
| 341 | |||
| 342 | static const struct regmap_config aud96p22_regmap = { | ||
| 343 | .reg_bits = 8, | ||
| 344 | .val_bits = 8, | ||
| 345 | .max_register = AUD96P22_REG_MAX, | ||
| 346 | .cache_type = REGCACHE_RBTREE, | ||
| 347 | }; | ||
| 348 | |||
| 349 | static int aud96p22_i2c_probe(struct i2c_client *i2c, | ||
| 350 | const struct i2c_device_id *id) | ||
| 351 | { | ||
| 352 | struct device *dev = &i2c->dev; | ||
| 353 | struct aud96p22_priv *priv; | ||
| 354 | int ret; | ||
| 355 | |||
| 356 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
| 357 | if (priv == NULL) | ||
| 358 | return -ENOMEM; | ||
| 359 | |||
| 360 | priv->regmap = devm_regmap_init_i2c(i2c, &aud96p22_regmap); | ||
| 361 | if (IS_ERR(priv->regmap)) { | ||
| 362 | ret = PTR_ERR(priv->regmap); | ||
| 363 | dev_err(dev, "failed to init i2c regmap: %d\n", ret); | ||
| 364 | return ret; | ||
| 365 | } | ||
| 366 | |||
| 367 | i2c_set_clientdata(i2c, priv); | ||
| 368 | |||
| 369 | ret = devm_snd_soc_register_component(dev, &aud96p22_driver, &aud96p22_dai, 1); | ||
| 370 | if (ret) { | ||
| 371 | dev_err(dev, "failed to register component: %d\n", ret); | ||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | |||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | static int aud96p22_i2c_remove(struct i2c_client *i2c) | ||
| 379 | { | ||
| 380 | return 0; | ||
| 381 | } | ||
| 382 | |||
| 383 | static const struct of_device_id aud96p22_dt_ids[] = { | ||
| 384 | { .compatible = "zte,zx-aud96p22", }, | ||
| 385 | { } | ||
| 386 | }; | ||
| 387 | MODULE_DEVICE_TABLE(of, aud96p22_dt_ids); | ||
| 388 | |||
| 389 | static struct i2c_driver aud96p22_i2c_driver = { | ||
| 390 | .driver = { | ||
| 391 | .name = "zx_aud96p22", | ||
| 392 | .of_match_table = aud96p22_dt_ids, | ||
| 393 | }, | ||
| 394 | .probe = aud96p22_i2c_probe, | ||
| 395 | .remove = aud96p22_i2c_remove, | ||
| 396 | }; | ||
| 397 | module_i2c_driver(aud96p22_i2c_driver); | ||
| 398 | |||
| 399 | MODULE_DESCRIPTION("ZTE ASoC AUD96P22 CODEC driver"); | ||
| 400 | MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>"); | ||
| 401 | MODULE_LICENSE("GPL v2"); | ||
| @@ -108,6 +108,7 @@ config SND_SOC_FSL_XCVR · 107 unmodified lines | |||
| 108 | config SND_SOC_FSL_AUD2HTX | 108 | config SND_SOC_FSL_AUD2HTX |
| 109 | tristate "AUDIO TO HDMI TX module support" | 109 | tristate "AUDIO TO HDMI TX module support" |
| 110 | depends on ARCH_MXC || COMPILE_TEST | 110 | depends on ARCH_MXC || COMPILE_TEST |
| 111 | select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n | ||
| 111 | help | 112 | help |
| 112 | Say Y if you want to add AUDIO TO HDMI TX support for NXP. | 113 | Say Y if you want to add AUDIO TO HDMI TX support for NXP. |
| 113 | 114 | ||
| @@ -1083,11 +1083,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) · 1082 unmodified lines | |||
| 1083 | } | 1083 | } |
| 1084 | 1084 | ||
| 1085 | asrc_priv->soc = of_device_get_match_data(&pdev->dev); | 1085 | asrc_priv->soc = of_device_get_match_data(&pdev->dev); |
| 1086 | if (!asrc_priv->soc) { | ||
| 1087 | dev_err(&pdev->dev, "failed to get soc data\n"); | ||
| 1088 | return -ENODEV; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | asrc->use_edma = asrc_priv->soc->use_edma; | 1086 | asrc->use_edma = asrc_priv->soc->use_edma; |
| 1092 | asrc->get_dma_channel = fsl_asrc_get_dma_channel; | 1087 | asrc->get_dma_channel = fsl_asrc_get_dma_channel; |
| 1093 | asrc->request_pair = fsl_asrc_request_pair; | 1088 | asrc->request_pair = fsl_asrc_request_pair; |
| @@ -1530,7 +1530,7 @@ static int fsl_easrc_hw_free(struct snd_pcm_substream *substream, · 1529 unmodified lines | |||
| 1530 | return 0; | 1530 | return 0; |
| 1531 | } | 1531 | } |
| 1532 | 1532 | ||
| 1533 | static struct snd_soc_dai_ops fsl_easrc_dai_ops = { | 1533 | static const struct snd_soc_dai_ops fsl_easrc_dai_ops = { |
| 1534 | .startup = fsl_easrc_startup, | 1534 | .startup = fsl_easrc_startup, |
| 1535 | .trigger = fsl_easrc_trigger, | 1535 | .trigger = fsl_easrc_trigger, |
| 1536 | .hw_params = fsl_easrc_hw_params, | 1536 | .hw_params = fsl_easrc_hw_params, |
| @@ -23,11 +23,9 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | * struct fsl_esai_soc_data - soc specific data | 25 | * struct fsl_esai_soc_data - soc specific data |
| 26 | * @imx: for imx platform | ||
| 27 | * @reset_at_xrun: flags for enable reset operaton | 26 | * @reset_at_xrun: flags for enable reset operaton |
| 28 | */ | 27 | */ |
| 29 | struct fsl_esai_soc_data { | 28 | struct fsl_esai_soc_data { |
| 30 | bool imx; | ||
| 31 | bool reset_at_xrun; | 29 | bool reset_at_xrun; |
| 32 | }; | 30 | }; |
| 33 | 31 | ||
| @@ -86,17 +84,14 @@ struct fsl_esai { · 52 unmodified lines | |||
| 86 | }; | 84 | }; |
| 87 | 85 | ||
| 88 | static struct fsl_esai_soc_data fsl_esai_vf610 = { | 86 | static struct fsl_esai_soc_data fsl_esai_vf610 = { |
| 89 | .imx = false, | ||
| 90 | .reset_at_xrun = true, | 87 | .reset_at_xrun = true, |
| 91 | }; | 88 | }; |
| 92 | 89 | ||
| 93 | static struct fsl_esai_soc_data fsl_esai_imx35 = { | 90 | static struct fsl_esai_soc_data fsl_esai_imx35 = { |
| 94 | .imx = true, | ||
| 95 | .reset_at_xrun = true, | 91 | .reset_at_xrun = true, |
| 96 | }; | 92 | }; |
| 97 | 93 | ||
| 98 | static struct fsl_esai_soc_data fsl_esai_imx6ull = { | 94 | static struct fsl_esai_soc_data fsl_esai_imx6ull = { |
| 99 | .imx = true, | ||
| 100 | .reset_at_xrun = false, | 95 | .reset_at_xrun = false, |
| 101 | }; | 96 | }; |
| 102 | 97 | ||
| @@ -967,10 +962,6 @@ static int fsl_esai_probe(struct platform_device *pdev) · 864 unmodified lines | |||
| 967 | snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); | 962 | snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); |
| 968 | 963 | ||
| 969 | esai_priv->soc = of_device_get_match_data(&pdev->dev); | 964 | esai_priv->soc = of_device_get_match_data(&pdev->dev); |
| 970 | if (!esai_priv->soc) { | ||
| 971 | dev_err(&pdev->dev, "failed to get soc data\n"); | ||
| 972 | return -ENODEV; | ||
| 973 | } | ||
| 974 | 965 | ||
| 975 | /* Get the addresses and IRQ */ | 966 | /* Get the addresses and IRQ */ |
| 976 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 967 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -1042,9 +1033,9 @@ static int fsl_esai_probe(struct platform_device *pdev) · 65 unmodified lines | |||
| 1042 | 1033 | ||
| 1043 | /* Implement full symmetry for synchronous mode */ | 1034 | /* Implement full symmetry for synchronous mode */ |
| 1044 | if (esai_priv->synchronous) { | 1035 | if (esai_priv->synchronous) { |
| 1045 | fsl_esai_dai.symmetric_rates = 1; | 1036 | fsl_esai_dai.symmetric_rate = 1; |
| 1046 | fsl_esai_dai.symmetric_channels = 1; | 1037 | fsl_esai_dai.symmetric_channels = 1; |
| 1047 | fsl_esai_dai.symmetric_samplebits = 1; | 1038 | fsl_esai_dai.symmetric_sample_bits = 1; |
| 1048 | } | 1039 | } |
| 1049 | 1040 | ||
| 1050 | dev_set_drvdata(&pdev->dev, esai_priv); | 1041 | dev_set_drvdata(&pdev->dev, esai_priv); |
| @@ -381,7 +381,7 @@ static int fsl_micfil_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, · 380 unmodified lines | |||
| 381 | return ret; | 381 | return ret; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | static struct snd_soc_dai_ops fsl_micfil_dai_ops = { | 384 | static const struct snd_soc_dai_ops fsl_micfil_dai_ops = { |
| 385 | .startup = fsl_micfil_startup, | 385 | .startup = fsl_micfil_startup, |
| 386 | .trigger = fsl_micfil_trigger, | 386 | .trigger = fsl_micfil_trigger, |
| 387 | .hw_params = fsl_micfil_hw_params, | 387 | .hw_params = fsl_micfil_hw_params, |
| @@ -637,7 +637,6 @@ static irqreturn_t micfil_err_isr(int irq, void *devid) · 249 unmodified lines | |||
| 637 | static int fsl_micfil_probe(struct platform_device *pdev) | 637 | static int fsl_micfil_probe(struct platform_device *pdev) |
| 638 | { | 638 | { |
| 639 | struct device_node *np = pdev->dev.of_node; | 639 | struct device_node *np = pdev->dev.of_node; |
| 640 | const struct of_device_id *of_id; | ||
| 641 | struct fsl_micfil *micfil; | 640 | struct fsl_micfil *micfil; |
| 642 | struct resource *res; | 641 | struct resource *res; |
| 643 | void __iomem *regs; | 642 | void __iomem *regs; |
| @@ -651,11 +650,7 @@ static int fsl_micfil_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 651 | micfil->pdev = pdev; | 650 | micfil->pdev = pdev; |
| 652 | strncpy(micfil->name, np->name, sizeof(micfil->name) - 1); | 651 | strncpy(micfil->name, np->name, sizeof(micfil->name) - 1); |
| 653 | 652 | ||
| 654 | of_id = of_match_device(fsl_micfil_dt_ids, &pdev->dev); | 653 | micfil->soc = of_device_get_match_data(&pdev->dev); |
| 655 | if (!of_id || !of_id->data) | ||
| 656 | return -EINVAL; | ||
| 657 | |||
| 658 | micfil->soc = of_id->data; | ||
| 659 | 654 | ||
| 660 | /* ipg_clk is used to control the registers | 655 | /* ipg_clk is used to control the registers |
| 661 | * ipg_clk_app is used to operate the filter | 656 | * ipg_clk_app is used to operate the filter |
| @@ -1079,9 +1079,9 @@ static int fsl_sai_probe(struct platform_device *pdev) · 1078 unmodified lines | |||
| 1079 | /* Sync Tx with Rx as default by following old DT binding */ | 1079 | /* Sync Tx with Rx as default by following old DT binding */ |
| 1080 | sai->synchronous[RX] = true; | 1080 | sai->synchronous[RX] = true; |
| 1081 | sai->synchronous[TX] = false; | 1081 | sai->synchronous[TX] = false; |
| 1082 | sai->cpu_dai_drv.symmetric_rates = 1; | 1082 | sai->cpu_dai_drv.symmetric_rate = 1; |
| 1083 | sai->cpu_dai_drv.symmetric_channels = 1; | 1083 | sai->cpu_dai_drv.symmetric_channels = 1; |
| 1084 | sai->cpu_dai_drv.symmetric_samplebits = 1; | 1084 | sai->cpu_dai_drv.symmetric_sample_bits = 1; |
| 1085 | 1085 | ||
| 1086 | if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && | 1086 | if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && |
| 1087 | of_find_property(np, "fsl,sai-asynchronous", NULL)) { | 1087 | of_find_property(np, "fsl,sai-asynchronous", NULL)) { |
| @@ -1098,9 +1098,9 @@ static int fsl_sai_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 1098 | /* Discard all settings for asynchronous mode */ | 1098 | /* Discard all settings for asynchronous mode */ |
| 1099 | sai->synchronous[RX] = false; | 1099 | sai->synchronous[RX] = false; |
| 1100 | sai->synchronous[TX] = false; | 1100 | sai->synchronous[TX] = false; |
| 1101 | sai->cpu_dai_drv.symmetric_rates = 0; | 1101 | sai->cpu_dai_drv.symmetric_rate = 0; |
| 1102 | sai->cpu_dai_drv.symmetric_channels = 0; | 1102 | sai->cpu_dai_drv.symmetric_channels = 0; |
| 1103 | sai->cpu_dai_drv.symmetric_samplebits = 0; | 1103 | sai->cpu_dai_drv.symmetric_sample_bits = 0; |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && | 1106 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && |
| @@ -1255,7 +1255,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, · 1254 unmodified lines | |||
| 1255 | 1255 | ||
| 1256 | for (i = 0; i < STC_TXCLK_SRC_MAX; i++) { | 1256 | for (i = 0; i < STC_TXCLK_SRC_MAX; i++) { |
| 1257 | sprintf(tmp, "rxtx%d", i); | 1257 | sprintf(tmp, "rxtx%d", i); |
| 1258 | clk = devm_clk_get(&pdev->dev, tmp); | 1258 | clk = devm_clk_get(dev, tmp); |
| 1259 | if (IS_ERR(clk)) { | 1259 | if (IS_ERR(clk)) { |
| 1260 | dev_err(dev, "no rxtx%d clock in devicetree\n", i); | 1260 | dev_err(dev, "no rxtx%d clock in devicetree\n", i); |
| 1261 | return PTR_ERR(clk); | 1261 | return PTR_ERR(clk); |
| @@ -1277,14 +1277,14 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, · 15 unmodified lines | |||
| 1277 | break; | 1277 | break; |
| 1278 | } | 1278 | } |
| 1279 | 1279 | ||
| 1280 | dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", | 1280 | dev_dbg(dev, "use rxtx%d as tx clock source for %dHz sample rate\n", |
| 1281 | spdif_priv->txclk_src[index], rate[index]); | 1281 | spdif_priv->txclk_src[index], rate[index]); |
| 1282 | dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n", | 1282 | dev_dbg(dev, "use txclk df %d for %dHz sample rate\n", |
| 1283 | spdif_priv->txclk_df[index], rate[index]); | 1283 | spdif_priv->txclk_df[index], rate[index]); |
| 1284 | if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk)) | 1284 | if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk)) |
| 1285 | dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n", | 1285 | dev_dbg(dev, "use sysclk df %d for %dHz sample rate\n", |
| 1286 | spdif_priv->sysclk_df[index], rate[index]); | 1286 | spdif_priv->sysclk_df[index], rate[index]); |
| 1287 | dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n", | 1287 | dev_dbg(dev, "the best rate for %dHz sample rate is %dHz\n", |
| 1288 | rate[index], spdif_priv->txrate[index]); | 1288 | rate[index], spdif_priv->txrate[index]); |
| 1289 | 1289 | ||
| 1290 | return 0; | 1290 | return 0; |
| @@ -1305,10 +1305,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 1305 | spdif_priv->pdev = pdev; | 1305 | spdif_priv->pdev = pdev; |
| 1306 | 1306 | ||
| 1307 | spdif_priv->soc = of_device_get_match_data(&pdev->dev); | 1307 | spdif_priv->soc = of_device_get_match_data(&pdev->dev); |
| 1308 | if (!spdif_priv->soc) { | ||
| 1309 | dev_err(&pdev->dev, "failed to get soc data\n"); | ||
| 1310 | return -ENODEV; | ||
| 1311 | } | ||
| 1312 | 1308 | ||
| 1313 | /* Initialize this copy of the CPU DAI driver structure */ | 1309 | /* Initialize this copy of the CPU DAI driver structure */ |
| 1314 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); | 1310 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); |
| @@ -1397,18 +1397,11 @@ static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi) · 1396 unmodified lines | |||
| 1397 | { | 1397 | { |
| 1398 | struct device *dev = ssi->dev; | 1398 | struct device *dev = ssi->dev; |
| 1399 | struct device_node *np = dev->of_node; | 1399 | struct device_node *np = dev->of_node; |
| 1400 | const struct of_device_id *of_id; | ||
| 1401 | const char *p, *sprop; | 1400 | const char *p, *sprop; |
| 1402 | const __be32 *iprop; | 1401 | const __be32 *iprop; |
| 1403 | u32 dmas[4]; | 1402 | u32 dmas[4]; |
| 1404 | int ret; | 1403 | int ret; |
| 1405 | 1404 | ||
| 1406 | of_id = of_match_device(fsl_ssi_ids, dev); | ||
| 1407 | if (!of_id || !of_id->data) | ||
| 1408 | return -EINVAL; | ||
| 1409 | |||
| 1410 | ssi->soc = of_id->data; | ||
| 1411 | |||
| 1412 | ret = of_property_match_string(np, "clock-names", "ipg"); | 1405 | ret = of_property_match_string(np, "clock-names", "ipg"); |
| 1413 | /* Get error code if not found */ | 1406 | /* Get error code if not found */ |
| 1414 | ssi->has_ipg_clk_name = ret >= 0; | 1407 | ssi->has_ipg_clk_name = ret >= 0; |
| @@ -1492,6 +1485,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 77 unmodified lines | |||
| 1492 | return -ENOMEM; | 1485 | return -ENOMEM; |
| 1493 | 1486 | ||
| 1494 | ssi->dev = dev; | 1487 | ssi->dev = dev; |
| 1488 | ssi->soc = of_device_get_match_data(&pdev->dev); | ||
| 1495 | 1489 | ||
| 1496 | /* Probe from DT */ | 1490 | /* Probe from DT */ |
| 1497 | ret = fsl_ssi_probe_from_dt(ssi); | 1491 | ret = fsl_ssi_probe_from_dt(ssi); |
| @@ -1537,9 +1531,9 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 39 unmodified lines | |||
| 1537 | 1531 | ||
| 1538 | /* Set software limitations for synchronous mode except AC97 */ | 1532 | /* Set software limitations for synchronous mode except AC97 */ |
| 1539 | if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { | 1533 | if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { |
| 1540 | ssi->cpu_dai_drv.symmetric_rates = 1; | 1534 | ssi->cpu_dai_drv.symmetric_rate = 1; |
| 1541 | ssi->cpu_dai_drv.symmetric_channels = 1; | 1535 | ssi->cpu_dai_drv.symmetric_channels = 1; |
| 1542 | ssi->cpu_dai_drv.symmetric_samplebits = 1; | 1536 | ssi->cpu_dai_drv.symmetric_sample_bits = 1; |
| 1543 | } | 1537 | } |
| 1544 | 1538 | ||
| 1545 | /* | 1539 | /* |
| @@ -857,7 +857,7 @@ static struct snd_kcontrol_new fsl_xcvr_tx_ctls[] = { · 856 unmodified lines | |||
| 857 | }, | 857 | }, |
| 858 | }; | 858 | }; |
| 859 | 859 | ||
| 860 | static struct snd_soc_dai_ops fsl_xcvr_dai_ops = { | 860 | static const struct snd_soc_dai_ops fsl_xcvr_dai_ops = { |
| 861 | .prepare = fsl_xcvr_prepare, | 861 | .prepare = fsl_xcvr_prepare, |
| 862 | .startup = fsl_xcvr_startup, | 862 | .startup = fsl_xcvr_startup, |
| 863 | .shutdown = fsl_xcvr_shutdown, | 863 | .shutdown = fsl_xcvr_shutdown, |
| @@ -1130,16 +1130,11 @@ MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids); · 266 unmodified lines | |||
| 1130 | static int fsl_xcvr_probe(struct platform_device *pdev) | 1130 | static int fsl_xcvr_probe(struct platform_device *pdev) |
| 1131 | { | 1131 | { |
| 1132 | struct device *dev = &pdev->dev; | 1132 | struct device *dev = &pdev->dev; |
| 1133 | const struct of_device_id *of_id; | ||
| 1134 | struct fsl_xcvr *xcvr; | 1133 | struct fsl_xcvr *xcvr; |
| 1135 | struct resource *ram_res, *regs_res, *rx_res, *tx_res; | 1134 | struct resource *ram_res, *regs_res, *rx_res, *tx_res; |
| 1136 | void __iomem *regs; | 1135 | void __iomem *regs; |
| 1137 | int ret, irq; | 1136 | int ret, irq; |
| 1138 | 1137 | ||
| 1139 | of_id = of_match_device(fsl_xcvr_dt_ids, dev); | ||
| 1140 | if (!of_id) | ||
| 1141 | return -EINVAL; | ||
| 1142 | |||
| 1143 | xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL); | 1138 | xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL); |
| 1144 | if (!xcvr) | 1139 | if (!xcvr) |
| 1145 | return -ENOMEM; | 1140 | return -ENOMEM; |
| @@ -532,7 +532,7 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, · 531 unmodified lines | |||
| 532 | static void graph_get_dais_count(struct asoc_simple_priv *priv, | 532 | static void graph_get_dais_count(struct asoc_simple_priv *priv, |
| 533 | struct link_info *li); | 533 | struct link_info *li); |
| 534 | 534 | ||
| 535 | int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) | 535 | int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev) |
| 536 | { | 536 | { |
| 537 | struct snd_soc_card *card = simple_priv_to_card(priv); | 537 | struct snd_soc_card *card = simple_priv_to_card(priv); |
| 538 | struct link_info li; | 538 | struct link_info li; |
| @@ -608,7 +608,7 @@ err: · 69 unmodified lines | |||
| 608 | 608 | ||
| 609 | return ret; | 609 | return ret; |
| 610 | } | 610 | } |
| 611 | EXPORT_SYMBOL_GPL(graph_parse_of); | 611 | EXPORT_SYMBOL_GPL(audio_graph_parse_of); |
| 612 | 612 | ||
| 613 | static int graph_count_noml(struct asoc_simple_priv *priv, | 613 | static int graph_count_noml(struct asoc_simple_priv *priv, |
| 614 | struct device_node *cpu_ep, | 614 | struct device_node *cpu_ep, |
| @@ -705,7 +705,7 @@ static void graph_get_dais_count(struct asoc_simple_priv *priv, · 90 unmodified lines | |||
| 705 | li->link, li->dais, li->conf); | 705 | li->link, li->dais, li->conf); |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | int graph_card_probe(struct snd_soc_card *card) | 708 | int audio_graph_card_probe(struct snd_soc_card *card) |
| 709 | { | 709 | { |
| 710 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); | 710 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); |
| 711 | int ret; | 711 | int ret; |
| @@ -720,7 +720,7 @@ int graph_card_probe(struct snd_soc_card *card) · 8 unmodified lines | |||
| 720 | 720 | ||
| 721 | return 0; | 721 | return 0; |
| 722 | } | 722 | } |
| 723 | EXPORT_SYMBOL_GPL(graph_card_probe); | 723 | EXPORT_SYMBOL_GPL(audio_graph_card_probe); |
| 724 | 724 | ||
| 725 | static int graph_probe(struct platform_device *pdev) | 725 | static int graph_probe(struct platform_device *pdev) |
| 726 | { | 726 | { |
| @@ -736,20 +736,21 @@ static int graph_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 736 | card = simple_priv_to_card(priv); | 736 | card = simple_priv_to_card(priv); |
| 737 | card->dapm_widgets = graph_dapm_widgets; | 737 | card->dapm_widgets = graph_dapm_widgets; |
| 738 | card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets); | 738 | card->num_dapm_widgets = ARRAY_SIZE(graph_dapm_widgets); |
| 739 | card->probe = graph_card_probe; | 739 | card->probe = audio_graph_card_probe; |
| 740 | 740 | ||
| 741 | if (of_device_get_match_data(dev)) | 741 | if (of_device_get_match_data(dev)) |
| 742 | priv->dpcm_selectable = 1; | 742 | priv->dpcm_selectable = 1; |
| 743 | 743 | ||
| 744 | return graph_parse_of(priv, dev); | 744 | return audio_graph_parse_of(priv, dev); |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | static int graph_remove(struct platform_device *pdev) | 747 | int audio_graph_remove(struct platform_device *pdev) |
| 748 | { | 748 | { |
| 749 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 749 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
| 750 | 750 | ||
| 751 | return asoc_simple_clean_reference(card); | 751 | return asoc_simple_clean_reference(card); |
| 752 | } | 752 | } |
| 753 | EXPORT_SYMBOL_GPL(audio_graph_remove); | ||
| 753 | 754 | ||
| 754 | static const struct of_device_id graph_of_match[] = { | 755 | static const struct of_device_id graph_of_match[] = { |
| 755 | { .compatible = "audio-graph-card", }, | 756 | { .compatible = "audio-graph-card", }, |
| @@ -766,7 +767,7 @@ static struct platform_driver graph_card = { · 10 unmodified lines | |||
| 766 | .of_match_table = graph_of_match, | 767 | .of_match_table = graph_of_match, |
| 767 | }, | 768 | }, |
| 768 | .probe = graph_probe, | 769 | .probe = graph_probe, |
| 769 | .remove = graph_remove, | 770 | .remove = audio_graph_remove, |
| 770 | }; | 771 | }; |
| 771 | module_platform_driver(graph_card); | 772 | module_platform_driver(graph_card); |
| 772 | 773 | ||
| @@ -172,16 +172,15 @@ int asoc_simple_parse_clk(struct device *dev, · 171 unmodified lines | |||
| 172 | * or device's module clock. | 172 | * or device's module clock. |
| 173 | */ | 173 | */ |
| 174 | clk = devm_get_clk_from_child(dev, node, NULL); | 174 | clk = devm_get_clk_from_child(dev, node, NULL); |
| 175 | if (!IS_ERR(clk)) { | 175 | if (IS_ERR(clk)) |
| 176 | simple_dai->sysclk = clk_get_rate(clk); | 176 | clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); |
| 177 | 177 | ||
| 178 | if (!IS_ERR(clk)) { | ||
| 178 | simple_dai->clk = clk; | 179 | simple_dai->clk = clk; |
| 179 | } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { | 180 | simple_dai->sysclk = clk_get_rate(clk); |
| 181 | } else if (!of_property_read_u32(node, "system-clock-frequency", | ||
| 182 | &val)) { | ||
| 180 | simple_dai->sysclk = val; | 183 | simple_dai->sysclk = val; |
| 181 | } else { | ||
| 182 | clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); | ||
| 183 | if (!IS_ERR(clk)) | ||
| 184 | simple_dai->sysclk = clk_get_rate(clk); | ||
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | if (of_property_read_bool(node, "system-clock-direction-out")) | 186 | if (of_property_read_bool(node, "system-clock-direction-out")) |
| @@ -203,6 +203,8 @@ config SND_SOC_INTEL_KEEMBAY · 202 unmodified lines | |||
| 203 | tristate "Keembay Platforms" | 203 | tristate "Keembay Platforms" |
| 204 | depends on ARCH_KEEMBAY || COMPILE_TEST | 204 | depends on ARCH_KEEMBAY || COMPILE_TEST |
| 205 | depends on COMMON_CLK | 205 | depends on COMMON_CLK |
| 206 | select SND_DMAENGINE_PCM | ||
| 207 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
| 206 | help | 208 | help |
| 207 | If you have a Intel Keembay platform then enable this option | 209 | If you have a Intel Keembay platform then enable this option |
| 208 | by saying Y or m. | 210 | by saying Y or m. |
| @@ -111,6 +111,18 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH · 110 unmodified lines | |||
| 111 | Say Y or m if you have such a device. This is a recommended option. | 111 | Say Y or m if you have such a device. This is a recommended option. |
| 112 | If unsure select "N". | 112 | If unsure select "N". |
| 113 | 113 | ||
| 114 | config SND_SOC_INTEL_BYTCR_WM5102_MACH | ||
| 115 | tristate "Baytrail and Baytrail-CR with WM5102 codec" | ||
| 116 | depends on MFD_ARIZONA && MFD_WM5102 && SPI_MASTER && ACPI | ||
| 117 | depends on X86_INTEL_LPSS || COMPILE_TEST | ||
| 118 | select SND_SOC_ACPI | ||
| 119 | select SND_SOC_WM5102 | ||
| 120 | help | ||
| 121 | This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR | ||
| 122 | platforms with WM5102 audio codec. | ||
| 123 | Say Y if you have such a device. | ||
| 124 | If unsure select "N". | ||
| 125 | |||
| 114 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH | 126 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH |
| 115 | tristate "Cherrytrail & Braswell with RT5672 codec" | 127 | tristate "Cherrytrail & Braswell with RT5672 codec" |
| 116 | depends on I2C && ACPI | 128 | depends on I2C && ACPI |
| @@ -10,6 +10,7 @@ snd-soc-sst-sof-wm8804-objs := sof_wm8804.o · 9 unmodified lines | |||
| 10 | snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o | 10 | snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o |
| 11 | snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o | 11 | snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o |
| 12 | snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o | 12 | snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o |
| 13 | snd-soc-sst-bytcr-wm5102-objs := bytcr_wm5102.o | ||
| 13 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o | 14 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o |
| 14 | snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o | 15 | snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o |
| 15 | snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o | 16 | snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o |
| @@ -51,6 +52,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH) += snd-soc-sst-bdw-rt5650-mach.o · 35 unmodified lines | |||
| 51 | obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o | 52 | obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o |
| 52 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o | 53 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o |
| 53 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o | 54 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o |
| 55 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH) += snd-soc-sst-bytcr-wm5102.o | ||
| 54 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o | 56 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o |
| 55 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o | 57 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o |
| 56 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o | 58 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o |
| @@ -331,9 +331,6 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { · 330 unmodified lines | |||
| 331 | 331 | ||
| 332 | /* back ends */ | 332 | /* back ends */ |
| 333 | { | 333 | { |
| 334 | /* Only SSP2 has been tested here, so BYT-CR platforms that | ||
| 335 | * require SSP0 will not work. | ||
| 336 | */ | ||
| 337 | .name = "SSP2-Codec", | 334 | .name = "SSP2-Codec", |
| 338 | .id = 0, | 335 | .id = 0, |
| 339 | .no_pcm = 1, | 336 | .no_pcm = 1, |
| @@ -35,6 +35,7 @@ enum { · 34 unmodified lines | |||
| 35 | BYT_RT5640_DMIC2_MAP, | 35 | BYT_RT5640_DMIC2_MAP, |
| 36 | BYT_RT5640_IN1_MAP, | 36 | BYT_RT5640_IN1_MAP, |
| 37 | BYT_RT5640_IN3_MAP, | 37 | BYT_RT5640_IN3_MAP, |
| 38 | BYT_RT5640_NO_INTERNAL_MIC_MAP, | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | enum { | 41 | enum { |
| @@ -71,6 +72,7 @@ enum { · 30 unmodified lines | |||
| 71 | #define BYT_RT5640_SSP0_AIF2 BIT(21) | 72 | #define BYT_RT5640_SSP0_AIF2 BIT(21) |
| 72 | #define BYT_RT5640_MCLK_EN BIT(22) | 73 | #define BYT_RT5640_MCLK_EN BIT(22) |
| 73 | #define BYT_RT5640_MCLK_25MHZ BIT(23) | 74 | #define BYT_RT5640_MCLK_25MHZ BIT(23) |
| 75 | #define BYT_RT5640_NO_SPEAKERS BIT(24) | ||
| 74 | 76 | ||
| 75 | #define BYTCR_INPUT_DEFAULTS \ | 77 | #define BYTCR_INPUT_DEFAULTS \ |
| 76 | (BYT_RT5640_IN3_MAP | \ | 78 | (BYT_RT5640_IN3_MAP | \ |
| @@ -116,6 +118,9 @@ static void log_quirks(struct device *dev) · 39 unmodified lines | |||
| 116 | case BYT_RT5640_IN3_MAP: | 118 | case BYT_RT5640_IN3_MAP: |
| 117 | dev_info(dev, "quirk IN3_MAP enabled\n"); | 119 | dev_info(dev, "quirk IN3_MAP enabled\n"); |
| 118 | break; | 120 | break; |
| 121 | case BYT_RT5640_NO_INTERNAL_MIC_MAP: | ||
| 122 | dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n"); | ||
| 123 | break; | ||
| 119 | default: | 124 | default: |
| 120 | dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); | 125 | dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); |
| 121 | break; | 126 | break; |
| @@ -132,6 +137,8 @@ static void log_quirks(struct device *dev) · 10 unmodified lines | |||
| 132 | dev_info(dev, "quirk JD_NOT_INV enabled\n"); | 137 | dev_info(dev, "quirk JD_NOT_INV enabled\n"); |
| 133 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) | 138 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) |
| 134 | dev_info(dev, "quirk MONO_SPEAKER enabled\n"); | 139 | dev_info(dev, "quirk MONO_SPEAKER enabled\n"); |
| 140 | if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) | ||
| 141 | dev_info(dev, "quirk NO_SPEAKERS enabled\n"); | ||
| 135 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) | 142 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) |
| 136 | dev_info(dev, "quirk DIFF_MIC enabled\n"); | 143 | dev_info(dev, "quirk DIFF_MIC enabled\n"); |
| 137 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { | 144 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { |
| @@ -399,6 +406,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { · 261 unmodified lines | |||
| 399 | BYT_RT5640_SSP0_AIF1 | | 406 | BYT_RT5640_SSP0_AIF1 | |
| 400 | BYT_RT5640_MCLK_EN), | 407 | BYT_RT5640_MCLK_EN), |
| 401 | }, | 408 | }, |
| 409 | { /* Acer One 10 S1002 */ | ||
| 410 | .matches = { | ||
| 411 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 412 | DMI_MATCH(DMI_PRODUCT_NAME, "One S1002"), | ||
| 413 | }, | ||
| 414 | .driver_data = (void *)(BYT_RT5640_IN1_MAP | | ||
| 415 | BYT_RT5640_JD_SRC_JD2_IN4N | | ||
| 416 | BYT_RT5640_OVCD_TH_2000UA | | ||
| 417 | BYT_RT5640_OVCD_SF_0P75 | | ||
| 418 | BYT_RT5640_DIFF_MIC | | ||
| 419 | BYT_RT5640_SSP0_AIF2 | | ||
| 420 | BYT_RT5640_MCLK_EN), | ||
| 421 | }, | ||
| 402 | { | 422 | { |
| 403 | .matches = { | 423 | .matches = { |
| 404 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 424 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
| @@ -524,6 +544,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { · 119 unmodified lines | |||
| 524 | BYT_RT5640_MONO_SPEAKER | | 544 | BYT_RT5640_MONO_SPEAKER | |
| 525 | BYT_RT5640_MCLK_EN), | 545 | BYT_RT5640_MCLK_EN), |
| 526 | }, | 546 | }, |
| 547 | { /* Estar Beauty HD MID 7316R */ | ||
| 548 | .matches = { | ||
| 549 | DMI_MATCH(DMI_SYS_VENDOR, "Estar"), | ||
| 550 | DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), | ||
| 551 | }, | ||
| 552 | .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | | ||
| 553 | BYT_RT5640_MONO_SPEAKER | | ||
| 554 | BYT_RT5640_SSP0_AIF1 | | ||
| 555 | BYT_RT5640_MCLK_EN), | ||
| 556 | }, | ||
| 527 | { | 557 | { |
| 528 | .matches = { | 558 | .matches = { |
| 529 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 559 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
| @@ -613,6 +643,15 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { · 83 unmodified lines | |||
| 613 | BYT_RT5640_SSP0_AIF1 | | 643 | BYT_RT5640_SSP0_AIF1 | |
| 614 | BYT_RT5640_MCLK_EN), | 644 | BYT_RT5640_MCLK_EN), |
| 615 | }, | 645 | }, |
| 646 | { /* Mele PCG03 Mini PC */ | ||
| 647 | .matches = { | ||
| 648 | DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"), | ||
| 649 | DMI_EXACT_MATCH(DMI_BOARD_NAME, "Mini PC"), | ||
| 650 | }, | ||
| 651 | .driver_data = (void *)(BYT_RT5640_NO_INTERNAL_MIC_MAP | | ||
| 652 | BYT_RT5640_NO_SPEAKERS | | ||
| 653 | BYT_RT5640_SSP0_AIF1), | ||
| 654 | }, | ||
| 616 | { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ | 655 | { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ |
| 617 | .matches = { | 656 | .matches = { |
| 618 | DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"), | 657 | DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"), |
| @@ -798,6 +837,20 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { · 179 unmodified lines | |||
| 798 | BYT_RT5640_SSP0_AIF2 | | 837 | BYT_RT5640_SSP0_AIF2 | |
| 799 | BYT_RT5640_MCLK_EN), | 838 | BYT_RT5640_MCLK_EN), |
| 800 | }, | 839 | }, |
| 840 | { /* Voyo Winpad A15 */ | ||
| 841 | .matches = { | ||
| 842 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | ||
| 843 | DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), | ||
| 844 | /* Above strings are too generic, also match on BIOS date */ | ||
| 845 | DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"), | ||
| 846 | }, | ||
| 847 | .driver_data = (void *)(BYT_RT5640_IN1_MAP | | ||
| 848 | BYT_RT5640_JD_SRC_JD2_IN4N | | ||
| 849 | BYT_RT5640_OVCD_TH_2000UA | | ||
| 850 | BYT_RT5640_OVCD_SF_0P75 | | ||
| 851 | BYT_RT5640_DIFF_MIC | | ||
| 852 | BYT_RT5640_MCLK_EN), | ||
| 853 | }, | ||
| 801 | { /* Catch-all for generic Insyde tablets, must be last */ | 854 | { /* Catch-all for generic Insyde tablets, must be last */ |
| 802 | .matches = { | 855 | .matches = { |
| 803 | DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), | 856 | DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), |
| @@ -873,8 +926,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) · 69 unmodified lines | |||
| 873 | struct snd_soc_card *card = runtime->card; | 926 | struct snd_soc_card *card = runtime->card; |
| 874 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); | 927 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); |
| 875 | struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; | 928 | struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; |
| 876 | const struct snd_soc_dapm_route *custom_map; | 929 | const struct snd_soc_dapm_route *custom_map = NULL; |
| 877 | int num_routes; | 930 | int num_routes = 0; |
| 878 | int ret; | 931 | int ret; |
| 879 | 932 | ||
| 880 | card->dapm.idle_bias_off = true; | 933 | card->dapm.idle_bias_off = true; |
| @@ -909,13 +962,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) · 28 unmodified lines | |||
| 909 | custom_map = byt_rt5640_intmic_in3_map; | 962 | custom_map = byt_rt5640_intmic_in3_map; |
| 910 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); | 963 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); |
| 911 | break; | 964 | break; |
| 965 | case BYT_RT5640_DMIC1_MAP: | ||
| 966 | custom_map = byt_rt5640_intmic_dmic1_map; | ||
| 967 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); | ||
| 968 | break; | ||
| 912 | case BYT_RT5640_DMIC2_MAP: | 969 | case BYT_RT5640_DMIC2_MAP: |
| 913 | custom_map = byt_rt5640_intmic_dmic2_map; | 970 | custom_map = byt_rt5640_intmic_dmic2_map; |
| 914 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); | 971 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); |
| 915 | break; | 972 | break; |
| 916 | default: | ||
| 917 | custom_map = byt_rt5640_intmic_dmic1_map; | ||
| 918 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); | ||
| 919 | } | 973 | } |
| 920 | 974 | ||
| 921 | ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); | 975 | ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); |
| @@ -946,7 +1000,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) · 24 unmodified lines | |||
| 946 | ret = snd_soc_dapm_add_routes(&card->dapm, | 1000 | ret = snd_soc_dapm_add_routes(&card->dapm, |
| 947 | byt_rt5640_mono_spk_map, | 1001 | byt_rt5640_mono_spk_map, |
| 948 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); | 1002 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); |
| 949 | } else { | 1003 | } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { |
| 950 | ret = snd_soc_dapm_add_routes(&card->dapm, | 1004 | ret = snd_soc_dapm_add_routes(&card->dapm, |
| 951 | byt_rt5640_stereo_spk_map, | 1005 | byt_rt5640_stereo_spk_map, |
| 952 | ARRAY_SIZE(byt_rt5640_stereo_spk_map)); | 1006 | ARRAY_SIZE(byt_rt5640_stereo_spk_map)); |
| @@ -1187,7 +1241,8 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ · 234 unmodified lines | |||
| 1187 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | 1241 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
| 1188 | { | 1242 | { |
| 1189 | struct device *dev = &pdev->dev; | 1243 | struct device *dev = &pdev->dev; |
| 1190 | static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; | 1244 | static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" }; |
| 1245 | __maybe_unused const char *spk_type; | ||
| 1191 | const struct dmi_system_id *dmi_id; | 1246 | const struct dmi_system_id *dmi_id; |
| 1192 | struct byt_rt5640_private *priv; | 1247 | struct byt_rt5640_private *priv; |
| 1193 | struct snd_soc_acpi_mach *mach; | 1248 | struct snd_soc_acpi_mach *mach; |
| @@ -1196,7 +1251,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 1196 | bool sof_parent; | 1251 | bool sof_parent; |
| 1197 | int ret_val = 0; | 1252 | int ret_val = 0; |
| 1198 | int dai_index = 0; | 1253 | int dai_index = 0; |
| 1199 | int i; | 1254 | int i, cfg_spk; |
| 1200 | 1255 | ||
| 1201 | is_bytcr = false; | 1256 | is_bytcr = false; |
| 1202 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 1257 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| @@ -1335,16 +1390,24 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) · 132 unmodified lines | |||
| 1335 | } | 1390 | } |
| 1336 | } | 1391 | } |
| 1337 | 1392 | ||
| 1393 | if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) { | ||
| 1394 | cfg_spk = 0; | ||
| 1395 | spk_type = "none"; | ||
| 1396 | } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { | ||
| 1397 | cfg_spk = 1; | ||
| 1398 | spk_type = "mono"; | ||
| 1399 | } else { | ||
| 1400 | cfg_spk = 2; | ||
| 1401 | spk_type = "stereo"; | ||
| 1402 | } | ||
| 1403 | |||
| 1338 | snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), | 1404 | snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), |
| 1339 | "cfg-spk:%s cfg-mic:%s", | 1405 | "cfg-spk:%d cfg-mic:%s", cfg_spk, |
| 1340 | (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? "1" : "2", | ||
| 1341 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); | 1406 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
| 1342 | byt_rt5640_card.components = byt_rt5640_components; | 1407 | byt_rt5640_card.components = byt_rt5640_components; |
| 1343 | #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) | 1408 | #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) |
| 1344 | snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), | 1409 | snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), |
| 1345 | "bytcr-rt5640-%s-spk-%s-mic", | 1410 | "bytcr-rt5640-%s-spk-%s-mic", spk_type, |
| 1346 | (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? | ||
| 1347 | "mono" : "stereo", | ||
| 1348 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); | 1411 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
| 1349 | byt_rt5640_card.long_name = byt_rt5640_long_name; | 1412 | byt_rt5640_card.long_name = byt_rt5640_long_name; |
| 1350 | #endif | 1413 | #endif |
| @@ -435,6 +435,19 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { · 434 unmodified lines | |||
| 435 | BYT_RT5651_SSP0_AIF1 | | 435 | BYT_RT5651_SSP0_AIF1 | |
| 436 | BYT_RT5651_MONO_SPEAKER), | 436 | BYT_RT5651_MONO_SPEAKER), |
| 437 | }, | 437 | }, |
| 438 | { | ||
| 439 | /* Jumper EZpad 7 */ | ||
| 440 | .callback = byt_rt5651_quirk_cb, | ||
| 441 | .matches = { | ||
| 442 | DMI_MATCH(DMI_SYS_VENDOR, "Jumper"), | ||
| 443 | DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"), | ||
| 444 | /* Jumper12x.WJ2012.bsBKRCP05 with the version dropped */ | ||
| 445 | DMI_MATCH(DMI_BIOS_VERSION, "Jumper12x.WJ2012.bsBKRCP"), | ||
| 446 | }, | ||
| 447 | .driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS | | ||
| 448 | BYT_RT5651_IN2_MAP | | ||
| 449 | BYT_RT5651_JD_NOT_INV), | ||
| 450 | }, | ||
| 438 | { | 451 | { |
| 439 | /* KIANO SlimNote 14.2 */ | 452 | /* KIANO SlimNote 14.2 */ |
| 440 | .callback = byt_rt5651_quirk_cb, | 453 | .callback = byt_rt5651_quirk_cb, |
| @@ -0,0 +1,465 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * bytcr_wm5102.c - ASoc Machine driver for Intel Baytrail platforms with a | ||
| 4 | * Wolfson Microelectronics WM5102 codec | ||
| 5 | * | ||
| 6 | * Copyright (C) 2020 Hans de Goede <hdegoede@redhat.com> | ||
| 7 | * Loosely based on bytcr_rt5640.c which is: | ||
| 8 | * Copyright (C) 2014-2020 Intel Corp | ||
| 9 | * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com> | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/acpi.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/moduleparam.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/spi/spi.h> | ||
| 21 | #include <sound/pcm.h> | ||
| 22 | #include <sound/pcm_params.h> | ||
| 23 | #include <sound/soc.h> | ||
| 24 | #include <sound/soc-acpi.h> | ||
| 25 | #include "../../codecs/wm5102.h" | ||
| 26 | #include "../atom/sst-atom-controls.h" | ||
| 27 | |||
| 28 | #define MCLK_FREQ 25000000 | ||
| 29 | |||
| 30 | #define WM5102_MAX_SYSCLK_4K 49152000 /* max sysclk for 4K family */ | ||
| 31 | #define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */ | ||
| 32 | |||
| 33 | struct byt_wm5102_private { | ||
| 34 | struct clk *mclk; | ||
| 35 | struct gpio_desc *spkvdd_en_gpio; | ||
| 36 | }; | ||
| 37 | |||
| 38 | static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, | ||
| 39 | struct snd_kcontrol *kcontrol, int event) | ||
| 40 | { | ||
| 41 | struct snd_soc_card *card = w->dapm->card; | ||
| 42 | struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); | ||
| 43 | |||
| 44 | gpiod_set_value_cansleep(priv->spkvdd_en_gpio, | ||
| 45 | !!SND_SOC_DAPM_EVENT_ON(event)); | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int rate) | ||
| 51 | { | ||
| 52 | struct snd_soc_component *codec_component = codec_dai->component; | ||
| 53 | int sr_mult = ((rate % 4000) == 0) ? | ||
| 54 | (WM5102_MAX_SYSCLK_4K / rate) : | ||
| 55 | (WM5102_MAX_SYSCLK_11025 / rate); | ||
| 56 | int ret; | ||
| 57 | |||
| 58 | /* Reset FLL1 */ | ||
| 59 | snd_soc_dai_set_pll(codec_dai, WM5102_FLL1_REFCLK, ARIZONA_FLL_SRC_NONE, 0, 0); | ||
| 60 | snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_FLL_SRC_NONE, 0, 0); | ||
| 61 | |||
| 62 | /* Configure the FLL1 PLL before selecting it */ | ||
| 63 | ret = snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_CLK_SRC_MCLK1, | ||
| 64 | MCLK_FREQ, rate * sr_mult); | ||
| 65 | if (ret) { | ||
| 66 | dev_err(codec_component->dev, "Error setting PLL: %d\n", ret); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | ret = snd_soc_component_set_sysclk(codec_component, ARIZONA_CLK_SYSCLK, | ||
| 71 | ARIZONA_CLK_SRC_FLL1, rate * sr_mult, | ||
| 72 | SND_SOC_CLOCK_IN); | ||
| 73 | if (ret) { | ||
| 74 | dev_err(codec_component->dev, "Error setting SYSCLK: %d\n", ret); | ||
| 75 | return ret; | ||
| 76 | } | ||
| 77 | |||
| 78 | ret = snd_soc_dai_set_sysclk(codec_dai, ARIZONA_CLK_SYSCLK, | ||
| 79 | rate * 512, SND_SOC_CLOCK_IN); | ||
| 80 | if (ret) { | ||
| 81 | dev_err(codec_component->dev, "Error setting clock: %d\n", ret); | ||
| 82 | return ret; | ||
| 83 | } | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int platform_clock_control(struct snd_soc_dapm_widget *w, | ||
| 89 | struct snd_kcontrol *k, int event) | ||
| 90 | { | ||
| 91 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
| 92 | struct snd_soc_card *card = dapm->card; | ||
| 93 | struct snd_soc_dai *codec_dai; | ||
| 94 | struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); | ||
| 95 | int ret; | ||
| 96 | |||
| 97 | codec_dai = snd_soc_card_get_codec_dai(card, "wm5102-aif1"); | ||
| 98 | if (!codec_dai) { | ||
| 99 | dev_err(card->dev, "Error codec DAI not found\n"); | ||
| 100 | return -EIO; | ||
| 101 | } | ||
| 102 | |||
| 103 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 104 | ret = clk_prepare_enable(priv->mclk); | ||
| 105 | if (ret) { | ||
| 106 | dev_err(card->dev, "Error enabling MCLK: %d\n", ret); | ||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | ret = byt_wm5102_prepare_and_enable_pll1(codec_dai, 48000); | ||
| 110 | if (ret) { | ||
| 111 | dev_err(card->dev, "Error setting codec sysclk: %d\n", ret); | ||
| 112 | return ret; | ||
| 113 | } | ||
| 114 | } else { | ||
| 115 | /* | ||
| 116 | * The WM5102 has a separate 32KHz clock for jack-detect | ||
| 117 | * so we can disable the PLL, followed by disabling the | ||
| 118 | * platform clock which is the source-clock for the PLL. | ||
| 119 | */ | ||
| 120 | snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_FLL_SRC_NONE, 0, 0); | ||
| 121 | clk_disable_unprepare(priv->mclk); | ||
| 122 | } | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static const struct snd_soc_dapm_widget byt_wm5102_widgets[] = { | ||
| 128 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
| 129 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
| 130 | SND_SOC_DAPM_MIC("Internal Mic", NULL), | ||
| 131 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
| 132 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | ||
| 133 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | ||
| 134 | SND_SOC_DAPM_POST_PMD), | ||
| 135 | SND_SOC_DAPM_SUPPLY("Speaker VDD", SND_SOC_NOPM, 0, 0, | ||
| 136 | byt_wm5102_spkvdd_power_event, | ||
| 137 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 138 | }; | ||
| 139 | |||
| 140 | static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { | ||
| 141 | {"Headphone", NULL, "Platform Clock"}, | ||
| 142 | {"Headset Mic", NULL, "Platform Clock"}, | ||
| 143 | {"Internal Mic", NULL, "Platform Clock"}, | ||
| 144 | {"Speaker", NULL, "Platform Clock"}, | ||
| 145 | |||
| 146 | {"Speaker", NULL, "SPKOUTLP"}, | ||
| 147 | {"Speaker", NULL, "SPKOUTLN"}, | ||
| 148 | {"Speaker", NULL, "SPKOUTRP"}, | ||
| 149 | {"Speaker", NULL, "SPKOUTRN"}, | ||
| 150 | {"Speaker", NULL, "Speaker VDD"}, | ||
| 151 | |||
| 152 | {"Headphone", NULL, "HPOUT1L"}, | ||
| 153 | {"Headphone", NULL, "HPOUT1R"}, | ||
| 154 | |||
| 155 | {"Internal Mic", NULL, "MICBIAS3"}, | ||
| 156 | {"IN3L", NULL, "Internal Mic"}, | ||
| 157 | |||
| 158 | /* | ||
| 159 | * The Headset Mix uses MICBIAS1 or 2 depending on if a CTIA/OMTP Headset | ||
| 160 | * is connected, as the MICBIAS is applied after the CTIA/OMTP cross-switch. | ||
| 161 | */ | ||
| 162 | {"Headset Mic", NULL, "MICBIAS1"}, | ||
| 163 | {"Headset Mic", NULL, "MICBIAS2"}, | ||
| 164 | {"IN1L", NULL, "Headset Mic"}, | ||
| 165 | |||
| 166 | {"AIF1 Playback", NULL, "ssp0 Tx"}, | ||
| 167 | {"ssp0 Tx", NULL, "modem_out"}, | ||
| 168 | |||
| 169 | {"modem_in", NULL, "ssp0 Rx"}, | ||
| 170 | {"ssp0 Rx", NULL, "AIF1 Capture"}, | ||
| 171 | }; | ||
| 172 | |||
| 173 | static const struct snd_kcontrol_new byt_wm5102_controls[] = { | ||
| 174 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
| 175 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
| 176 | SOC_DAPM_PIN_SWITCH("Internal Mic"), | ||
| 177 | SOC_DAPM_PIN_SWITCH("Speaker"), | ||
| 178 | }; | ||
| 179 | |||
| 180 | static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) | ||
| 181 | { | ||
| 182 | struct snd_soc_card *card = runtime->card; | ||
| 183 | struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); | ||
| 184 | int ret; | ||
| 185 | |||
| 186 | card->dapm.idle_bias_off = true; | ||
| 187 | |||
| 188 | ret = snd_soc_add_card_controls(card, byt_wm5102_controls, | ||
| 189 | ARRAY_SIZE(byt_wm5102_controls)); | ||
| 190 | if (ret) { | ||
| 191 | dev_err(card->dev, "Error adding card controls: %d\n", ret); | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * The firmware might enable the clock at boot (this information | ||
| 197 | * may or may not be reflected in the enable clock register). | ||
| 198 | * To change the rate we must disable the clock first to cover these | ||
| 199 | * cases. Due to common clock framework restrictions that do not allow | ||
| 200 | * to disable a clock that has not been enabled, we need to enable | ||
| 201 | * the clock first. | ||
| 202 | */ | ||
| 203 | ret = clk_prepare_enable(priv->mclk); | ||
| 204 | if (!ret) | ||
| 205 | clk_disable_unprepare(priv->mclk); | ||
| 206 | |||
| 207 | ret = clk_set_rate(priv->mclk, MCLK_FREQ); | ||
| 208 | if (ret) { | ||
| 209 | dev_err(card->dev, "Error setting MCLK rate: %d\n", ret); | ||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | |||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static const struct snd_soc_pcm_stream byt_wm5102_dai_params = { | ||
| 217 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 218 | .rate_min = 48000, | ||
| 219 | .rate_max = 48000, | ||
| 220 | .channels_min = 2, | ||
| 221 | .channels_max = 2, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, | ||
| 225 | struct snd_pcm_hw_params *params) | ||
| 226 | { | ||
| 227 | struct snd_interval *rate = hw_param_interval(params, | ||
| 228 | SNDRV_PCM_HW_PARAM_RATE); | ||
| 229 | struct snd_interval *channels = hw_param_interval(params, | ||
| 230 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
| 231 | int ret; | ||
| 232 | |||
| 233 | /* The DSP will covert the FE rate to 48k, stereo */ | ||
| 234 | rate->min = 48000; | ||
| 235 | rate->max = 48000; | ||
| 236 | channels->min = 2; | ||
| 237 | channels->max = 2; | ||
| 238 | |||
| 239 | /* set SSP0 to 16-bit */ | ||
| 240 | params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); | ||
| 241 | |||
| 242 | /* | ||
| 243 | * Default mode for SSP configuration is TDM 4 slot, override config | ||
| 244 | * with explicit setting to I2S 2ch 16-bit. The word length is set with | ||
| 245 | * dai_set_tdm_slot() since there is no other API exposed | ||
| 246 | */ | ||
| 247 | ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), | ||
| 248 | SND_SOC_DAIFMT_I2S | | ||
| 249 | SND_SOC_DAIFMT_NB_NF | | ||
| 250 | SND_SOC_DAIFMT_CBS_CFS); | ||
| 251 | if (ret) { | ||
| 252 | dev_err(rtd->dev, "Error setting format to I2S: %d\n", ret); | ||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); | ||
| 257 | if (ret) { | ||
| 258 | dev_err(rtd->dev, "Error setting I2S config: %d\n", ret); | ||
| 259 | return ret; | ||
| 260 | } | ||
| 261 | |||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | |||
| 265 | static int byt_wm5102_aif1_startup(struct snd_pcm_substream *substream) | ||
| 266 | { | ||
| 267 | return snd_pcm_hw_constraint_single(substream->runtime, | ||
| 268 | SNDRV_PCM_HW_PARAM_RATE, 48000); | ||
| 269 | } | ||
| 270 | |||
| 271 | static const struct snd_soc_ops byt_wm5102_aif1_ops = { | ||
| 272 | .startup = byt_wm5102_aif1_startup, | ||
| 273 | }; | ||
| 274 | |||
| 275 | SND_SOC_DAILINK_DEF(dummy, | ||
| 276 | DAILINK_COMP_ARRAY(COMP_DUMMY())); | ||
| 277 | |||
| 278 | SND_SOC_DAILINK_DEF(media, | ||
| 279 | DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai"))); | ||
| 280 | |||
| 281 | SND_SOC_DAILINK_DEF(deepbuffer, | ||
| 282 | DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai"))); | ||
| 283 | |||
| 284 | SND_SOC_DAILINK_DEF(ssp0_port, | ||
| 285 | DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); | ||
| 286 | |||
| 287 | SND_SOC_DAILINK_DEF(ssp0_codec, | ||
| 288 | DAILINK_COMP_ARRAY(COMP_CODEC( | ||
| 289 | /* | ||
| 290 | * Note there is no need to overwrite the codec-name as is done in | ||
| 291 | * other bytcr machine drivers, because the codec is a MFD child-dev. | ||
| 292 | */ | ||
| 293 | "wm5102-codec", | ||
| 294 | "wm5102-aif1"))); | ||
| 295 | |||
| 296 | SND_SOC_DAILINK_DEF(platform, | ||
| 297 | DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform"))); | ||
| 298 | |||
| 299 | static struct snd_soc_dai_link byt_wm5102_dais[] = { | ||
| 300 | [MERR_DPCM_AUDIO] = { | ||
| 301 | .name = "Baytrail Audio Port", | ||
| 302 | .stream_name = "Baytrail Audio", | ||
| 303 | .nonatomic = true, | ||
| 304 | .dynamic = 1, | ||
| 305 | .dpcm_playback = 1, | ||
| 306 | .dpcm_capture = 1, | ||
| 307 | .ops = &byt_wm5102_aif1_ops, | ||
| 308 | SND_SOC_DAILINK_REG(media, dummy, platform), | ||
| 309 | |||
| 310 | }, | ||
| 311 | [MERR_DPCM_DEEP_BUFFER] = { | ||
| 312 | .name = "Deep-Buffer Audio Port", | ||
| 313 | .stream_name = "Deep-Buffer Audio", | ||
| 314 | .nonatomic = true, | ||
| 315 | .dynamic = 1, | ||
| 316 | .dpcm_playback = 1, | ||
| 317 | .ops = &byt_wm5102_aif1_ops, | ||
| 318 | SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), | ||
| 319 | }, | ||
| 320 | /* back ends */ | ||
| 321 | { | ||
| 322 | /* | ||
| 323 | * This must be named SSP2-Codec even though this machine driver | ||
| 324 | * always uses SSP0. Most machine drivers support both and dynamically | ||
| 325 | * update the dailink to point to SSP0 or SSP2, while keeping the name | ||
| 326 | * as "SSP2-Codec". The SOF tplg files hardcode the "SSP2-Codec" even | ||
| 327 | * in the byt-foo-ssp0.tplg versions because the other machine-drivers | ||
| 328 | * use "SSP2-Codec" even when SSP0 is used. | ||
| 329 | */ | ||
| 330 | .name = "SSP2-Codec", | ||
| 331 | .id = 0, | ||
| 332 | .no_pcm = 1, | ||
| 333 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
| 334 | | SND_SOC_DAIFMT_CBS_CFS, | ||
| 335 | .be_hw_params_fixup = byt_wm5102_codec_fixup, | ||
| 336 | .nonatomic = true, | ||
| 337 | .dpcm_playback = 1, | ||
| 338 | .dpcm_capture = 1, | ||
| 339 | .init = byt_wm5102_init, | ||
| 340 | SND_SOC_DAILINK_REG(ssp0_port, ssp0_codec, platform), | ||
| 341 | }, | ||
| 342 | }; | ||
| 343 | |||
| 344 | /* use space before codec name to simplify card ID, and simplify driver name */ | ||
| 345 | #define SOF_CARD_NAME "bytcht wm5102" /* card name will be 'sof-bytcht wm5102' */ | ||
| 346 | #define SOF_DRIVER_NAME "SOF" | ||
| 347 | |||
| 348 | #define CARD_NAME "bytcr-wm5102" | ||
| 349 | #define DRIVER_NAME NULL /* card name will be used for driver name */ | ||
| 350 | |||
| 351 | /* SoC card */ | ||
| 352 | static struct snd_soc_card byt_wm5102_card = { | ||
| 353 | .owner = THIS_MODULE, | ||
| 354 | .dai_link = byt_wm5102_dais, | ||
| 355 | .num_links = ARRAY_SIZE(byt_wm5102_dais), | ||
| 356 | .dapm_widgets = byt_wm5102_widgets, | ||
| 357 | .num_dapm_widgets = ARRAY_SIZE(byt_wm5102_widgets), | ||
| 358 | .dapm_routes = byt_wm5102_audio_map, | ||
| 359 | .num_dapm_routes = ARRAY_SIZE(byt_wm5102_audio_map), | ||
| 360 | .fully_routed = true, | ||
| 361 | }; | ||
| 362 | |||
| 363 | static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) | ||
| 364 | { | ||
| 365 | char codec_name[SND_ACPI_I2C_ID_LEN]; | ||
| 366 | struct device *dev = &pdev->dev; | ||
| 367 | struct byt_wm5102_private *priv; | ||
| 368 | struct snd_soc_acpi_mach *mach; | ||
| 369 | const char *platform_name; | ||
| 370 | struct acpi_device *adev; | ||
| 371 | struct device *codec_dev; | ||
| 372 | bool sof_parent; | ||
| 373 | int ret; | ||
| 374 | |||
| 375 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_ATOMIC); | ||
| 376 | if (!priv) | ||
| 377 | return -ENOMEM; | ||
| 378 | |||
| 379 | /* Get MCLK */ | ||
| 380 | priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); | ||
| 381 | if (IS_ERR(priv->mclk)) | ||
| 382 | return dev_err_probe(dev, PTR_ERR(priv->mclk), "getting pmc_plt_clk_3\n"); | ||
| 383 | |||
| 384 | /* | ||
| 385 | * Get speaker VDD enable GPIO: | ||
| 386 | * 1. Get codec-device-name | ||
| 387 | * 2. Get codec-device | ||
| 388 | * 3. Get GPIO from codec-device | ||
| 389 | */ | ||
| 390 | mach = dev->platform_data; | ||
| 391 | adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); | ||
| 392 | if (!adev) { | ||
| 393 | dev_err(dev, "Error cannot find acpi-dev for codec\n"); | ||
| 394 | return -ENOENT; | ||
| 395 | } | ||
| 396 | snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); | ||
| 397 | put_device(&adev->dev); | ||
| 398 | |||
| 399 | codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); | ||
| 400 | if (!codec_dev) | ||
| 401 | return -EPROBE_DEFER; | ||
| 402 | |||
| 403 | /* Note no devm_ here since we call gpiod_get on codec_dev rather then dev */ | ||
| 404 | priv->spkvdd_en_gpio = gpiod_get(codec_dev, "wlf,spkvdd-ena", GPIOD_OUT_LOW); | ||
| 405 | put_device(codec_dev); | ||
| 406 | |||
| 407 | if (IS_ERR(priv->spkvdd_en_gpio)) | ||
| 408 | return dev_err_probe(dev, PTR_ERR(priv->spkvdd_en_gpio), "getting spkvdd-GPIO\n"); | ||
| 409 | |||
| 410 | /* override platform name, if required */ | ||
| 411 | byt_wm5102_card.dev = dev; | ||
| 412 | platform_name = mach->mach_params.platform; | ||
| 413 | ret = snd_soc_fixup_dai_links_platform_name(&byt_wm5102_card, platform_name); | ||
| 414 | if (ret) | ||
| 415 | goto out_put_gpio; | ||
| 416 | |||
| 417 | /* set card and driver name and pm-ops */ | ||
| 418 | sof_parent = snd_soc_acpi_sof_parent(dev); | ||
| 419 | if (sof_parent) { | ||
| 420 | byt_wm5102_card.name = SOF_CARD_NAME; | ||
| 421 | byt_wm5102_card.driver_name = SOF_DRIVER_NAME; | ||
| 422 | dev->driver->pm = &snd_soc_pm_ops; | ||
| 423 | } else { | ||
| 424 | byt_wm5102_card.name = CARD_NAME; | ||
| 425 | byt_wm5102_card.driver_name = DRIVER_NAME; | ||
| 426 | } | ||
| 427 | |||
| 428 | snd_soc_card_set_drvdata(&byt_wm5102_card, priv); | ||
| 429 | ret = devm_snd_soc_register_card(dev, &byt_wm5102_card); | ||
| 430 | if (ret) { | ||
| 431 | dev_err_probe(dev, ret, "registering card\n"); | ||
| 432 | goto out_put_gpio; | ||
| 433 | } | ||
| 434 | |||
| 435 | platform_set_drvdata(pdev, &byt_wm5102_card); | ||
| 436 | return 0; | ||
| 437 | |||
| 438 | out_put_gpio: | ||
| 439 | gpiod_put(priv->spkvdd_en_gpio); | ||
| 440 | return ret; | ||
| 441 | } | ||
| 442 | |||
| 443 | static int snd_byt_wm5102_mc_remove(struct platform_device *pdev) | ||
| 444 | { | ||
| 445 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 446 | struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); | ||
| 447 | |||
| 448 | gpiod_put(priv->spkvdd_en_gpio); | ||
| 449 | return 0; | ||
| 450 | } | ||
| 451 | |||
| 452 | static struct platform_driver snd_byt_wm5102_mc_driver = { | ||
| 453 | .driver = { | ||
| 454 | .name = "bytcr_wm5102", | ||
| 455 | }, | ||
| 456 | .probe = snd_byt_wm5102_mc_probe, | ||
| 457 | .remove = snd_byt_wm5102_mc_remove, | ||
| 458 | }; | ||
| 459 | |||
| 460 | module_platform_driver(snd_byt_wm5102_mc_driver); | ||
| 461 | |||
| 462 | MODULE_DESCRIPTION("ASoC Baytrail with WM5102 codec machine driver"); | ||
| 463 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
| 464 | MODULE_LICENSE("GPL v2"); | ||
| 465 | MODULE_ALIAS("platform:bytcr_wm5102"); | ||
| @@ -100,13 +100,6 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) · 99 unmodified lines | |||
| 100 | struct snd_soc_component *component = codec_dai->component; | 100 | struct snd_soc_component *component = codec_dai->component; |
| 101 | int ret, jack_type; | 101 | int ret, jack_type; |
| 102 | 102 | ||
| 103 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ | ||
| 104 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xf, 0x1, 4, 24); | ||
| 105 | if (ret < 0) { | ||
| 106 | dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret); | ||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* NAU88L24 supports 4 butons headset detection | 103 | /* NAU88L24 supports 4 butons headset detection |
| 111 | * KEY_PLAYPAUSE | 104 | * KEY_PLAYPAUSE |
| 112 | * KEY_VOICECOMMAND | 105 | * KEY_VOICECOMMAND |
| @@ -141,6 +134,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, · 28 unmodified lines | |||
| 141 | SNDRV_PCM_HW_PARAM_CHANNELS); | 134 | SNDRV_PCM_HW_PARAM_CHANNELS); |
| 142 | struct snd_mask *fmt = | 135 | struct snd_mask *fmt = |
| 143 | hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 136 | hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
| 137 | int ret; | ||
| 144 | 138 | ||
| 145 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ | 139 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ |
| 146 | rate->min = rate->max = 48000; | 140 | rate->min = rate->max = 48000; |
| @@ -150,6 +144,13 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, · 3 unmodified lines | |||
| 150 | snd_mask_none(fmt); | 144 | snd_mask_none(fmt); |
| 151 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); | 145 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); |
| 152 | 146 | ||
| 147 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ | ||
| 148 | ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); | ||
| 149 | if (ret < 0) { | ||
| 150 | dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); | ||
| 151 | return ret; | ||
| 152 | } | ||
| 153 | |||
| 153 | return 0; | 154 | return 0; |
| 154 | } | 155 | } |
| 155 | 156 | ||
| @@ -63,6 +63,7 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) · 62 unmodified lines | |||
| 63 | { | 63 | { |
| 64 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 64 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 65 | struct snd_soc_dai *codec_dai; | 65 | struct snd_soc_dai *codec_dai; |
| 66 | struct snd_soc_dai *cpu_dai; | ||
| 66 | int j; | 67 | int j; |
| 67 | int ret = 0; | 68 | int ret = 0; |
| 68 | 69 | ||
| @@ -70,10 +71,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) · 1 unmodified line | |||
| 70 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 71 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
| 71 | return 0; | 72 | return 0; |
| 72 | 73 | ||
| 74 | cpu_dai = asoc_rtd_to_cpu(rtd, 0); | ||
| 73 | for_each_rtd_codec_dais(rtd, j, codec_dai) { | 75 | for_each_rtd_codec_dais(rtd, j, codec_dai) { |
| 74 | struct snd_soc_component *component = codec_dai->component; | ||
| 75 | struct snd_soc_dapm_context *dapm = | 76 | struct snd_soc_dapm_context *dapm = |
| 76 | snd_soc_component_get_dapm(component); | 77 | snd_soc_component_get_dapm(cpu_dai->component); |
| 77 | char pin_name[MAX_98373_PIN_NAME]; | 78 | char pin_name[MAX_98373_PIN_NAME]; |
| 78 | 79 | ||
| 79 | snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", | 80 | snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", |
| @@ -323,13 +323,6 @@ static int sof_rt1015_hw_params(struct snd_pcm_substream *substream, · 322 unmodified lines | |||
| 323 | fs = 64; | 323 | fs = 64; |
| 324 | 324 | ||
| 325 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 325 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 326 | /* Set tdm/i2s1 master bclk ratio */ | ||
| 327 | ret = snd_soc_dai_set_bclk_ratio(codec_dai, fs); | ||
| 328 | if (ret < 0) { | ||
| 329 | dev_err(card->dev, "failed to set bclk ratio\n"); | ||
| 330 | return ret; | ||
| 331 | } | ||
| 332 | |||
| 333 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, | 326 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 334 | params_rate(params) * fs, | 327 | params_rate(params) * fs, |
| 335 | params_rate(params) * 256); | 328 | params_rate(params) * 256); |
| @@ -48,34 +48,14 @@ static int sof_sdw_quirk_cb(const struct dmi_system_id *id) · 47 unmodified lines | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static const struct dmi_system_id sof_sdw_quirk_table[] = { | 50 | static const struct dmi_system_id sof_sdw_quirk_table[] = { |
| 51 | /* CometLake devices */ | ||
| 51 | { | 52 | { |
| 52 | .callback = sof_sdw_quirk_cb, | 53 | .callback = sof_sdw_quirk_cb, |
| 53 | .matches = { | 54 | .matches = { |
| 54 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | 55 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), |
| 55 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") | 56 | DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), |
| 56 | }, | ||
| 57 | .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | | ||
| 58 | SOF_RT715_DAI_ID_FIX | | ||
| 59 | SOF_SDW_FOUR_SPK), | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | .callback = sof_sdw_quirk_cb, | ||
| 63 | .matches = { | ||
| 64 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | ||
| 65 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") | ||
| 66 | }, | ||
| 67 | .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | | ||
| 68 | SOF_RT715_DAI_ID_FIX), | ||
| 69 | }, | ||
| 70 | { | ||
| 71 | .callback = sof_sdw_quirk_cb, | ||
| 72 | .matches = { | ||
| 73 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | ||
| 74 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") | ||
| 75 | }, | 57 | }, |
| 76 | .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | | 58 | .driver_data = (void *)SOF_SDW_PCH_DMIC, |
| 77 | SOF_RT715_DAI_ID_FIX | | ||
| 78 | SOF_SDW_FOUR_SPK), | ||
| 79 | }, | 59 | }, |
| 80 | { | 60 | { |
| 81 | .callback = sof_sdw_quirk_cb, | 61 | .callback = sof_sdw_quirk_cb, |
| @@ -106,7 +86,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 24 unmodified lines | |||
| 106 | SOF_RT715_DAI_ID_FIX | | 86 | SOF_RT715_DAI_ID_FIX | |
| 107 | SOF_SDW_FOUR_SPK), | 87 | SOF_SDW_FOUR_SPK), |
| 108 | }, | 88 | }, |
| 109 | { | 89 | { |
| 110 | .callback = sof_sdw_quirk_cb, | 90 | .callback = sof_sdw_quirk_cb, |
| 111 | .matches = { | 91 | .matches = { |
| 112 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | 92 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), |
| @@ -116,6 +96,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 3 unmodified lines | |||
| 116 | SOF_RT715_DAI_ID_FIX | | 96 | SOF_RT715_DAI_ID_FIX | |
| 117 | SOF_SDW_FOUR_SPK), | 97 | SOF_SDW_FOUR_SPK), |
| 118 | }, | 98 | }, |
| 99 | /* IceLake devices */ | ||
| 100 | { | ||
| 101 | .callback = sof_sdw_quirk_cb, | ||
| 102 | .matches = { | ||
| 103 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | ||
| 104 | DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), | ||
| 105 | }, | ||
| 106 | .driver_data = (void *)SOF_SDW_PCH_DMIC, | ||
| 107 | }, | ||
| 108 | /* TigerLake devices */ | ||
| 119 | { | 109 | { |
| 120 | .callback = sof_sdw_quirk_cb, | 110 | .callback = sof_sdw_quirk_cb, |
| 121 | .matches = { | 111 | .matches = { |
| @@ -123,25 +113,31 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 1 unmodified line | |||
| 123 | DMI_MATCH(DMI_PRODUCT_NAME, | 113 | DMI_MATCH(DMI_PRODUCT_NAME, |
| 124 | "Tiger Lake Client Platform"), | 114 | "Tiger Lake Client Platform"), |
| 125 | }, | 115 | }, |
| 126 | .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 | | 116 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
| 127 | SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | | 117 | SOF_RT711_JD_SRC_JD1 | |
| 128 | SOF_SSP_PORT(SOF_I2S_SSP2)), | 118 | SOF_SDW_PCH_DMIC | |
| 119 | SOF_SSP_PORT(SOF_I2S_SSP2)), | ||
| 129 | }, | 120 | }, |
| 130 | { | 121 | { |
| 131 | .callback = sof_sdw_quirk_cb, | 122 | .callback = sof_sdw_quirk_cb, |
| 132 | .matches = { | 123 | .matches = { |
| 133 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | 124 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), |
| 134 | DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), | 125 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") |
| 135 | }, | 126 | }, |
| 136 | .driver_data = (void *)SOF_SDW_PCH_DMIC, | 127 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
| 128 | SOF_RT711_JD_SRC_JD2 | | ||
| 129 | SOF_RT715_DAI_ID_FIX), | ||
| 137 | }, | 130 | }, |
| 138 | { | 131 | { |
| 139 | .callback = sof_sdw_quirk_cb, | 132 | .callback = sof_sdw_quirk_cb, |
| 140 | .matches = { | 133 | .matches = { |
| 141 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | 134 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), |
| 142 | DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), | 135 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") |
| 143 | }, | 136 | }, |
| 144 | .driver_data = (void *)SOF_SDW_PCH_DMIC, | 137 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
| 138 | SOF_RT711_JD_SRC_JD2 | | ||
| 139 | SOF_RT715_DAI_ID_FIX | | ||
| 140 | SOF_SDW_FOUR_SPK), | ||
| 145 | }, | 141 | }, |
| 146 | { | 142 | { |
| 147 | .callback = sof_sdw_quirk_cb, | 143 | .callback = sof_sdw_quirk_cb, |
| @@ -149,7 +145,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 1 unmodified line | |||
| 149 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | 145 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
| 150 | DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), | 146 | DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), |
| 151 | }, | 147 | }, |
| 152 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | | 148 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
| 149 | SOF_SDW_PCH_DMIC | | ||
| 153 | SOF_SDW_FOUR_SPK), | 150 | SOF_SDW_FOUR_SPK), |
| 154 | }, | 151 | }, |
| 155 | { | 152 | { |
| @@ -158,10 +155,38 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 2 unmodified lines | |||
| 158 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | 155 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
| 159 | DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), | 156 | DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), |
| 160 | }, | 157 | }, |
| 161 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | | 158 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
| 159 | SOF_SDW_PCH_DMIC | | ||
| 160 | SOF_SDW_FOUR_SPK), | ||
| 161 | }, | ||
| 162 | { | ||
| 163 | /* | ||
| 164 | * this entry covers multiple HP SKUs. The family name | ||
| 165 | * does not seem robust enough, so we use a partial | ||
| 166 | * match that ignores the product name suffix | ||
| 167 | * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) | ||
| 168 | */ | ||
| 169 | .callback = sof_sdw_quirk_cb, | ||
| 170 | .matches = { | ||
| 171 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | ||
| 172 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), | ||
| 173 | }, | ||
| 174 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | | ||
| 175 | SOF_SDW_PCH_DMIC | | ||
| 176 | SOF_RT711_JD_SRC_JD2), | ||
| 177 | }, | ||
| 178 | /* TigerLake-SDCA devices */ | ||
| 179 | { | ||
| 180 | .callback = sof_sdw_quirk_cb, | ||
| 181 | .matches = { | ||
| 182 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | ||
| 183 | DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") | ||
| 184 | }, | ||
| 185 | .driver_data = (void *)(SOF_SDW_TGL_HDMI | | ||
| 186 | SOF_RT711_JD_SRC_JD2 | | ||
| 187 | SOF_RT715_DAI_ID_FIX | | ||
| 162 | SOF_SDW_FOUR_SPK), | 188 | SOF_SDW_FOUR_SPK), |
| 163 | }, | 189 | }, |
| 164 | |||
| 165 | {} | 190 | {} |
| 166 | }; | 191 | }; |
| 167 | 192 | ||
| @@ -451,15 +476,14 @@ static int get_sdw_dailink_info(const struct snd_soc_acpi_link_adr *links, · 283 unmodified lines | |||
| 451 | return 0; | 476 | return 0; |
| 452 | } | 477 | } |
| 453 | 478 | ||
| 454 | static void init_dai_link(struct snd_soc_dai_link *dai_links, int be_id, | 479 | static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, |
| 455 | char *name, int playback, int capture, | 480 | int be_id, char *name, int playback, int capture, |
| 456 | struct snd_soc_dai_link_component *cpus, | 481 | struct snd_soc_dai_link_component *cpus, int cpus_num, |
| 457 | int cpus_num, | 482 | struct snd_soc_dai_link_component *codecs, int codecs_num, |
| 458 | struct snd_soc_dai_link_component *codecs, | ||
| 459 | int codecs_num, | ||
| 460 | int (*init)(struct snd_soc_pcm_runtime *rtd), | 483 | int (*init)(struct snd_soc_pcm_runtime *rtd), |
| 461 | const struct snd_soc_ops *ops) | 484 | const struct snd_soc_ops *ops) |
| 462 | { | 485 | { |
| 486 | dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); | ||
| 463 | dai_links->id = be_id; | 487 | dai_links->id = be_id; |
| 464 | dai_links->name = name; | 488 | dai_links->name = name; |
| 465 | dai_links->platforms = platform_component; | 489 | dai_links->platforms = platform_component; |
| @@ -797,7 +821,7 @@ static int create_sdw_dailink(struct device *dev, int *be_index, · 331 unmodified lines | |||
| 797 | 821 | ||
| 798 | playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); | 822 | playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); |
| 799 | capture = (stream == SNDRV_PCM_STREAM_CAPTURE); | 823 | capture = (stream == SNDRV_PCM_STREAM_CAPTURE); |
| 800 | init_dai_link(dai_links + *be_index, *be_index, name, | 824 | init_dai_link(dev, dai_links + *be_index, *be_index, name, |
| 801 | playback, capture, | 825 | playback, capture, |
| 802 | cpus + *cpu_id, cpu_dai_num, | 826 | cpus + *cpu_id, cpu_dai_num, |
| 803 | codecs, codec_num, | 827 | codecs, codec_num, |
| @@ -930,7 +954,7 @@ static int sof_card_dai_links_create(struct device *dev, · 126 unmodified lines | |||
| 930 | ctx->idisp_codec = true; | 954 | ctx->idisp_codec = true; |
| 931 | 955 | ||
| 932 | /* enable dmic01 & dmic16k */ | 956 | /* enable dmic01 & dmic16k */ |
| 933 | dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0; | 957 | dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0; |
| 934 | comp_num += dmic_num; | 958 | comp_num += dmic_num; |
| 935 | 959 | ||
| 936 | dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, | 960 | dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, |
| @@ -1036,7 +1060,7 @@ SSP: · 99 unmodified lines | |||
| 1036 | 1060 | ||
| 1037 | playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; | 1061 | playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; |
| 1038 | capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; | 1062 | capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; |
| 1039 | init_dai_link(links + link_id, be_id, name, | 1063 | init_dai_link(dev, links + link_id, be_id, name, |
| 1040 | playback, capture, | 1064 | playback, capture, |
| 1041 | cpus + cpu_id, 1, | 1065 | cpus + cpu_id, 1, |
| 1042 | ssp_components, 1, | 1066 | ssp_components, 1, |
| @@ -1053,7 +1077,7 @@ DMIC: · 10 unmodified lines | |||
| 1053 | /* dmic */ | 1077 | /* dmic */ |
| 1054 | if (dmic_num > 0) { | 1078 | if (dmic_num > 0) { |
| 1055 | cpus[cpu_id].dai_name = "DMIC01 Pin"; | 1079 | cpus[cpu_id].dai_name = "DMIC01 Pin"; |
| 1056 | init_dai_link(links + link_id, be_id, "dmic01", | 1080 | init_dai_link(dev, links + link_id, be_id, "dmic01", |
| 1057 | 0, 1, // DMIC only supports capture | 1081 | 0, 1, // DMIC only supports capture |
| 1058 | cpus + cpu_id, 1, | 1082 | cpus + cpu_id, 1, |
| 1059 | dmic_component, 1, | 1083 | dmic_component, 1, |
| @@ -1061,7 +1085,7 @@ DMIC: · 1 unmodified line | |||
| 1061 | INC_ID(be_id, cpu_id, link_id); | 1085 | INC_ID(be_id, cpu_id, link_id); |
| 1062 | 1086 | ||
| 1063 | cpus[cpu_id].dai_name = "DMIC16k Pin"; | 1087 | cpus[cpu_id].dai_name = "DMIC16k Pin"; |
| 1064 | init_dai_link(links + link_id, be_id, "dmic16k", | 1088 | init_dai_link(dev, links + link_id, be_id, "dmic16k", |
| 1065 | 0, 1, // DMIC only supports capture | 1089 | 0, 1, // DMIC only supports capture |
| 1066 | cpus + cpu_id, 1, | 1090 | cpus + cpu_id, 1, |
| 1067 | dmic_component, 1, | 1091 | dmic_component, 1, |
| @@ -1104,7 +1128,7 @@ DMIC: · 36 unmodified lines | |||
| 1104 | return -ENOMEM; | 1128 | return -ENOMEM; |
| 1105 | 1129 | ||
| 1106 | cpus[cpu_id].dai_name = cpu_name; | 1130 | cpus[cpu_id].dai_name = cpu_name; |
| 1107 | init_dai_link(links + link_id, be_id, name, | 1131 | init_dai_link(dev, links + link_id, be_id, name, |
| 1108 | 1, 0, // HDMI only supports playback | 1132 | 1, 0, // HDMI only supports playback |
| 1109 | cpus + cpu_id, 1, | 1133 | cpus + cpu_id, 1, |
| 1110 | idisp_components + i, 1, | 1134 | idisp_components + i, 1, |
| @@ -1197,6 +1221,15 @@ static int mc_probe(struct platform_device *pdev) · 86 unmodified lines | |||
| 1197 | if (!card->components) | 1221 | if (!card->components) |
| 1198 | return -ENOMEM; | 1222 | return -ENOMEM; |
| 1199 | 1223 | ||
| 1224 | if (mach->mach_params.dmic_num) { | ||
| 1225 | card->components = devm_kasprintf(card->dev, GFP_KERNEL, | ||
| 1226 | "%s mic:dmic cfg-mics:%d", | ||
| 1227 | card->components, | ||
| 1228 | mach->mach_params.dmic_num); | ||
| 1229 | if (!card->components) | ||
| 1230 | return -ENOMEM; | ||
| 1231 | } | ||
| 1232 | |||
| 1200 | card->long_name = sdw_card_long_name; | 1233 | card->long_name = sdw_card_long_name; |
| 1201 | 1234 | ||
| 1202 | /* Register the card */ | 1235 | /* Register the card */ |
| @@ -331,7 +331,7 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, · 330 unmodified lines | |||
| 331 | { | 331 | { |
| 332 | struct catpt_dev *cdev = dev_get_drvdata(dai->dev); | 332 | struct catpt_dev *cdev = dev_get_drvdata(dai->dev); |
| 333 | struct snd_soc_component *component = dai->component; | 333 | struct snd_soc_component *component = dai->component; |
| 334 | struct snd_kcontrol *pos, *kctl = NULL; | 334 | struct snd_kcontrol *pos; |
| 335 | const char *name; | 335 | const char *name; |
| 336 | int ret; | 336 | int ret; |
| 337 | u32 id = stream->info.stream_hw_id; | 337 | u32 id = stream->info.stream_hw_id; |
| @@ -352,21 +352,19 @@ static int catpt_dai_apply_usettings(struct snd_soc_dai *dai, · 14 unmodified lines | |||
| 352 | break; | 352 | break; |
| 353 | default: | 353 | default: |
| 354 | return 0; | 354 | return 0; |
| 355 | }; | 355 | } |
| 356 | 356 | ||
| 357 | list_for_each_entry(pos, &component->card->snd_card->controls, list) { | 357 | list_for_each_entry(pos, &component->card->snd_card->controls, list) { |
| 358 | if (pos->private_data == component && | 358 | if (pos->private_data == component && |
| 359 | !strncmp(name, pos->id.name, sizeof(pos->id.name))) { | 359 | !strncmp(name, pos->id.name, sizeof(pos->id.name))) |
| 360 | kctl = pos; | ||
| 361 | break; | 360 | break; |
| 362 | } | ||
| 363 | } | 361 | } |
| 364 | if (!kctl) | 362 | if (list_entry_is_head(pos, &component->card->snd_card->controls, list)) |
| 365 | return -ENOENT; | 363 | return -ENOENT; |
| 366 | 364 | ||
| 367 | if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) | 365 | if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) |
| 368 | return catpt_set_dspvol(cdev, id, (long *)kctl->private_value); | 366 | return catpt_set_dspvol(cdev, id, (long *)pos->private_value); |
| 369 | ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value); | 367 | ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)pos->private_value); |
| 370 | if (ret) | 368 | if (ret) |
| 371 | return CATPT_IPC_ERROR(ret); | 369 | return CATPT_IPC_ERROR(ret); |
| 372 | return 0; | 370 | return 0; |
| @@ -44,7 +44,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { · 43 unmodified lines | |||
| 44 | .link_mask = 0x1, /* link0 required */ | 44 | .link_mask = 0x1, /* link0 required */ |
| 45 | .links = adl_rvp, | 45 | .links = adl_rvp, |
| 46 | .drv_name = "sof_sdw", | 46 | .drv_name = "sof_sdw", |
| 47 | .sof_fw_filename = "sof-adl.ri", | ||
| 48 | .sof_tplg_filename = "sof-adl-rt711.tplg", | 47 | .sof_tplg_filename = "sof-adl-rt711.tplg", |
| 49 | }, | 48 | }, |
| 50 | {}, | 49 | {}, |
| @@ -85,6 +85,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[] = { · 84 unmodified lines | |||
| 85 | {}, | 85 | {}, |
| 86 | }; | 86 | }; |
| 87 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_bxt_machines); | 87 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_bxt_machines); |
| 88 | |||
| 89 | MODULE_LICENSE("GPL v2"); | ||
| 90 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -154,6 +154,22 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = { · 153 unmodified lines | |||
| 154 | .sof_fw_filename = "sof-byt.ri", | 154 | .sof_fw_filename = "sof-byt.ri", |
| 155 | .sof_tplg_filename = "sof-byt-rt5651.tplg", | 155 | .sof_tplg_filename = "sof-byt-rt5651.tplg", |
| 156 | }, | 156 | }, |
| 157 | { | ||
| 158 | .id = "WM510204", | ||
| 159 | .drv_name = "bytcr_wm5102", | ||
| 160 | .fw_filename = "intel/fw_sst_0f28.bin", | ||
| 161 | .board = "bytcr_wm5102", | ||
| 162 | .sof_fw_filename = "sof-byt.ri", | ||
| 163 | .sof_tplg_filename = "sof-byt-wm5102.tplg", | ||
| 164 | }, | ||
| 165 | { | ||
| 166 | .id = "WM510205", | ||
| 167 | .drv_name = "bytcr_wm5102", | ||
| 168 | .fw_filename = "intel/fw_sst_0f28.bin", | ||
| 169 | .board = "bytcr_wm5102", | ||
| 170 | .sof_fw_filename = "sof-byt.ri", | ||
| 171 | .sof_tplg_filename = "sof-byt-wm5102.tplg", | ||
| 172 | }, | ||
| 157 | { | 173 | { |
| 158 | .id = "DLGS7212", | 174 | .id = "DLGS7212", |
| 159 | .drv_name = "bytcht_da7213", | 175 | .drv_name = "bytcht_da7213", |
| @@ -233,6 +249,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = { · 73 unmodified lines | |||
| 233 | {}, | 249 | {}, |
| 234 | }; | 250 | }; |
| 235 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_machines); | 251 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_machines); |
| 236 | |||
| 237 | MODULE_LICENSE("GPL v2"); | ||
| 238 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -18,6 +18,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[] = { · 17 unmodified lines | |||
| 18 | {} | 18 | {} |
| 19 | }; | 19 | }; |
| 20 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cfl_sdw_machines); | 20 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cfl_sdw_machines); |
| 21 | |||
| 22 | MODULE_LICENSE("GPL v2"); | ||
| 23 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -196,6 +196,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { · 195 unmodified lines | |||
| 196 | {}, | 196 | {}, |
| 197 | }; | 197 | }; |
| 198 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cherrytrail_machines); | 198 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cherrytrail_machines); |
| 199 | |||
| 200 | MODULE_LICENSE("GPL v2"); | ||
| 201 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -309,6 +309,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = { · 308 unmodified lines | |||
| 309 | {} | 309 | {} |
| 310 | }; | 310 | }; |
| 311 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_sdw_machines); | 311 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_sdw_machines); |
| 312 | |||
| 313 | MODULE_LICENSE("GPL v2"); | ||
| 314 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -63,6 +63,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[] = { · 62 unmodified lines | |||
| 63 | {} | 63 | {} |
| 64 | }; | 64 | }; |
| 65 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines); | 65 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines); |
| 66 | |||
| 67 | MODULE_LICENSE("GPL v2"); | ||
| 68 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * soc-apci-intel-ehl-match.c - tables and support for EHL ACPI enumeration. | 3 | * soc-acpi-intel-ehl-match.c - tables and support for EHL ACPI enumeration. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2019, Intel Corporation. | 5 | * Copyright (c) 2019, Intel Corporation. |
| 6 | * | 6 | * |
| @@ -20,6 +20,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = { · 13 unmodified lines | |||
| 20 | {}, | 20 | {}, |
| 21 | }; | 21 | }; |
| 22 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines); | 22 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ehl_machines); |
| 23 | |||
| 24 | MODULE_LICENSE("GPL v2"); | ||
| 25 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -43,6 +43,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { · 42 unmodified lines | |||
| 43 | {}, | 43 | {}, |
| 44 | }; | 44 | }; |
| 45 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_glk_machines); | 45 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_glk_machines); |
| 46 | |||
| 47 | MODULE_LICENSE("GPL v2"); | ||
| 48 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -53,6 +53,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = { · 52 unmodified lines | |||
| 53 | {} | 53 | {} |
| 54 | }; | 54 | }; |
| 55 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_broadwell_machines); | 55 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_broadwell_machines); |
| 56 | |||
| 57 | MODULE_LICENSE("GPL v2"); | ||
| 58 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -185,6 +185,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[] = { · 184 unmodified lines | |||
| 185 | {}, | 185 | {}, |
| 186 | }; | 186 | }; |
| 187 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_sdw_machines); | 187 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_sdw_machines); |
| 188 | |||
| 189 | MODULE_LICENSE("GPL v2"); | ||
| 190 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -63,6 +63,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { · 62 unmodified lines | |||
| 63 | {}, | 63 | {}, |
| 64 | }; | 64 | }; |
| 65 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines); | 65 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines); |
| 66 | |||
| 67 | MODULE_LICENSE("GPL v2"); | ||
| 68 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -128,6 +128,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { · 127 unmodified lines | |||
| 128 | {}, | 128 | {}, |
| 129 | }; | 129 | }; |
| 130 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_kbl_machines); | 130 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_kbl_machines); |
| 131 | |||
| 132 | MODULE_LICENSE("GPL v2"); | ||
| 133 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -42,6 +42,3 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = { · 41 unmodified lines | |||
| 42 | {}, | 42 | {}, |
| 43 | }; | 43 | }; |
| 44 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_skl_machines); | 44 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_skl_machines); |
| 45 | |||
| 46 | MODULE_LICENSE("GPL v2"); | ||
| 47 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * soc-apci-intel-tgl-match.c - tables and support for ICL ACPI enumeration. | 3 | * soc-acpi-intel-tgl-match.c - tables and support for TGL ACPI enumeration. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2019, Intel Corporation. | 5 | * Copyright (c) 2019, Intel Corporation. |
| 6 | * | 6 | * |
| @@ -205,6 +205,20 @@ static const struct snd_soc_acpi_link_adr tgl_rvp[] = { · 198 unmodified lines | |||
| 205 | {} | 205 | {} |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | static const struct snd_soc_acpi_link_adr tgl_hp[] = { | ||
| 209 | { | ||
| 210 | .mask = BIT(0), | ||
| 211 | .num_adr = ARRAY_SIZE(rt711_0_adr), | ||
| 212 | .adr_d = rt711_0_adr, | ||
| 213 | }, | ||
| 214 | { | ||
| 215 | .mask = BIT(1), | ||
| 216 | .num_adr = ARRAY_SIZE(rt1308_1_single_adr), | ||
| 217 | .adr_d = rt1308_1_single_adr, | ||
| 218 | }, | ||
| 219 | {} | ||
| 220 | }; | ||
| 221 | |||
| 208 | static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { | 222 | static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { |
| 209 | { | 223 | { |
| 210 | .mask = BIT(0), | 224 | .mask = BIT(0), |
| @@ -358,14 +372,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { · 147 unmodified lines | |||
| 358 | .link_mask = 0x7, | 372 | .link_mask = 0x7, |
| 359 | .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, | 373 | .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, |
| 360 | .drv_name = "sof_sdw", | 374 | .drv_name = "sof_sdw", |
| 361 | .sof_fw_filename = "sof-tgl.ri", | ||
| 362 | .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", | 375 | .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", |
| 363 | }, | 376 | }, |
| 364 | { | 377 | { |
| 365 | .link_mask = 0xF, /* 4 active links required */ | 378 | .link_mask = 0xF, /* 4 active links required */ |
| 366 | .links = tgl_3_in_1_default, | 379 | .links = tgl_3_in_1_default, |
| 367 | .drv_name = "sof_sdw", | 380 | .drv_name = "sof_sdw", |
| 368 | .sof_fw_filename = "sof-tgl.ri", | ||
| 369 | .sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg", | 381 | .sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg", |
| 370 | }, | 382 | }, |
| 371 | { | 383 | { |
| @@ -377,40 +389,38 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { · 5 unmodified lines | |||
| 377 | .link_mask = 0xF, | 389 | .link_mask = 0xF, |
| 378 | .links = tgl_3_in_1_mono_amp, | 390 | .links = tgl_3_in_1_mono_amp, |
| 379 | .drv_name = "sof_sdw", | 391 | .drv_name = "sof_sdw", |
| 380 | .sof_fw_filename = "sof-tgl.ri", | ||
| 381 | .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", | 392 | .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", |
| 382 | }, | 393 | }, |
| 383 | { | 394 | { |
| 384 | .link_mask = 0xF, /* 4 active links required */ | 395 | .link_mask = 0xF, /* 4 active links required */ |
| 385 | .links = tgl_3_in_1_sdca, | 396 | .links = tgl_3_in_1_sdca, |
| 386 | .drv_name = "sof_sdw", | 397 | .drv_name = "sof_sdw", |
| 387 | .sof_fw_filename = "sof-tgl.ri", | ||
| 388 | .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", | 398 | .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", |
| 389 | }, | 399 | }, |
| 400 | { | ||
| 401 | .link_mask = 0x3, /* rt711 on link 0 and 1 rt1308 on link 1 */ | ||
| 402 | .links = tgl_hp, | ||
| 403 | .drv_name = "sof_sdw", | ||
| 404 | .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", | ||
| 405 | }, | ||
| 390 | { | 406 | { |
| 391 | .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ | 407 | .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ |
| 392 | .links = tgl_rvp, | 408 | .links = tgl_rvp, |
| 393 | .drv_name = "sof_sdw", | 409 | .drv_name = "sof_sdw", |
| 394 | .sof_fw_filename = "sof-tgl.ri", | ||
| 395 | .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", | 410 | .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", |
| 396 | }, | 411 | }, |
| 397 | { | 412 | { |
| 398 | .link_mask = 0x3, /* rt5682 on link0 & 2xmax98373 on link 1 */ | 413 | .link_mask = 0x3, /* rt5682 on link0 & 2xmax98373 on link 1 */ |
| 399 | .links = tgl_chromebook_base, | 414 | .links = tgl_chromebook_base, |
| 400 | .drv_name = "sof_sdw", | 415 | .drv_name = "sof_sdw", |
| 401 | .sof_fw_filename = "sof-tgl.ri", | ||
| 402 | .sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg", | 416 | .sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg", |
| 403 | }, | 417 | }, |
| 404 | { | 418 | { |
| 405 | .link_mask = 0x1, /* this will only enable rt5682 for now */ | 419 | .link_mask = 0x1, /* this will only enable rt5682 for now */ |
| 406 | .links = tgl_chromebook_base, | 420 | .links = tgl_chromebook_base, |
| 407 | .drv_name = "sof_sdw", | 421 | .drv_name = "sof_sdw", |
| 408 | .sof_fw_filename = "sof-tgl.ri", | ||
| 409 | .sof_tplg_filename = "sof-tgl-rt5682.tplg", | 422 | .sof_tplg_filename = "sof-tgl-rt5682.tplg", |
| 410 | }, | 423 | }, |
| 411 | {}, | 424 | {}, |
| 412 | }; | 425 | }; |
| 413 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines); | 426 | EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines); |
| 414 | |||
| 415 | MODULE_LICENSE("GPL v2"); | ||
| 416 | MODULE_DESCRIPTION("Intel Common ACPI Match module"); | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #if IS_ENABLED(CONFIG_X86) | 12 | #if IS_ENABLED(CONFIG_X86) |
| 13 | 13 | ||
| 14 | #include <linux/dmi.h> | ||
| 14 | #include <asm/cpu_device_id.h> | 15 | #include <asm/cpu_device_id.h> |
| 15 | #include <asm/intel-family.h> | 16 | #include <asm/intel-family.h> |
| 16 | #include <asm/iosf_mbi.h> | 17 | #include <asm/iosf_mbi.h> |
| @@ -38,12 +39,36 @@ SOC_INTEL_IS_CPU(cml, KABYLAKE_L); · 21 unmodified lines | |||
| 38 | 39 | ||
| 39 | static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) | 40 | static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) |
| 40 | { | 41 | { |
| 42 | /* | ||
| 43 | * List of systems which: | ||
| 44 | * 1. Use a non CR version of the Bay Trail SoC | ||
| 45 | * 2. Contain at least 6 interrupt resources so that the | ||
| 46 | * platform_get_resource(pdev, IORESOURCE_IRQ, 5) check below | ||
| 47 | * succeeds | ||
| 48 | * 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5 | ||
| 49 | * | ||
| 50 | * This needs to be here so that it can be shared between the SST and | ||
| 51 | * SOF drivers. We rely on the compiler to optimize this out in files | ||
| 52 | * where soc_intel_is_byt_cr is not used. | ||
| 53 | */ | ||
| 54 | static const struct dmi_system_id force_bytcr_table[] = { | ||
| 55 | { /* Lenovo Yoga Tablet 2 series */ | ||
| 56 | .matches = { | ||
| 57 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 58 | DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"), | ||
| 59 | }, | ||
| 60 | }, | ||
| 61 | {} | ||
| 62 | }; | ||
| 41 | struct device *dev = &pdev->dev; | 63 | struct device *dev = &pdev->dev; |
| 42 | int status = 0; | 64 | int status = 0; |
| 43 | 65 | ||
| 44 | if (!soc_intel_is_byt()) | 66 | if (!soc_intel_is_byt()) |
| 45 | return false; | 67 | return false; |
| 46 | 68 | ||
| 69 | if (dmi_check_system(force_bytcr_table)) | ||
| 70 | return true; | ||
| 71 | |||
| 47 | if (iosf_mbi_available()) { | 72 | if (iosf_mbi_available()) { |
| 48 | u32 bios_status; | 73 | u32 bios_status; |
| 49 | 74 | ||
| @@ -5,11 +5,14 @@ · 4 unmodified lines | |||
| 5 | // Intel KeemBay Platform driver. | 5 | // Intel KeemBay Platform driver. |
| 6 | // | 6 | // |
| 7 | 7 | ||
| 8 | #include <linux/bitrev.h> | ||
| 8 | #include <linux/clk.h> | 9 | #include <linux/clk.h> |
| 10 | #include <linux/dma-mapping.h> | ||
| 9 | #include <linux/io.h> | 11 | #include <linux/io.h> |
| 10 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 11 | #include <linux/of.h> | 13 | #include <linux/of.h> |
| 12 | #include <linux/of_device.h> | 14 | #include <linux/of_device.h> |
| 15 | #include <sound/dmaengine_pcm.h> | ||
| 13 | #include <sound/pcm.h> | 16 | #include <sound/pcm.h> |
| 14 | #include <sound/pcm_params.h> | 17 | #include <sound/pcm_params.h> |
| 15 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
| @@ -37,7 +40,8 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { · 21 unmodified lines | |||
| 37 | .rate_max = 48000, | 40 | .rate_max = 48000, |
| 38 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 41 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
| 39 | SNDRV_PCM_FMTBIT_S24_LE | | 42 | SNDRV_PCM_FMTBIT_S24_LE | |
| 40 | SNDRV_PCM_FMTBIT_S32_LE, | 43 | SNDRV_PCM_FMTBIT_S32_LE | |
| 44 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, | ||
| 41 | .channels_min = 2, | 45 | .channels_min = 2, |
| 42 | .channels_max = 2, | 46 | .channels_max = 2, |
| 43 | .buffer_bytes_max = BUFFER_BYTES_MAX, | 47 | .buffer_bytes_max = BUFFER_BYTES_MAX, |
| @@ -48,6 +52,50 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { · 4 unmodified lines | |||
| 48 | .fifo_size = 16, | 52 | .fifo_size = 16, |
| 49 | }; | 53 | }; |
| 50 | 54 | ||
| 55 | /* | ||
| 56 | * Convert to ADV7511 HDMI hardware format. | ||
| 57 | * ADV7511 HDMI chip need parity bit replaced by block start bit and | ||
| 58 | * with the preamble bits left out. | ||
| 59 | * ALSA IEC958 subframe format: | ||
| 60 | * bit 0-3 = preamble (0x8 = block start) | ||
| 61 | * 4-7 = AUX (=0) | ||
| 62 | * 8-27 = audio data (without AUX if 24bit sample) | ||
| 63 | * 28 = validity | ||
| 64 | * 29 = user data | ||
| 65 | * 30 = channel status | ||
| 66 | * 31 = parity | ||
| 67 | * | ||
| 68 | * ADV7511 IEC958 subframe format: | ||
| 69 | * bit 0-23 = audio data | ||
| 70 | * 24 = validity | ||
| 71 | * 25 = user data | ||
| 72 | * 26 = channel status | ||
| 73 | * 27 = block start | ||
| 74 | * 28-31 = 0 | ||
| 75 | * MSB to LSB bit reverse by software as hardware not supporting it. | ||
| 76 | */ | ||
| 77 | static void hdmi_reformat_iec958(struct snd_pcm_runtime *runtime, | ||
| 78 | struct kmb_i2s_info *kmb_i2s, | ||
| 79 | unsigned int tx_ptr) | ||
| 80 | { | ||
| 81 | u32(*buf)[2] = (void *)runtime->dma_area; | ||
| 82 | unsigned long temp; | ||
| 83 | u32 i, j, sample; | ||
| 84 | |||
| 85 | for (i = 0; i < kmb_i2s->fifo_th; i++) { | ||
| 86 | j = 0; | ||
| 87 | do { | ||
| 88 | temp = buf[tx_ptr][j]; | ||
| 89 | /* Replace parity with block start*/ | ||
| 90 | assign_bit(31, &temp, (BIT(3) & temp)); | ||
| 91 | sample = bitrev32(temp); | ||
| 92 | buf[tx_ptr][j] = sample << 4; | ||
| 93 | j++; | ||
| 94 | } while (j < 2); | ||
| 95 | tx_ptr++; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 51 | static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, | 99 | static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, |
| 52 | struct snd_pcm_runtime *runtime, | 100 | struct snd_pcm_runtime *runtime, |
| 53 | unsigned int tx_ptr, bool *period_elapsed) | 101 | unsigned int tx_ptr, bool *period_elapsed) |
| @@ -63,6 +111,8 @@ static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, · 9 unmodified lines | |||
| 63 | writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); | 111 | writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); |
| 64 | writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); | 112 | writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); |
| 65 | } else { | 113 | } else { |
| 114 | if (kmb_i2s->iec958_fmt) | ||
| 115 | hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr); | ||
| 66 | writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); | 116 | writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); |
| 67 | writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); | 117 | writel(((u32(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); |
| 68 | } | 118 | } |
| @@ -233,6 +283,7 @@ static int kmb_pcm_trigger(struct snd_soc_component *component, · 164 unmodified lines | |||
| 233 | kmb_i2s->tx_substream = NULL; | 283 | kmb_i2s->tx_substream = NULL; |
| 234 | else | 284 | else |
| 235 | kmb_i2s->rx_substream = NULL; | 285 | kmb_i2s->rx_substream = NULL; |
| 286 | kmb_i2s->iec958_fmt = false; | ||
| 236 | break; | 287 | break; |
| 237 | default: | 288 | default: |
| 238 | return -EINVAL; | 289 | return -EINVAL; |
| @@ -343,6 +394,53 @@ static const struct snd_soc_component_driver kmb_component = { · 104 unmodified lines | |||
| 343 | .pointer = kmb_pcm_pointer, | 394 | .pointer = kmb_pcm_pointer, |
| 344 | }; | 395 | }; |
| 345 | 396 | ||
| 397 | static const struct snd_soc_component_driver kmb_component_dma = { | ||
| 398 | .name = "kmb", | ||
| 399 | }; | ||
| 400 | |||
| 401 | static int kmb_probe(struct snd_soc_dai *cpu_dai) | ||
| 402 | { | ||
| 403 | struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 404 | |||
| 405 | if (kmb_i2s->use_pio) | ||
| 406 | return 0; | ||
| 407 | |||
| 408 | snd_soc_dai_init_dma_data(cpu_dai, &kmb_i2s->play_dma_data, | ||
| 409 | &kmb_i2s->capture_dma_data); | ||
| 410 | |||
| 411 | return 0; | ||
| 412 | } | ||
| 413 | |||
| 414 | static inline void kmb_i2s_enable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream) | ||
| 415 | { | ||
| 416 | u32 dma_reg; | ||
| 417 | |||
| 418 | dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR); | ||
| 419 | /* Enable DMA handshake for stream */ | ||
| 420 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 421 | dma_reg |= I2S_DMAEN_TXBLOCK; | ||
| 422 | else | ||
| 423 | dma_reg |= I2S_DMAEN_RXBLOCK; | ||
| 424 | |||
| 425 | writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR); | ||
| 426 | } | ||
| 427 | |||
| 428 | static inline void kmb_i2s_disable_dma(struct kmb_i2s_info *kmb_i2s, u32 stream) | ||
| 429 | { | ||
| 430 | u32 dma_reg; | ||
| 431 | |||
| 432 | dma_reg = readl(kmb_i2s->i2s_base + I2S_DMACR); | ||
| 433 | /* Disable DMA handshake for stream */ | ||
| 434 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 435 | dma_reg &= ~I2S_DMAEN_TXBLOCK; | ||
| 436 | writel(1, kmb_i2s->i2s_base + I2S_RTXDMA); | ||
| 437 | } else { | ||
| 438 | dma_reg &= ~I2S_DMAEN_RXBLOCK; | ||
| 439 | writel(1, kmb_i2s->i2s_base + I2S_RRXDMA); | ||
| 440 | } | ||
| 441 | writel(dma_reg, kmb_i2s->i2s_base + I2S_DMACR); | ||
| 442 | } | ||
| 443 | |||
| 346 | static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, | 444 | static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, |
| 347 | struct snd_pcm_substream *substream) | 445 | struct snd_pcm_substream *substream) |
| 348 | { | 446 | { |
| @@ -356,7 +454,11 @@ static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, · 7 unmodified lines | |||
| 356 | else | 454 | else |
| 357 | writel(1, kmb_i2s->i2s_base + IRER); | 455 | writel(1, kmb_i2s->i2s_base + IRER); |
| 358 | 456 | ||
| 359 | kmb_i2s_irq_trigger(kmb_i2s, substream->stream, config->chan_nr, true); | 457 | if (kmb_i2s->use_pio) |
| 458 | kmb_i2s_irq_trigger(kmb_i2s, substream->stream, | ||
| 459 | config->chan_nr, true); | ||
| 460 | else | ||
| 461 | kmb_i2s_enable_dma(kmb_i2s, substream->stream); | ||
| 360 | 462 | ||
| 361 | if (kmb_i2s->clock_provider) | 463 | if (kmb_i2s->clock_provider) |
| 362 | writel(1, kmb_i2s->i2s_base + CER); | 464 | writel(1, kmb_i2s->i2s_base + CER); |
| @@ -434,7 +536,8 @@ static int kmb_dai_trigger(struct snd_pcm_substream *substream, · 71 unmodified lines | |||
| 434 | break; | 536 | break; |
| 435 | case SNDRV_PCM_TRIGGER_STOP: | 537 | case SNDRV_PCM_TRIGGER_STOP: |
| 436 | kmb_i2s->active--; | 538 | kmb_i2s->active--; |
| 437 | kmb_i2s_stop(kmb_i2s, substream); | 539 | if (kmb_i2s->use_pio) |
| 540 | kmb_i2s_stop(kmb_i2s, substream); | ||
| 438 | break; | 541 | break; |
| 439 | default: | 542 | default: |
| 440 | return -EINVAL; | 543 | return -EINVAL; |
| @@ -485,16 +588,25 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, · 44 unmodified lines | |||
| 485 | config->data_width = 16; | 588 | config->data_width = 16; |
| 486 | kmb_i2s->ccr = 0x00; | 589 | kmb_i2s->ccr = 0x00; |
| 487 | kmb_i2s->xfer_resolution = 0x02; | 590 | kmb_i2s->xfer_resolution = 0x02; |
| 591 | kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
| 592 | kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
| 488 | break; | 593 | break; |
| 489 | case SNDRV_PCM_FORMAT_S24_LE: | 594 | case SNDRV_PCM_FORMAT_S24_LE: |
| 490 | config->data_width = 32; | 595 | config->data_width = 32; |
| 491 | kmb_i2s->ccr = 0x14; | 596 | kmb_i2s->ccr = 0x14; |
| 492 | kmb_i2s->xfer_resolution = 0x05; | 597 | kmb_i2s->xfer_resolution = 0x05; |
| 598 | kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 599 | kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 493 | break; | 600 | break; |
| 601 | case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: | ||
| 602 | kmb_i2s->iec958_fmt = true; | ||
| 603 | fallthrough; | ||
| 494 | case SNDRV_PCM_FORMAT_S32_LE: | 604 | case SNDRV_PCM_FORMAT_S32_LE: |
| 495 | config->data_width = 32; | 605 | config->data_width = 32; |
| 496 | kmb_i2s->ccr = 0x10; | 606 | kmb_i2s->ccr = 0x10; |
| 497 | kmb_i2s->xfer_resolution = 0x05; | 607 | kmb_i2s->xfer_resolution = 0x05; |
| 608 | kmb_i2s->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 609 | kmb_i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 498 | break; | 610 | break; |
| 499 | default: | 611 | default: |
| 500 | dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt"); | 612 | dev_err(kmb_i2s->dev, "kmb: unsupported PCM fmt"); |
| @@ -572,13 +684,78 @@ static int kmb_dai_prepare(struct snd_pcm_substream *substream, · 71 unmodified lines | |||
| 572 | return 0; | 684 | return 0; |
| 573 | } | 685 | } |
| 574 | 686 | ||
| 687 | static int kmb_dai_startup(struct snd_pcm_substream *substream, | ||
| 688 | struct snd_soc_dai *cpu_dai) | ||
| 689 | { | ||
| 690 | struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 691 | struct snd_dmaengine_dai_dma_data *dma_data; | ||
| 692 | |||
| 693 | if (kmb_i2s->use_pio) | ||
| 694 | return 0; | ||
| 695 | |||
| 696 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 697 | dma_data = &kmb_i2s->play_dma_data; | ||
| 698 | else | ||
| 699 | dma_data = &kmb_i2s->capture_dma_data; | ||
| 700 | |||
| 701 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
| 702 | |||
| 703 | return 0; | ||
| 704 | } | ||
| 705 | |||
| 706 | static int kmb_dai_hw_free(struct snd_pcm_substream *substream, | ||
| 707 | struct snd_soc_dai *cpu_dai) | ||
| 708 | { | ||
| 709 | struct kmb_i2s_info *kmb_i2s = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 710 | /* I2S Programming sequence in Keem_Bay_VPU_DB_v1.1 */ | ||
| 711 | if (kmb_i2s->use_pio) | ||
| 712 | kmb_i2s_clear_irqs(kmb_i2s, substream->stream); | ||
| 713 | |||
| 714 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 715 | writel(0, kmb_i2s->i2s_base + ITER); | ||
| 716 | else | ||
| 717 | writel(0, kmb_i2s->i2s_base + IRER); | ||
| 718 | |||
| 719 | if (kmb_i2s->use_pio) | ||
| 720 | kmb_i2s_irq_trigger(kmb_i2s, substream->stream, 8, false); | ||
| 721 | else | ||
| 722 | kmb_i2s_disable_dma(kmb_i2s, substream->stream); | ||
| 723 | |||
| 724 | if (!kmb_i2s->active) { | ||
| 725 | writel(0, kmb_i2s->i2s_base + CER); | ||
| 726 | writel(0, kmb_i2s->i2s_base + IER); | ||
| 727 | } | ||
| 728 | |||
| 729 | return 0; | ||
| 730 | } | ||
| 731 | |||
| 575 | static struct snd_soc_dai_ops kmb_dai_ops = { | 732 | static struct snd_soc_dai_ops kmb_dai_ops = { |
| 733 | .startup = kmb_dai_startup, | ||
| 576 | .trigger = kmb_dai_trigger, | 734 | .trigger = kmb_dai_trigger, |
| 577 | .hw_params = kmb_dai_hw_params, | 735 | .hw_params = kmb_dai_hw_params, |
| 736 | .hw_free = kmb_dai_hw_free, | ||
| 578 | .prepare = kmb_dai_prepare, | 737 | .prepare = kmb_dai_prepare, |
| 579 | .set_fmt = kmb_set_dai_fmt, | 738 | .set_fmt = kmb_set_dai_fmt, |
| 580 | }; | 739 | }; |
| 581 | 740 | ||
| 741 | static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = { | ||
| 742 | { | ||
| 743 | .name = "intel_kmb_hdmi_i2s", | ||
| 744 | .playback = { | ||
| 745 | .channels_min = 2, | ||
| 746 | .channels_max = 2, | ||
| 747 | .rates = SNDRV_PCM_RATE_48000, | ||
| 748 | .rate_min = 48000, | ||
| 749 | .rate_max = 48000, | ||
| 750 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | | ||
| 751 | SNDRV_PCM_FMTBIT_S24_LE | | ||
| 752 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE), | ||
| 753 | }, | ||
| 754 | .ops = &kmb_dai_ops, | ||
| 755 | .probe = kmb_probe, | ||
| 756 | }, | ||
| 757 | }; | ||
| 758 | |||
| 582 | static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { | 759 | static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { |
| 583 | { | 760 | { |
| 584 | .name = "intel_kmb_i2s", | 761 | .name = "intel_kmb_i2s", |
| @@ -607,6 +784,7 @@ static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { · 22 unmodified lines | |||
| 607 | SNDRV_PCM_FMTBIT_S16_LE), | 784 | SNDRV_PCM_FMTBIT_S16_LE), |
| 608 | }, | 785 | }, |
| 609 | .ops = &kmb_dai_ops, | 786 | .ops = &kmb_dai_ops, |
| 787 | .probe = kmb_probe, | ||
| 610 | }, | 788 | }, |
| 611 | }; | 789 | }; |
| 612 | 790 | ||
| @@ -626,21 +804,25 @@ static struct snd_soc_dai_driver intel_kmb_tdm_dai[] = { · 13 unmodified lines | |||
| 626 | SNDRV_PCM_FMTBIT_S16_LE), | 804 | SNDRV_PCM_FMTBIT_S16_LE), |
| 627 | }, | 805 | }, |
| 628 | .ops = &kmb_dai_ops, | 806 | .ops = &kmb_dai_ops, |
| 807 | .probe = kmb_probe, | ||
| 629 | }, | 808 | }, |
| 630 | }; | 809 | }; |
| 631 | 810 | ||
| 632 | static const struct of_device_id kmb_plat_of_match[] = { | 811 | static const struct of_device_id kmb_plat_of_match[] = { |
| 633 | { .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai}, | 812 | { .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai}, |
| 813 | { .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai}, | ||
| 634 | { .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai}, | 814 | { .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai}, |
| 635 | {} | 815 | {} |
| 636 | }; | 816 | }; |
| 637 | 817 | ||
| 638 | static int kmb_plat_dai_probe(struct platform_device *pdev) | 818 | static int kmb_plat_dai_probe(struct platform_device *pdev) |
| 639 | { | 819 | { |
| 820 | struct device_node *np = pdev->dev.of_node; | ||
| 640 | struct snd_soc_dai_driver *kmb_i2s_dai; | 821 | struct snd_soc_dai_driver *kmb_i2s_dai; |
| 641 | const struct of_device_id *match; | 822 | const struct of_device_id *match; |
| 642 | struct device *dev = &pdev->dev; | 823 | struct device *dev = &pdev->dev; |
| 643 | struct kmb_i2s_info *kmb_i2s; | 824 | struct kmb_i2s_info *kmb_i2s; |
| 825 | struct resource *res; | ||
| 644 | int ret, irq; | 826 | int ret, irq; |
| 645 | u32 comp1_reg; | 827 | u32 comp1_reg; |
| 646 | 828 | ||
| @@ -682,7 +864,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) · 35 unmodified lines | |||
| 682 | return PTR_ERR(kmb_i2s->clk_i2s); | 864 | return PTR_ERR(kmb_i2s->clk_i2s); |
| 683 | } | 865 | } |
| 684 | 866 | ||
| 685 | kmb_i2s->i2s_base = devm_platform_ioremap_resource(pdev, 0); | 867 | kmb_i2s->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
| 686 | if (IS_ERR(kmb_i2s->i2s_base)) | 868 | if (IS_ERR(kmb_i2s->i2s_base)) |
| 687 | return PTR_ERR(kmb_i2s->i2s_base); | 869 | return PTR_ERR(kmb_i2s->i2s_base); |
| 688 | 870 | ||
| @@ -692,22 +874,38 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 692 | 874 | ||
| 693 | kmb_i2s->dev = &pdev->dev; | 875 | kmb_i2s->dev = &pdev->dev; |
| 694 | 876 | ||
| 695 | irq = platform_get_irq_optional(pdev, 0); | ||
| 696 | if (irq > 0) { | ||
| 697 | ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0, | ||
| 698 | pdev->name, kmb_i2s); | ||
| 699 | if (ret < 0) { | ||
| 700 | dev_err(dev, "failed to request irq\n"); | ||
| 701 | return ret; | ||
| 702 | } | ||
| 703 | } | ||
| 704 | |||
| 705 | comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1); | 877 | comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1); |
| 706 | 878 | ||
| 707 | kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2; | 879 | kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2; |
| 708 | 880 | ||
| 709 | ret = devm_snd_soc_register_component(dev, &kmb_component, | 881 | kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas")); |
| 710 | kmb_i2s_dai, 1); | 882 | |
| 883 | if (kmb_i2s->use_pio) { | ||
| 884 | irq = platform_get_irq_optional(pdev, 0); | ||
| 885 | if (irq > 0) { | ||
| 886 | ret = devm_request_irq(dev, irq, kmb_i2s_irq_handler, 0, | ||
| 887 | pdev->name, kmb_i2s); | ||
| 888 | if (ret < 0) { | ||
| 889 | dev_err(dev, "failed to request irq\n"); | ||
| 890 | return ret; | ||
| 891 | } | ||
| 892 | } | ||
| 893 | ret = devm_snd_soc_register_component(dev, &kmb_component, | ||
| 894 | kmb_i2s_dai, 1); | ||
| 895 | } else { | ||
| 896 | kmb_i2s->play_dma_data.addr = res->start + I2S_TXDMA; | ||
| 897 | kmb_i2s->capture_dma_data.addr = res->start + I2S_RXDMA; | ||
| 898 | ret = snd_dmaengine_pcm_register(&pdev->dev, | ||
| 899 | NULL, 0); | ||
| 900 | if (ret) { | ||
| 901 | dev_err(&pdev->dev, "could not register dmaengine: %d\n", | ||
| 902 | ret); | ||
| 903 | return ret; | ||
| 904 | } | ||
| 905 | ret = devm_snd_soc_register_component(dev, &kmb_component_dma, | ||
| 906 | kmb_i2s_dai, 1); | ||
| 907 | } | ||
| 908 | |||
| 711 | if (ret) { | 909 | if (ret) { |
| 712 | dev_err(dev, "not able to register dai\n"); | 910 | dev_err(dev, "not able to register dai\n"); |
| 713 | return ret; | 911 | return ret; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/bits.h> | 12 | #include <linux/bits.h> |
| 13 | #include <linux/bitfield.h> | 13 | #include <linux/bitfield.h> |
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <sound/dmaengine_pcm.h> | ||
| 15 | 16 | ||
| 16 | /* Register values with reference to KMB databook v1.1 */ | 17 | /* Register values with reference to KMB databook v1.1 */ |
| 17 | /* common register for all channel */ | 18 | /* common register for all channel */ |
| @@ -103,7 +104,12 @@ · 85 unmodified lines | |||
| 103 | #define DW_I2S_PROVIDER BIT(3) | 104 | #define DW_I2S_PROVIDER BIT(3) |
| 104 | 105 | ||
| 105 | #define I2S_RXDMA 0x01C0 | 106 | #define I2S_RXDMA 0x01C0 |
| 107 | #define I2S_RRXDMA 0x01C4 | ||
| 106 | #define I2S_TXDMA 0x01C8 | 108 | #define I2S_TXDMA 0x01C8 |
| 109 | #define I2S_RTXDMA 0x01CC | ||
| 110 | #define I2S_DMACR 0x0200 | ||
| 111 | #define I2S_DMAEN_RXBLOCK (1 << 16) | ||
| 112 | #define I2S_DMAEN_TXBLOCK (1 << 17) | ||
| 107 | 113 | ||
| 108 | /* | 114 | /* |
| 109 | * struct i2s_clk_config_data - represent i2s clk configuration data | 115 | * struct i2s_clk_config_data - represent i2s clk configuration data |
| @@ -131,6 +137,9 @@ struct kmb_i2s_info { · 21 unmodified lines | |||
| 131 | u32 xfer_resolution; | 137 | u32 xfer_resolution; |
| 132 | u32 fifo_th; | 138 | u32 fifo_th; |
| 133 | bool clock_provider; | 139 | bool clock_provider; |
| 140 | /* data related to DMA transfers b/w i2s and DMAC */ | ||
| 141 | struct snd_dmaengine_dai_dma_data play_dma_data; | ||
| 142 | struct snd_dmaengine_dai_dma_data capture_dma_data; | ||
| 134 | 143 | ||
| 135 | struct i2s_clk_config_data config; | 144 | struct i2s_clk_config_data config; |
| 136 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); | 145 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); |
| @@ -141,6 +150,7 @@ struct kmb_i2s_info { · 4 unmodified lines | |||
| 141 | struct snd_pcm_substream *rx_substream; | 150 | struct snd_pcm_substream *rx_substream; |
| 142 | unsigned int tx_ptr; | 151 | unsigned int tx_ptr; |
| 143 | unsigned int rx_ptr; | 152 | unsigned int rx_ptr; |
| 153 | bool iec958_fmt; | ||
| 144 | }; | 154 | }; |
| 145 | 155 | ||
| 146 | #endif /* KMB_PLATFORM_H_ */ | 156 | #endif /* KMB_PLATFORM_H_ */ |
| @@ -950,12 +950,8 @@ static int skl_first_init(struct hdac_bus *bus) · 949 unmodified lines | |||
| 950 | bus->num_streams = cp_streams + pb_streams; | 950 | bus->num_streams = cp_streams + pb_streams; |
| 951 | 951 | ||
| 952 | /* allow 64bit DMA address if supported by H/W */ | 952 | /* allow 64bit DMA address if supported by H/W */ |
| 953 | if (!dma_set_mask(bus->dev, DMA_BIT_MASK(64))) { | 953 | if (dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(64))) |
| 954 | dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(64)); | 954 | dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(32)); |
| 955 | } else { | ||
| 956 | dma_set_mask(bus->dev, DMA_BIT_MASK(32)); | ||
| 957 | dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(32)); | ||
| 958 | } | ||
| 959 | 955 | ||
| 960 | /* initialize streams */ | 956 | /* initialize streams */ |
| 961 | snd_hdac_ext_stream_init_all | 957 | snd_hdac_ext_stream_init_all |
| @@ -455,7 +455,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { · 454 unmodified lines | |||
| 455 | .rates = SNDRV_PCM_RATE_8000_48000, | 455 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 456 | .formats = JZ4740_I2S_FMTS, | 456 | .formats = JZ4740_I2S_FMTS, |
| 457 | }, | 457 | }, |
| 458 | .symmetric_rates = 1, | 458 | .symmetric_rate = 1, |
| 459 | .ops = &jz4740_i2s_dai_ops, | 459 | .ops = &jz4740_i2s_dai_ops, |
| 460 | }; | 460 | }; |
| 461 | 461 | ||
| @@ -182,25 +182,6 @@ static int kirkwood_dma_close(struct snd_soc_component *component, · 181 unmodified lines | |||
| 182 | return 0; | 182 | return 0; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | static int kirkwood_dma_hw_params(struct snd_soc_component *component, | ||
| 186 | struct snd_pcm_substream *substream, | ||
| 187 | struct snd_pcm_hw_params *params) | ||
| 188 | { | ||
| 189 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 190 | |||
| 191 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
| 192 | runtime->dma_bytes = params_buffer_bytes(params); | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | static int kirkwood_dma_hw_free(struct snd_soc_component *component, | ||
| 198 | struct snd_pcm_substream *substream) | ||
| 199 | { | ||
| 200 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static int kirkwood_dma_prepare(struct snd_soc_component *component, | 185 | static int kirkwood_dma_prepare(struct snd_soc_component *component, |
| 205 | struct snd_pcm_substream *substream) | 186 | struct snd_pcm_substream *substream) |
| 206 | { | 187 | { |
| @@ -244,82 +225,28 @@ static snd_pcm_uframes_t kirkwood_dma_pointer( · 37 unmodified lines | |||
| 244 | return count; | 225 | return count; |
| 245 | } | 226 | } |
| 246 | 227 | ||
| 247 | static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm, | ||
| 248 | int stream) | ||
| 249 | { | ||
| 250 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
| 251 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
| 252 | size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; | ||
| 253 | |||
| 254 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
| 255 | buf->dev.dev = pcm->card->dev; | ||
| 256 | buf->area = dma_alloc_coherent(pcm->card->dev, size, | ||
| 257 | &buf->addr, GFP_KERNEL); | ||
| 258 | if (!buf->area) | ||
| 259 | return -ENOMEM; | ||
| 260 | buf->bytes = size; | ||
| 261 | buf->private_data = NULL; | ||
| 262 | |||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | static int kirkwood_dma_new(struct snd_soc_component *component, | 228 | static int kirkwood_dma_new(struct snd_soc_component *component, |
| 267 | struct snd_soc_pcm_runtime *rtd) | 229 | struct snd_soc_pcm_runtime *rtd) |
| 268 | { | 230 | { |
| 231 | size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; | ||
| 269 | struct snd_card *card = rtd->card->snd_card; | 232 | struct snd_card *card = rtd->card->snd_card; |
| 270 | struct snd_pcm *pcm = rtd->pcm; | ||
| 271 | int ret; | 233 | int ret; |
| 272 | 234 | ||
| 273 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); | 235 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); |
| 274 | if (ret) | 236 | if (ret) |
| 275 | return ret; | 237 | return ret; |
| 276 | 238 | ||
| 277 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 239 | snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, |
| 278 | ret = kirkwood_dma_preallocate_dma_buffer(pcm, | 240 | card->dev, size, size); |
| 279 | SNDRV_PCM_STREAM_PLAYBACK); | ||
| 280 | if (ret) | ||
| 281 | return ret; | ||
| 282 | } | ||
| 283 | |||
| 284 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
| 285 | ret = kirkwood_dma_preallocate_dma_buffer(pcm, | ||
| 286 | SNDRV_PCM_STREAM_CAPTURE); | ||
| 287 | if (ret) | ||
| 288 | return ret; | ||
| 289 | } | ||
| 290 | 241 | ||
| 291 | return 0; | 242 | return 0; |
| 292 | } | 243 | } |
| 293 | 244 | ||
| 294 | static void kirkwood_dma_free_dma_buffers(struct snd_soc_component *component, | ||
| 295 | struct snd_pcm *pcm) | ||
| 296 | { | ||
| 297 | struct snd_pcm_substream *substream; | ||
| 298 | struct snd_dma_buffer *buf; | ||
| 299 | int stream; | ||
| 300 | |||
| 301 | for (stream = 0; stream < 2; stream++) { | ||
| 302 | substream = pcm->streams[stream].substream; | ||
| 303 | if (!substream) | ||
| 304 | continue; | ||
| 305 | buf = &substream->dma_buffer; | ||
| 306 | if (!buf->area) | ||
| 307 | continue; | ||
| 308 | |||
| 309 | dma_free_coherent(pcm->card->dev, buf->bytes, | ||
| 310 | buf->area, buf->addr); | ||
| 311 | buf->area = NULL; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | const struct snd_soc_component_driver kirkwood_soc_component = { | 245 | const struct snd_soc_component_driver kirkwood_soc_component = { |
| 316 | .name = DRV_NAME, | 246 | .name = DRV_NAME, |
| 317 | .open = kirkwood_dma_open, | 247 | .open = kirkwood_dma_open, |
| 318 | .close = kirkwood_dma_close, | 248 | .close = kirkwood_dma_close, |
| 319 | .hw_params = kirkwood_dma_hw_params, | ||
| 320 | .hw_free = kirkwood_dma_hw_free, | ||
| 321 | .prepare = kirkwood_dma_prepare, | 249 | .prepare = kirkwood_dma_prepare, |
| 322 | .pointer = kirkwood_dma_pointer, | 250 | .pointer = kirkwood_dma_pointer, |
| 323 | .pcm_construct = kirkwood_dma_new, | 251 | .pcm_construct = kirkwood_dma_new, |
| 324 | .pcm_destruct = kirkwood_dma_free_dma_buffers, | ||
| 325 | }; | 252 | }; |
| @@ -172,7 +172,7 @@ config SND_SOC_MT8192 · 171 unmodified lines | |||
| 172 | config SND_SOC_MT8192_MT6359_RT1015_RT5682 | 172 | config SND_SOC_MT8192_MT6359_RT1015_RT5682 |
| 173 | tristate "ASoC Audio driver for MT8192 with MT6359 RT1015 RT5682 codec" | 173 | tristate "ASoC Audio driver for MT8192 with MT6359 RT1015 RT5682 codec" |
| 174 | depends on I2C | 174 | depends on I2C |
| 175 | depends on SND_SOC_MT8192 | 175 | depends on SND_SOC_MT8192 && MTK_PMIC_WRAP |
| 176 | select SND_SOC_MT6359 | 176 | select SND_SOC_MT6359 |
| 177 | select SND_SOC_RT1015 | 177 | select SND_SOC_RT1015 |
| 178 | select SND_SOC_RT1015P | 178 | select SND_SOC_RT1015P |
| @@ -655,7 +655,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 654 unmodified lines | |||
| 655 | 655 | ||
| 656 | }, | 656 | }, |
| 657 | .ops = &mt2701_afe_i2s_ops, | 657 | .ops = &mt2701_afe_i2s_ops, |
| 658 | .symmetric_rates = 1, | 658 | .symmetric_rate = 1, |
| 659 | }, | 659 | }, |
| 660 | { | 660 | { |
| 661 | .name = "I2S1", | 661 | .name = "I2S1", |
| @@ -679,7 +679,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | |||
| 679 | | SNDRV_PCM_FMTBIT_S32_LE) | 679 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 680 | }, | 680 | }, |
| 681 | .ops = &mt2701_afe_i2s_ops, | 681 | .ops = &mt2701_afe_i2s_ops, |
| 682 | .symmetric_rates = 1, | 682 | .symmetric_rate = 1, |
| 683 | }, | 683 | }, |
| 684 | { | 684 | { |
| 685 | .name = "I2S2", | 685 | .name = "I2S2", |
| @@ -703,7 +703,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | |||
| 703 | | SNDRV_PCM_FMTBIT_S32_LE) | 703 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 704 | }, | 704 | }, |
| 705 | .ops = &mt2701_afe_i2s_ops, | 705 | .ops = &mt2701_afe_i2s_ops, |
| 706 | .symmetric_rates = 1, | 706 | .symmetric_rate = 1, |
| 707 | }, | 707 | }, |
| 708 | { | 708 | { |
| 709 | .name = "I2S3", | 709 | .name = "I2S3", |
| @@ -727,7 +727,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | |||
| 727 | | SNDRV_PCM_FMTBIT_S32_LE) | 727 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 728 | }, | 728 | }, |
| 729 | .ops = &mt2701_afe_i2s_ops, | 729 | .ops = &mt2701_afe_i2s_ops, |
| 730 | .symmetric_rates = 1, | 730 | .symmetric_rate = 1, |
| 731 | }, | 731 | }, |
| 732 | { | 732 | { |
| 733 | .name = "MRG BT", | 733 | .name = "MRG BT", |
| @@ -749,7 +749,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 15 unmodified lines | |||
| 749 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 749 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 750 | }, | 750 | }, |
| 751 | .ops = &mt2701_btmrg_ops, | 751 | .ops = &mt2701_btmrg_ops, |
| 752 | .symmetric_rates = 1, | 752 | .symmetric_rate = 1, |
| 753 | } | 753 | } |
| 754 | }; | 754 | }; |
| 755 | 755 | ||
| @@ -270,8 +270,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 269 unmodified lines | |||
| 270 | .formats = MTK_PCM_FORMATS, | 270 | .formats = MTK_PCM_FORMATS, |
| 271 | }, | 271 | }, |
| 272 | .ops = &mtk_dai_pcm_ops, | 272 | .ops = &mtk_dai_pcm_ops, |
| 273 | .symmetric_rates = 1, | 273 | .symmetric_rate = 1, |
| 274 | .symmetric_samplebits = 1, | 274 | .symmetric_sample_bits = 1, |
| 275 | }, | 275 | }, |
| 276 | { | 276 | { |
| 277 | .name = "PCM 2", | 277 | .name = "PCM 2", |
| @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | |||
| 291 | .formats = MTK_PCM_FORMATS, | 291 | .formats = MTK_PCM_FORMATS, |
| 292 | }, | 292 | }, |
| 293 | .ops = &mtk_dai_pcm_ops, | 293 | .ops = &mtk_dai_pcm_ops, |
| 294 | .symmetric_rates = 1, | 294 | .symmetric_rate = 1, |
| 295 | .symmetric_samplebits = 1, | 295 | .symmetric_sample_bits = 1, |
| 296 | }, | 296 | }, |
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| @@ -571,7 +571,7 @@ static struct snd_soc_dai_driver mt8173_afe_pcm_dais[] = { · 570 unmodified lines | |||
| 571 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 571 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 572 | }, | 572 | }, |
| 573 | .ops = &mt8173_afe_i2s_ops, | 573 | .ops = &mt8173_afe_i2s_ops, |
| 574 | .symmetric_rates = 1, | 574 | .symmetric_rate = 1, |
| 575 | }, | 575 | }, |
| 576 | }; | 576 | }; |
| 577 | 577 | ||
| @@ -125,12 +125,6 @@ mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, · 124 unmodified lines | |||
| 125 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 125 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 126 | if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || | 126 | if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || |
| 127 | !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { | 127 | !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { |
| 128 | ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); | ||
| 129 | if (ret) { | ||
| 130 | dev_err(rtd->dev, "failed to set bclk ratio\n"); | ||
| 131 | return ret; | ||
| 132 | } | ||
| 133 | |||
| 134 | ret = snd_soc_dai_set_pll(codec_dai, 0, | 128 | ret = snd_soc_dai_set_pll(codec_dai, 0, |
| 135 | RT1015_PLL_S_BCLK, | 129 | RT1015_PLL_S_BCLK, |
| 136 | rate * 64, rate * 256); | 130 | rate * 64, rate * 256); |
| @@ -270,8 +270,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 269 unmodified lines | |||
| 270 | .formats = MTK_PCM_FORMATS, | 270 | .formats = MTK_PCM_FORMATS, |
| 271 | }, | 271 | }, |
| 272 | .ops = &mtk_dai_pcm_ops, | 272 | .ops = &mtk_dai_pcm_ops, |
| 273 | .symmetric_rates = 1, | 273 | .symmetric_rate = 1, |
| 274 | .symmetric_samplebits = 1, | 274 | .symmetric_sample_bits = 1, |
| 275 | }, | 275 | }, |
| 276 | { | 276 | { |
| 277 | .name = "PCM 2", | 277 | .name = "PCM 2", |
| @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | |||
| 291 | .formats = MTK_PCM_FORMATS, | 291 | .formats = MTK_PCM_FORMATS, |
| 292 | }, | 292 | }, |
| 293 | .ops = &mtk_dai_pcm_ops, | 293 | .ops = &mtk_dai_pcm_ops, |
| 294 | .symmetric_rates = 1, | 294 | .symmetric_rate = 1, |
| 295 | .symmetric_samplebits = 1, | 295 | .symmetric_sample_bits = 1, |
| 296 | }, | 296 | }, |
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| @@ -68,12 +68,6 @@ mt8183_mt6358_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, · 67 unmodified lines | |||
| 68 | int ret, i; | 68 | int ret, i; |
| 69 | 69 | ||
| 70 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 70 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 71 | ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); | ||
| 72 | if (ret < 0) { | ||
| 73 | dev_err(card->dev, "failed to set bclk ratio\n"); | ||
| 74 | return ret; | ||
| 75 | } | ||
| 76 | |||
| 77 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, | 71 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 78 | rate * 64, rate * 256); | 72 | rate * 64, rate * 256); |
| 79 | if (ret < 0) { | 73 | if (ret < 0) { |
| @@ -123,6 +117,45 @@ static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, · 43 unmodified lines | |||
| 123 | return 0; | 117 | return 0; |
| 124 | } | 118 | } |
| 125 | 119 | ||
| 120 | static int | ||
| 121 | mt8183_mt6358_startup(struct snd_pcm_substream *substream) | ||
| 122 | { | ||
| 123 | static const unsigned int rates[] = { | ||
| 124 | 48000, | ||
| 125 | }; | ||
| 126 | static const struct snd_pcm_hw_constraint_list constraints_rates = { | ||
| 127 | .count = ARRAY_SIZE(rates), | ||
| 128 | .list = rates, | ||
| 129 | .mask = 0, | ||
| 130 | }; | ||
| 131 | static const unsigned int channels[] = { | ||
| 132 | 2, | ||
| 133 | }; | ||
| 134 | static const struct snd_pcm_hw_constraint_list constraints_channels = { | ||
| 135 | .count = ARRAY_SIZE(channels), | ||
| 136 | .list = channels, | ||
| 137 | .mask = 0, | ||
| 138 | }; | ||
| 139 | |||
| 140 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 141 | |||
| 142 | snd_pcm_hw_constraint_list(runtime, 0, | ||
| 143 | SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); | ||
| 144 | runtime->hw.channels_max = 2; | ||
| 145 | snd_pcm_hw_constraint_list(runtime, 0, | ||
| 146 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
| 147 | &constraints_channels); | ||
| 148 | |||
| 149 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 150 | snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static const struct snd_soc_ops mt8183_mt6358_ops = { | ||
| 156 | .startup = mt8183_mt6358_startup, | ||
| 157 | }; | ||
| 158 | |||
| 126 | static int | 159 | static int |
| 127 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( | 160 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( |
| 128 | struct snd_pcm_substream *substream) | 161 | struct snd_pcm_substream *substream) |
| @@ -362,6 +395,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { · 233 unmodified lines | |||
| 362 | SND_SOC_DPCM_TRIGGER_PRE}, | 395 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 363 | .dynamic = 1, | 396 | .dynamic = 1, |
| 364 | .dpcm_playback = 1, | 397 | .dpcm_playback = 1, |
| 398 | .ops = &mt8183_mt6358_ops, | ||
| 365 | SND_SOC_DAILINK_REG(playback1), | 399 | SND_SOC_DAILINK_REG(playback1), |
| 366 | }, | 400 | }, |
| 367 | { | 401 | { |
| @@ -409,6 +443,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { · 41 unmodified lines | |||
| 409 | SND_SOC_DPCM_TRIGGER_PRE}, | 443 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 410 | .dynamic = 1, | 444 | .dynamic = 1, |
| 411 | .dpcm_capture = 1, | 445 | .dpcm_capture = 1, |
| 446 | .ops = &mt8183_mt6358_ops, | ||
| 412 | SND_SOC_DAILINK_REG(capture3), | 447 | SND_SOC_DAILINK_REG(capture3), |
| 413 | }, | 448 | }, |
| 414 | { | 449 | { |
| @@ -42,7 +42,7 @@ static const struct snd_pcm_hardware mt8192_afe_hardware = { · 41 unmodified lines | |||
| 42 | static int mt8192_memif_fs(struct snd_pcm_substream *substream, | 42 | static int mt8192_memif_fs(struct snd_pcm_substream *substream, |
| 43 | unsigned int rate) | 43 | unsigned int rate) |
| 44 | { | 44 | { |
| 45 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 45 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 46 | struct snd_soc_component *component = | 46 | struct snd_soc_component *component = |
| 47 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); | 47 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); |
| 48 | struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); | 48 | struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); |
| @@ -59,7 +59,7 @@ static int mt8192_get_dai_fs(struct mtk_base_afe *afe, · 10 unmodified lines | |||
| 59 | 59 | ||
| 60 | static int mt8192_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) | 60 | static int mt8192_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) |
| 61 | { | 61 | { |
| 62 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 62 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 63 | struct snd_soc_component *component = | 63 | struct snd_soc_component *component = |
| 64 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); | 64 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); |
| 65 | struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); | 65 | struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); |
| @@ -360,8 +360,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 359 unmodified lines | |||
| 360 | .formats = MTK_PCM_FORMATS, | 360 | .formats = MTK_PCM_FORMATS, |
| 361 | }, | 361 | }, |
| 362 | .ops = &mtk_dai_pcm_ops, | 362 | .ops = &mtk_dai_pcm_ops, |
| 363 | .symmetric_rates = 1, | 363 | .symmetric_rate = 1, |
| 364 | .symmetric_samplebits = 1, | 364 | .symmetric_sample_bits = 1, |
| 365 | }, | 365 | }, |
| 366 | { | 366 | { |
| 367 | .name = "PCM 2", | 367 | .name = "PCM 2", |
| @@ -381,8 +381,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | |||
| 381 | .formats = MTK_PCM_FORMATS, | 381 | .formats = MTK_PCM_FORMATS, |
| 382 | }, | 382 | }, |
| 383 | .ops = &mtk_dai_pcm_ops, | 383 | .ops = &mtk_dai_pcm_ops, |
| 384 | .symmetric_rates = 1, | 384 | .symmetric_rate = 1, |
| 385 | .symmetric_samplebits = 1, | 385 | .symmetric_sample_bits = 1, |
| 386 | }, | 386 | }, |
| 387 | }; | 387 | }; |
| 388 | 388 | ||
| @@ -738,7 +738,7 @@ static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe) · 737 unmodified lines | |||
| 738 | if (!tdm_priv) | 738 | if (!tdm_priv) |
| 739 | return NULL; | 739 | return NULL; |
| 740 | 740 | ||
| 741 | tdm_priv->mclk_multiple = 128; | 741 | tdm_priv->mclk_multiple = 512; |
| 742 | tdm_priv->bck_id = MT8192_I2S4_BCK; | 742 | tdm_priv->bck_id = MT8192_I2S4_BCK; |
| 743 | tdm_priv->mclk_id = MT8192_I2S4_MCK; | 743 | tdm_priv->mclk_id = MT8192_I2S4_MCK; |
| 744 | tdm_priv->id = MT8192_DAI_TDM; | 744 | tdm_priv->id = MT8192_DAI_TDM; |
| @@ -31,12 +31,15 @@ · 30 unmodified lines | |||
| 31 | #define RT5682_CODEC_DAI "rt5682-aif1" | 31 | #define RT5682_CODEC_DAI "rt5682-aif1" |
| 32 | #define RT5682_DEV0_NAME "rt5682.1-001a" | 32 | #define RT5682_DEV0_NAME "rt5682.1-001a" |
| 33 | 33 | ||
| 34 | static struct snd_soc_jack headset_jack; | 34 | struct mt8192_mt6359_priv { |
| 35 | struct snd_soc_jack headset_jack; | ||
| 36 | struct snd_soc_jack hdmi_jack; | ||
| 37 | }; | ||
| 35 | 38 | ||
| 36 | static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, | 39 | static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, |
| 37 | struct snd_pcm_hw_params *params) | 40 | struct snd_pcm_hw_params *params) |
| 38 | { | 41 | { |
| 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 42 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 40 | struct snd_soc_card *card = rtd->card; | 43 | struct snd_soc_card *card = rtd->card; |
| 41 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); | 44 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
| 42 | struct snd_soc_dai *codec_dai; | 45 | struct snd_soc_dai *codec_dai; |
| @@ -46,12 +49,6 @@ static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, · 3 unmodified lines | |||
| 46 | int ret, i; | 49 | int ret, i; |
| 47 | 50 | ||
| 48 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 51 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 49 | ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); | ||
| 50 | if (ret) { | ||
| 51 | dev_err(card->dev, "failed to set bclk ratio\n"); | ||
| 52 | return ret; | ||
| 53 | } | ||
| 54 | |||
| 55 | ret = snd_soc_dai_set_pll(codec_dai, 0, | 52 | ret = snd_soc_dai_set_pll(codec_dai, 0, |
| 56 | RT1015_PLL_S_BCLK, | 53 | RT1015_PLL_S_BCLK, |
| 57 | params_rate(params) * 64, | 54 | params_rate(params) * 64, |
| @@ -77,7 +74,7 @@ static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, · 19 unmodified lines | |||
| 77 | static int mt8192_rt5682_i2s_hw_params(struct snd_pcm_substream *substream, | 74 | static int mt8192_rt5682_i2s_hw_params(struct snd_pcm_substream *substream, |
| 78 | struct snd_pcm_hw_params *params) | 75 | struct snd_pcm_hw_params *params) |
| 79 | { | 76 | { |
| 80 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 77 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 81 | struct snd_soc_card *card = rtd->card; | 78 | struct snd_soc_card *card = rtd->card; |
| 82 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); | 79 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
| 83 | struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); | 80 | struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
| @@ -311,7 +308,8 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) · 227 unmodified lines | |||
| 311 | { | 308 | { |
| 312 | struct snd_soc_component *cmpnt_codec = | 309 | struct snd_soc_component *cmpnt_codec = |
| 313 | asoc_rtd_to_codec(rtd, 0)->component; | 310 | asoc_rtd_to_codec(rtd, 0)->component; |
| 314 | struct snd_soc_jack *jack = &headset_jack; | 311 | struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); |
| 312 | struct snd_soc_jack *jack = &priv->headset_jack; | ||
| 315 | int ret; | 313 | int ret; |
| 316 | 314 | ||
| 317 | ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", | 315 | ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", |
| @@ -329,14 +327,25 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd) · 11 unmodified lines | |||
| 329 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | 327 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
| 330 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | 328 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
| 331 | 329 | ||
| 332 | ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); | 330 | return snd_soc_component_set_jack(cmpnt_codec, jack, NULL); |
| 331 | }; | ||
| 332 | |||
| 333 | static int mt8192_mt6359_hdmi_init(struct snd_soc_pcm_runtime *rtd) | ||
| 334 | { | ||
| 335 | struct snd_soc_component *cmpnt_codec = | ||
| 336 | asoc_rtd_to_codec(rtd, 0)->component; | ||
| 337 | struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); | ||
| 338 | int ret; | ||
| 339 | |||
| 340 | ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, | ||
| 341 | &priv->hdmi_jack, NULL, 0); | ||
| 333 | if (ret) { | 342 | if (ret) { |
| 334 | dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); | 343 | dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret); |
| 335 | return ret; | 344 | return ret; |
| 336 | } | 345 | } |
| 337 | 346 | ||
| 338 | return 0; | 347 | return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); |
| 339 | }; | 348 | } |
| 340 | 349 | ||
| 341 | static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, | 350 | static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, |
| 342 | struct snd_pcm_hw_params *params) | 351 | struct snd_pcm_hw_params *params) |
| @@ -351,14 +360,8 @@ static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, · 8 unmodified lines | |||
| 351 | } | 360 | } |
| 352 | 361 | ||
| 353 | static int | 362 | static int |
| 354 | mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) | 363 | mt8192_mt6359_cap1_startup(struct snd_pcm_substream *substream) |
| 355 | { | 364 | { |
| 356 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 357 | struct snd_soc_component *component = | ||
| 358 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); | ||
| 359 | struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); | ||
| 360 | int ret; | ||
| 361 | |||
| 362 | static const unsigned int channels[] = { | 365 | static const unsigned int channels[] = { |
| 363 | 1, 2, 4 | 366 | 1, 2, 4 |
| 364 | }; | 367 | }; |
| @@ -376,13 +379,15 @@ mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) · 11 unmodified lines | |||
| 376 | .mask = 0, | 379 | .mask = 0, |
| 377 | }; | 380 | }; |
| 378 | 381 | ||
| 382 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | ||
| 379 | struct snd_pcm_runtime *runtime = substream->runtime; | 383 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 384 | int ret; | ||
| 380 | 385 | ||
| 381 | ret = snd_pcm_hw_constraint_list(runtime, 0, | 386 | ret = snd_pcm_hw_constraint_list(runtime, 0, |
| 382 | SNDRV_PCM_HW_PARAM_CHANNELS, | 387 | SNDRV_PCM_HW_PARAM_CHANNELS, |
| 383 | &constraints_channels); | 388 | &constraints_channels); |
| 384 | if (ret < 0) { | 389 | if (ret < 0) { |
| 385 | dev_err(afe->dev, "hw_constraint_list channels failed\n"); | 390 | dev_err(rtd->dev, "hw_constraint_list channels failed\n"); |
| 386 | return ret; | 391 | return ret; |
| 387 | } | 392 | } |
| 388 | 393 | ||
| @@ -390,15 +395,15 @@ mt8192_mt6359_rt1015_rt5682_cap1_startup(struct snd_pcm_substream *substream) · 1 unmodified line | |||
| 390 | SNDRV_PCM_HW_PARAM_RATE, | 395 | SNDRV_PCM_HW_PARAM_RATE, |
| 391 | &constraints_rates); | 396 | &constraints_rates); |
| 392 | if (ret < 0) { | 397 | if (ret < 0) { |
| 393 | dev_err(afe->dev, "hw_constraint_list rate failed\n"); | 398 | dev_err(rtd->dev, "hw_constraint_list rate failed\n"); |
| 394 | return ret; | 399 | return ret; |
| 395 | } | 400 | } |
| 396 | 401 | ||
| 397 | return 0; | 402 | return 0; |
| 398 | } | 403 | } |
| 399 | 404 | ||
| 400 | static const struct snd_soc_ops mt8192_mt6359_rt1015_rt5682_capture1_ops = { | 405 | static const struct snd_soc_ops mt8192_mt6359_capture1_ops = { |
| 401 | .startup = mt8192_mt6359_rt1015_rt5682_cap1_startup, | 406 | .startup = mt8192_mt6359_cap1_startup, |
| 402 | }; | 407 | }; |
| 403 | 408 | ||
| 404 | static int | 409 | static int |
| @@ -656,7 +661,7 @@ SND_SOC_DAILINK_DEFS(pcm2, · 251 unmodified lines | |||
| 656 | 661 | ||
| 657 | SND_SOC_DAILINK_DEFS(tdm, | 662 | SND_SOC_DAILINK_DEFS(tdm, |
| 658 | DAILINK_COMP_ARRAY(COMP_CPU("TDM")), | 663 | DAILINK_COMP_ARRAY(COMP_CPU("TDM")), |
| 659 | DAILINK_COMP_ARRAY(COMP_DUMMY()), | 664 | DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), |
| 660 | DAILINK_COMP_ARRAY(COMP_EMPTY())); | 665 | DAILINK_COMP_ARRAY(COMP_EMPTY())); |
| 661 | 666 | ||
| 662 | static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { | 667 | static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { |
| @@ -759,7 +764,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { · 96 unmodified lines | |||
| 759 | SND_SOC_DPCM_TRIGGER_PRE}, | 764 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 760 | .dynamic = 1, | 765 | .dynamic = 1, |
| 761 | .dpcm_capture = 1, | 766 | .dpcm_capture = 1, |
| 762 | .ops = &mt8192_mt6359_rt1015_rt5682_capture1_ops, | 767 | .ops = &mt8192_mt6359_capture1_ops, |
| 763 | SND_SOC_DAILINK_REG(capture1), | 768 | SND_SOC_DAILINK_REG(capture1), |
| 764 | }, | 769 | }, |
| 765 | { | 770 | { |
| @@ -994,8 +999,14 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { · 228 unmodified lines | |||
| 994 | { | 999 | { |
| 995 | .name = "TDM", | 1000 | .name = "TDM", |
| 996 | .no_pcm = 1, | 1001 | .no_pcm = 1, |
| 1002 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | | ||
| 1003 | SND_SOC_DAIFMT_IB_NF | | ||
| 1004 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 997 | .dpcm_playback = 1, | 1005 | .dpcm_playback = 1, |
| 998 | .ignore_suspend = 1, | 1006 | .ignore_suspend = 1, |
| 1007 | .be_hw_params_fixup = mt8192_i2s_hw_params_fixup, | ||
| 1008 | .ignore = 1, | ||
| 1009 | .init = mt8192_mt6359_hdmi_init, | ||
| 999 | SND_SOC_DAILINK_REG(tdm), | 1010 | SND_SOC_DAILINK_REG(tdm), |
| 1000 | }, | 1011 | }, |
| 1001 | }; | 1012 | }; |
| @@ -1006,6 +1017,7 @@ mt8192_mt6359_rt1015_rt5682_widgets[] = { · 4 unmodified lines | |||
| 1006 | SND_SOC_DAPM_SPK("Right Spk", NULL), | 1017 | SND_SOC_DAPM_SPK("Right Spk", NULL), |
| 1007 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | 1018 | SND_SOC_DAPM_HP("Headphone Jack", NULL), |
| 1008 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 1019 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
| 1020 | SND_SOC_DAPM_OUTPUT("TDM Out"), | ||
| 1009 | }; | 1021 | }; |
| 1010 | 1022 | ||
| 1011 | static const struct snd_soc_dapm_route mt8192_mt6359_rt1015_rt5682_routes[] = { | 1023 | static const struct snd_soc_dapm_route mt8192_mt6359_rt1015_rt5682_routes[] = { |
| @@ -1016,6 +1028,8 @@ static const struct snd_soc_dapm_route mt8192_mt6359_rt1015_rt5682_routes[] = { · 4 unmodified lines | |||
| 1016 | { "Headphone Jack", NULL, "HPOL" }, | 1028 | { "Headphone Jack", NULL, "HPOL" }, |
| 1017 | { "Headphone Jack", NULL, "HPOR" }, | 1029 | { "Headphone Jack", NULL, "HPOR" }, |
| 1018 | { "IN1P", NULL, "Headset Mic" }, | 1030 | { "IN1P", NULL, "Headset Mic" }, |
| 1031 | /* TDM */ | ||
| 1032 | { "TDM Out", NULL, "TDM" }, | ||
| 1019 | }; | 1033 | }; |
| 1020 | 1034 | ||
| 1021 | static const struct snd_kcontrol_new mt8192_mt6359_rt1015_rt5682_controls[] = { | 1035 | static const struct snd_kcontrol_new mt8192_mt6359_rt1015_rt5682_controls[] = { |
| @@ -1089,10 +1103,11 @@ static struct snd_soc_card mt8192_mt6359_rt1015p_rt5682_card = { · 67 unmodified lines | |||
| 1089 | static int mt8192_mt6359_dev_probe(struct platform_device *pdev) | 1103 | static int mt8192_mt6359_dev_probe(struct platform_device *pdev) |
| 1090 | { | 1104 | { |
| 1091 | struct snd_soc_card *card; | 1105 | struct snd_soc_card *card; |
| 1092 | struct device_node *platform_node; | 1106 | struct device_node *platform_node, *hdmi_codec; |
| 1093 | int ret, i; | 1107 | int ret, i; |
| 1094 | struct snd_soc_dai_link *dai_link; | 1108 | struct snd_soc_dai_link *dai_link; |
| 1095 | const struct of_device_id *match; | 1109 | const struct of_device_id *match; |
| 1110 | struct mt8192_mt6359_priv *priv; | ||
| 1096 | 1111 | ||
| 1097 | platform_node = of_parse_phandle(pdev->dev.of_node, | 1112 | platform_node = of_parse_phandle(pdev->dev.of_node, |
| 1098 | "mediatek,platform", 0); | 1113 | "mediatek,platform", 0); |
| @@ -1108,6 +1123,9 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 1108 | card = (struct snd_soc_card *)match->data; | 1123 | card = (struct snd_soc_card *)match->data; |
| 1109 | card->dev = &pdev->dev; | 1124 | card->dev = &pdev->dev; |
| 1110 | 1125 | ||
| 1126 | hdmi_codec = of_parse_phandle(pdev->dev.of_node, | ||
| 1127 | "mediatek,hdmi-codec", 0); | ||
| 1128 | |||
| 1111 | for_each_card_prelinks(card, i, dai_link) { | 1129 | for_each_card_prelinks(card, i, dai_link) { |
| 1112 | if (strcmp(dai_link->name, "I2S3") == 0) { | 1130 | if (strcmp(dai_link->name, "I2S3") == 0) { |
| 1113 | if (card == &mt8192_mt6359_rt1015_rt5682_card) { | 1131 | if (card == &mt8192_mt6359_rt1015_rt5682_card) { |
| @@ -1134,10 +1152,20 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 1134 | } | 1152 | } |
| 1135 | } | 1153 | } |
| 1136 | 1154 | ||
| 1155 | if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { | ||
| 1156 | dai_link->codecs->of_node = hdmi_codec; | ||
| 1157 | dai_link->ignore = 0; | ||
| 1158 | } | ||
| 1159 | |||
| 1137 | if (!dai_link->platforms->name) | 1160 | if (!dai_link->platforms->name) |
| 1138 | dai_link->platforms->of_node = platform_node; | 1161 | dai_link->platforms->of_node = platform_node; |
| 1139 | } | 1162 | } |
| 1140 | 1163 | ||
| 1164 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||
| 1165 | if (!priv) | ||
| 1166 | return -ENOMEM; | ||
| 1167 | snd_soc_card_set_drvdata(card, priv); | ||
| 1168 | |||
| 1141 | ret = mt8192_afe_gpio_init(&pdev->dev); | 1169 | ret = mt8192_afe_gpio_init(&pdev->dev); |
| 1142 | if (ret) { | 1170 | if (ret) { |
| 1143 | dev_err(&pdev->dev, "init gpio error %d\n", ret); | 1171 | dev_err(&pdev->dev, "init gpio error %d\n", ret); |
| @@ -124,7 +124,6 @@ const struct snd_soc_dai_ops aiu_fifo_i2s_dai_ops = { · 123 unmodified lines | |||
| 124 | .trigger = aiu_fifo_i2s_trigger, | 124 | .trigger = aiu_fifo_i2s_trigger, |
| 125 | .prepare = aiu_fifo_i2s_prepare, | 125 | .prepare = aiu_fifo_i2s_prepare, |
| 126 | .hw_params = aiu_fifo_i2s_hw_params, | 126 | .hw_params = aiu_fifo_i2s_hw_params, |
| 127 | .hw_free = aiu_fifo_hw_free, | ||
| 128 | .startup = aiu_fifo_startup, | 127 | .startup = aiu_fifo_startup, |
| 129 | .shutdown = aiu_fifo_shutdown, | 128 | .shutdown = aiu_fifo_shutdown, |
| 130 | }; | 129 | }; |
| @@ -158,7 +158,6 @@ const struct snd_soc_dai_ops aiu_fifo_spdif_dai_ops = { · 157 unmodified lines | |||
| 158 | .trigger = fifo_spdif_trigger, | 158 | .trigger = fifo_spdif_trigger, |
| 159 | .prepare = fifo_spdif_prepare, | 159 | .prepare = fifo_spdif_prepare, |
| 160 | .hw_params = fifo_spdif_hw_params, | 160 | .hw_params = fifo_spdif_hw_params, |
| 161 | .hw_free = aiu_fifo_hw_free, | ||
| 162 | .startup = aiu_fifo_startup, | 161 | .startup = aiu_fifo_startup, |
| 163 | .shutdown = aiu_fifo_shutdown, | 162 | .shutdown = aiu_fifo_shutdown, |
| 164 | }; | 163 | }; |
| @@ -99,11 +99,6 @@ int aiu_fifo_hw_params(struct snd_pcm_substream *substream, · 98 unmodified lines | |||
| 99 | struct snd_soc_component *component = dai->component; | 99 | struct snd_soc_component *component = dai->component; |
| 100 | struct aiu_fifo *fifo = dai->playback_dma_data; | 100 | struct aiu_fifo *fifo = dai->playback_dma_data; |
| 101 | dma_addr_t end; | 101 | dma_addr_t end; |
| 102 | int ret; | ||
| 103 | |||
| 104 | ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | ||
| 105 | if (ret < 0) | ||
| 106 | return ret; | ||
| 107 | 102 | ||
| 108 | /* Setup the fifo boundaries */ | 103 | /* Setup the fifo boundaries */ |
| 109 | end = runtime->dma_addr + runtime->dma_bytes - fifo->fifo_block; | 104 | end = runtime->dma_addr + runtime->dma_bytes - fifo->fifo_block; |
| @@ -124,12 +119,6 @@ int aiu_fifo_hw_params(struct snd_pcm_substream *substream, · 14 unmodified lines | |||
| 124 | return 0; | 119 | return 0; |
| 125 | } | 120 | } |
| 126 | 121 | ||
| 127 | int aiu_fifo_hw_free(struct snd_pcm_substream *substream, | ||
| 128 | struct snd_soc_dai *dai) | ||
| 129 | { | ||
| 130 | return snd_pcm_lib_free_pages(substream); | ||
| 131 | } | ||
| 132 | |||
| 133 | static irqreturn_t aiu_fifo_isr(int irq, void *dev_id) | 122 | static irqreturn_t aiu_fifo_isr(int irq, void *dev_id) |
| 134 | { | 123 | { |
| 135 | struct snd_pcm_substream *playback = dev_id; | 124 | struct snd_pcm_substream *playback = dev_id; |
| @@ -187,15 +176,12 @@ void aiu_fifo_shutdown(struct snd_pcm_substream *substream, · 51 unmodified lines | |||
| 187 | int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, | 176 | int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 188 | struct snd_soc_dai *dai) | 177 | struct snd_soc_dai *dai) |
| 189 | { | 178 | { |
| 190 | struct snd_pcm_substream *substream = | ||
| 191 | rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | ||
| 192 | struct snd_card *card = rtd->card->snd_card; | 179 | struct snd_card *card = rtd->card->snd_card; |
| 193 | struct aiu_fifo *fifo = dai->playback_dma_data; | 180 | struct aiu_fifo *fifo = dai->playback_dma_data; |
| 194 | size_t size = fifo->pcm->buffer_bytes_max; | 181 | size_t size = fifo->pcm->buffer_bytes_max; |
| 195 | 182 | ||
| 196 | snd_pcm_lib_preallocate_pages(substream, | 183 | snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, |
| 197 | SNDRV_DMA_TYPE_DEV, | 184 | card->dev, size, size); |
| 198 | card->dev, size, size); | ||
| 199 | 185 | ||
| 200 | return 0; | 186 | return 0; |
| 201 | } | 187 | } |
| @@ -353,7 +353,7 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { · 352 unmodified lines | |||
| 353 | .rates = PXA2XX_I2S_RATES, | 353 | .rates = PXA2XX_I2S_RATES, |
| 354 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 354 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
| 355 | .ops = &pxa_i2s_dai_ops, | 355 | .ops = &pxa_i2s_dai_ops, |
| 356 | .symmetric_rates = 1, | 356 | .symmetric_rate = 1, |
| 357 | }; | 357 | }; |
| 358 | 358 | ||
| 359 | static const struct snd_soc_component_driver pxa_i2s_component = { | 359 | static const struct snd_soc_component_driver pxa_i2s_component = { |
| @@ -250,7 +250,7 @@ static struct lpass_variant apq8016_data = { · 249 unmodified lines | |||
| 250 | .micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000), | 250 | .micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000), |
| 251 | .micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000), | 251 | .micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000), |
| 252 | .wssrc = REG_FIELD_ID(0x1000, 2, 2, 4, 0x1000), | 252 | .wssrc = REG_FIELD_ID(0x1000, 2, 2, 4, 0x1000), |
| 253 | .bitwidth = REG_FIELD_ID(0x1000, 0, 0, 4, 0x1000), | 253 | .bitwidth = REG_FIELD_ID(0x1000, 0, 1, 4, 0x1000), |
| 254 | 254 | ||
| 255 | .rdma_dyncclk = REG_FIELD_ID(0x8400, 12, 12, 2, 0x1000), | 255 | .rdma_dyncclk = REG_FIELD_ID(0x8400, 12, 12, 2, 0x1000), |
| 256 | .rdma_bursten = REG_FIELD_ID(0x8400, 11, 11, 2, 0x1000), | 256 | .rdma_bursten = REG_FIELD_ID(0x8400, 11, 11, 2, 0x1000), |
| @@ -286,16 +286,12 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, · 285 unmodified lines | |||
| 286 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", | 286 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", |
| 287 | ret); | 287 | ret); |
| 288 | 288 | ||
| 289 | if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) { | 289 | ret = clk_enable(drvdata->mi2s_bit_clk[id]); |
| 290 | ret = clk_enable(drvdata->mi2s_bit_clk[id]); | 290 | if (ret) { |
| 291 | if (ret) { | 291 | dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); |
| 292 | dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); | 292 | clk_disable(drvdata->mi2s_osr_clk[id]); |
| 293 | clk_disable(drvdata->mi2s_osr_clk[id]); | 293 | return ret; |
| 294 | return ret; | ||
| 295 | } | ||
| 296 | drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE; | ||
| 297 | } | 294 | } |
| 298 | |||
| 299 | break; | 295 | break; |
| 300 | case SNDRV_PCM_TRIGGER_STOP: | 296 | case SNDRV_PCM_TRIGGER_STOP: |
| 301 | case SNDRV_PCM_TRIGGER_SUSPEND: | 297 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| @@ -310,10 +306,9 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, · 8 unmodified lines | |||
| 310 | if (ret) | 306 | if (ret) |
| 311 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", | 307 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", |
| 312 | ret); | 308 | ret); |
| 313 | if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) { | 309 | |
| 314 | clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); | 310 | clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); |
| 315 | drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE; | 311 | |
| 316 | } | ||
| 317 | break; | 312 | break; |
| 318 | } | 313 | } |
| 319 | 314 | ||
| @@ -480,6 +475,7 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) · 160 unmodified lines | |||
| 480 | } | 475 | } |
| 481 | 476 | ||
| 482 | static struct regmap_config lpass_cpu_regmap_config = { | 477 | static struct regmap_config lpass_cpu_regmap_config = { |
| 478 | .name = "lpass_cpu", | ||
| 483 | .reg_bits = 32, | 479 | .reg_bits = 32, |
| 484 | .reg_stride = 4, | 480 | .reg_stride = 4, |
| 485 | .val_bits = 32, | 481 | .val_bits = 32, |
| @@ -599,7 +595,7 @@ static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg) · 113 unmodified lines | |||
| 599 | return true; | 595 | return true; |
| 600 | } | 596 | } |
| 601 | 597 | ||
| 602 | for (i = 0; i < v->rdma_channels; ++i) { | 598 | for (i = 0; i < v->hdmi_rdma_channels; ++i) { |
| 603 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) | 599 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) |
| 604 | return true; | 600 | return true; |
| 605 | if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) | 601 | if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) |
| @@ -645,7 +641,7 @@ static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg) · 39 unmodified lines | |||
| 645 | if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v)) | 641 | if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v)) |
| 646 | return true; | 642 | return true; |
| 647 | 643 | ||
| 648 | for (i = 0; i < v->rdma_channels; ++i) { | 644 | for (i = 0; i < v->hdmi_rdma_channels; ++i) { |
| 649 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) | 645 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) |
| 650 | return true; | 646 | return true; |
| 651 | if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) | 647 | if (reg == LPAIF_HDMI_RDMABASE_REG(v, i)) |
| @@ -672,7 +668,7 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg) · 20 unmodified lines | |||
| 672 | if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) | 668 | if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) |
| 673 | return true; | 669 | return true; |
| 674 | 670 | ||
| 675 | for (i = 0; i < v->rdma_channels; ++i) { | 671 | for (i = 0; i < v->hdmi_rdma_channels; ++i) { |
| 676 | if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) | 672 | if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) |
| 677 | return true; | 673 | return true; |
| 678 | } | 674 | } |
| @@ -680,6 +676,7 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg) · 1 unmodified line | |||
| 680 | } | 676 | } |
| 681 | 677 | ||
| 682 | static struct regmap_config lpass_hdmi_regmap_config = { | 678 | static struct regmap_config lpass_hdmi_regmap_config = { |
| 679 | .name = "lpass_hdmi", | ||
| 683 | .reg_bits = 32, | 680 | .reg_bits = 32, |
| 684 | .reg_stride = 4, | 681 | .reg_stride = 4, |
| 685 | .val_bits = 32, | 682 | .val_bits = 32, |
| @@ -748,7 +745,6 @@ static void of_lpass_cpu_parse_dai_data(struct device *dev, · 62 unmodified lines | |||
| 748 | } | 745 | } |
| 749 | if (id == LPASS_DP_RX) { | 746 | if (id == LPASS_DP_RX) { |
| 750 | data->hdmi_port_enable = 1; | 747 | data->hdmi_port_enable = 1; |
| 751 | dev_err(dev, "HDMI Port is enabled: %d\n", id); | ||
| 752 | } else { | 748 | } else { |
| 753 | data->mi2s_playback_sd_mode[id] = | 749 | data->mi2s_playback_sd_mode[id] = |
| 754 | of_lpass_cpu_parse_sd_lines(dev, node, | 750 | of_lpass_cpu_parse_sd_lines(dev, node, |
| @@ -793,11 +789,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) · 38 unmodified lines | |||
| 793 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); | 789 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); |
| 794 | 790 | ||
| 795 | drvdata->lpaif = devm_ioremap_resource(dev, res); | 791 | drvdata->lpaif = devm_ioremap_resource(dev, res); |
| 796 | if (IS_ERR((void const __force *)drvdata->lpaif)) { | 792 | if (IS_ERR(drvdata->lpaif)) |
| 797 | dev_err(dev, "error mapping reg resource: %ld\n", | 793 | return PTR_ERR(drvdata->lpaif); |
| 798 | PTR_ERR((void const __force *)drvdata->lpaif)); | ||
| 799 | return PTR_ERR((void const __force *)drvdata->lpaif); | ||
| 800 | } | ||
| 801 | 794 | ||
| 802 | lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, | 795 | lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, |
| 803 | variant->wrdma_channels + | 796 | variant->wrdma_channels + |
| @@ -815,14 +808,11 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 815 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif"); | 808 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif"); |
| 816 | 809 | ||
| 817 | drvdata->hdmiif = devm_ioremap_resource(dev, res); | 810 | drvdata->hdmiif = devm_ioremap_resource(dev, res); |
| 818 | if (IS_ERR((void const __force *)drvdata->hdmiif)) { | 811 | if (IS_ERR(drvdata->hdmiif)) |
| 819 | dev_err(dev, "error mapping reg resource: %ld\n", | 812 | return PTR_ERR(drvdata->hdmiif); |
| 820 | PTR_ERR((void const __force *)drvdata->hdmiif)); | ||
| 821 | return PTR_ERR((void const __force *)drvdata->hdmiif); | ||
| 822 | } | ||
| 823 | 813 | ||
| 824 | lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, | 814 | lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, |
| 825 | variant->hdmi_rdma_channels); | 815 | variant->hdmi_rdma_channels - 1); |
| 826 | drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif, | 816 | drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif, |
| 827 | &lpass_hdmi_regmap_config); | 817 | &lpass_hdmi_regmap_config); |
| 828 | if (IS_ERR(drvdata->hdmiif_map)) { | 818 | if (IS_ERR(drvdata->hdmiif_map)) { |
| @@ -866,7 +856,6 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) · 37 unmodified lines | |||
| 866 | PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); | 856 | PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); |
| 867 | return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); | 857 | return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); |
| 868 | } | 858 | } |
| 869 | drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE; | ||
| 870 | } | 859 | } |
| 871 | 860 | ||
| 872 | /* Allocation for i2sctl regmap fields */ | 861 | /* Allocation for i2sctl regmap fields */ |
| @@ -60,9 +60,6 @@ · 59 unmodified lines | |||
| 60 | #define LPAIF_I2SCTL_BITWIDTH_24 1 | 60 | #define LPAIF_I2SCTL_BITWIDTH_24 1 |
| 61 | #define LPAIF_I2SCTL_BITWIDTH_32 2 | 61 | #define LPAIF_I2SCTL_BITWIDTH_32 2 |
| 62 | 62 | ||
| 63 | #define LPAIF_BIT_CLK_DISABLE 0 | ||
| 64 | #define LPAIF_BIT_CLK_ENABLE 1 | ||
| 65 | |||
| 66 | #define LPAIF_I2SCTL_RESET_STATE 0x003C0004 | 63 | #define LPAIF_I2SCTL_RESET_STATE 0x003C0004 |
| 67 | #define LPAIF_DMACTL_RESET_STATE 0x00200000 | 64 | #define LPAIF_DMACTL_RESET_STATE 0x00200000 |
| 68 | 65 | ||
| @@ -171,7 +171,7 @@ static struct lpass_variant sc7180_data = { · 170 unmodified lines | |||
| 171 | .rdma_channels = 5, | 171 | .rdma_channels = 5, |
| 172 | .hdmi_rdma_reg_base = 0x64000, | 172 | .hdmi_rdma_reg_base = 0x64000, |
| 173 | .hdmi_rdma_reg_stride = 0x1000, | 173 | .hdmi_rdma_reg_stride = 0x1000, |
| 174 | .hdmi_rdma_channels = 3, | 174 | .hdmi_rdma_channels = 4, |
| 175 | .dmactl_audif_start = 1, | 175 | .dmactl_audif_start = 1, |
| 176 | .wrdma_reg_base = 0x18000, | 176 | .wrdma_reg_base = 0x18000, |
| 177 | .wrdma_reg_stride = 0x1000, | 177 | .wrdma_reg_stride = 0x1000, |
| @@ -68,7 +68,6 @@ struct lpass_data { · 67 unmodified lines | |||
| 68 | unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; | 68 | unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; |
| 69 | unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; | 69 | unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; |
| 70 | int hdmi_port_enable; | 70 | int hdmi_port_enable; |
| 71 | int bit_clk_state[LPASS_MAX_MI2S_PORTS]; | ||
| 72 | 71 | ||
| 73 | /* low-power audio interface (LPAIF) registers */ | 72 | /* low-power audio interface (LPAIF) registers */ |
| 74 | void __iomem *lpaif; | 73 | void __iomem *lpaif; |
| @@ -1707,7 +1707,7 @@ int q6afe_vote_lpass_core_hw(struct device *dev, uint32_t hw_block_id, · 1706 unmodified lines | |||
| 1707 | pkt->hdr.token = hw_block_id; | 1707 | pkt->hdr.token = hw_block_id; |
| 1708 | pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; | 1708 | pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; |
| 1709 | vote_cfg->hw_block_id = hw_block_id; | 1709 | vote_cfg->hw_block_id = hw_block_id; |
| 1710 | strlcpy(vote_cfg->client_name, client_name, | 1710 | strscpy(vote_cfg->client_name, client_name, |
| 1711 | sizeof(vote_cfg->client_name)); | 1711 | sizeof(vote_cfg->client_name)); |
| 1712 | 1712 | ||
| 1713 | ret = afe_apr_send_pkt(afe, pkt, NULL, | 1713 | ret = afe_apr_send_pkt(afe, pkt, NULL, |
| @@ -1233,6 +1233,25 @@ static void q6asm_dai_pcm_free(struct snd_soc_component *component, · 1232 unmodified lines | |||
| 1233 | } | 1233 | } |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | static const struct snd_soc_dapm_widget q6asm_dapm_widgets[] = { | ||
| 1237 | SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1238 | SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1239 | SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1240 | SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1241 | SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1242 | SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1243 | SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1244 | SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 1245 | SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1246 | SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1247 | SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1248 | SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1249 | SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1250 | SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1251 | SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1252 | SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 1253 | }; | ||
| 1254 | |||
| 1236 | static const struct snd_soc_component_driver q6asm_fe_dai_component = { | 1255 | static const struct snd_soc_component_driver q6asm_fe_dai_component = { |
| 1237 | .name = DRV_NAME, | 1256 | .name = DRV_NAME, |
| 1238 | .open = q6asm_dai_open, | 1257 | .open = q6asm_dai_open, |
| @@ -1245,6 +1264,8 @@ static const struct snd_soc_component_driver q6asm_fe_dai_component = { · 6 unmodified lines | |||
| 1245 | .pcm_construct = q6asm_dai_pcm_new, | 1264 | .pcm_construct = q6asm_dai_pcm_new, |
| 1246 | .pcm_destruct = q6asm_dai_pcm_free, | 1265 | .pcm_destruct = q6asm_dai_pcm_free, |
| 1247 | .compress_ops = &q6asm_dai_compress_ops, | 1266 | .compress_ops = &q6asm_dai_compress_ops, |
| 1267 | .dapm_widgets = q6asm_dapm_widgets, | ||
| 1268 | .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), | ||
| 1248 | }; | 1269 | }; |
| 1249 | 1270 | ||
| 1250 | static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { | 1271 | static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { |
| @@ -491,7 +491,7 @@ static int __q6asm_memory_map_regions(struct audio_client *ac, int dir, · 490 unmodified lines | |||
| 491 | * | 491 | * |
| 492 | * @dir: direction of audio stream | 492 | * @dir: direction of audio stream |
| 493 | * @ac: audio client instanace | 493 | * @ac: audio client instanace |
| 494 | * @phys: physcial address that needs mapping. | 494 | * @phys: physical address that needs mapping. |
| 495 | * @period_sz: audio period size | 495 | * @period_sz: audio period size |
| 496 | * @periods: number of periods | 496 | * @periods: number of periods |
| 497 | * | 497 | * |
| @@ -713,24 +713,6 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { · 712 unmodified lines | |||
| 713 | Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) }; | 713 | Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) }; |
| 714 | 714 | ||
| 715 | static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { | 715 | static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { |
| 716 | /* Frontend AIF */ | ||
| 717 | SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0), | ||
| 718 | SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0), | ||
| 719 | SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0), | ||
| 720 | SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0), | ||
| 721 | SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0), | ||
| 722 | SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0), | ||
| 723 | SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0), | ||
| 724 | SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0), | ||
| 725 | SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0), | ||
| 726 | SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0), | ||
| 727 | SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0), | ||
| 728 | SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0), | ||
| 729 | SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0), | ||
| 730 | SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), | ||
| 731 | SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, 0, 0, 0), | ||
| 732 | SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), | ||
| 733 | |||
| 734 | /* Mixer definitions */ | 716 | /* Mixer definitions */ |
| 735 | SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, | 717 | SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, |
| 736 | hdmi_mixer_controls, | 718 | hdmi_mixer_controls, |
| @@ -373,7 +373,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, · 372 unmodified lines | |||
| 373 | I2S_DMACR_RDL(16)); | 373 | I2S_DMACR_RDL(16)); |
| 374 | 374 | ||
| 375 | val = I2S_CKR_TRCM_TXRX; | 375 | val = I2S_CKR_TRCM_TXRX; |
| 376 | if (dai->driver->symmetric_rates && rtd->dai_link->symmetric_rates) | 376 | if (dai->driver->symmetric_rate && rtd->dai_link->symmetric_rate) |
| 377 | val = I2S_CKR_TRCM_TXONLY; | 377 | val = I2S_CKR_TRCM_TXONLY; |
| 378 | 378 | ||
| 379 | regmap_update_bits(i2s->regmap, I2S_CKR, | 379 | regmap_update_bits(i2s->regmap, I2S_CKR, |
| @@ -471,7 +471,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { · 91 unmodified lines | |||
| 471 | SNDRV_PCM_FMTBIT_S32_LE), | 471 | SNDRV_PCM_FMTBIT_S32_LE), |
| 472 | }, | 472 | }, |
| 473 | .ops = &rockchip_i2s_dai_ops, | 473 | .ops = &rockchip_i2s_dai_ops, |
| 474 | .symmetric_rates = 1, | 474 | .symmetric_rate = 1, |
| 475 | }; | 475 | }; |
| 476 | 476 | ||
| 477 | static const struct snd_soc_component_driver rockchip_i2s_component = { | 477 | static const struct snd_soc_component_driver rockchip_i2s_component = { |
| @@ -338,7 +338,7 @@ static struct snd_soc_dai_driver rockchip_pdm_dai = { · 337 unmodified lines | |||
| 338 | .formats = ROCKCHIP_PDM_FORMATS, | 338 | .formats = ROCKCHIP_PDM_FORMATS, |
| 339 | }, | 339 | }, |
| 340 | .ops = &rockchip_pdm_dai_ops, | 340 | .ops = &rockchip_pdm_dai_ops, |
| 341 | .symmetric_rates = 1, | 341 | .symmetric_rate = 1, |
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | static const struct snd_soc_component_driver rockchip_pdm_component = { | 344 | static const struct snd_soc_component_driver rockchip_pdm_component = { |
| @@ -1175,7 +1175,7 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, · 1174 unmodified lines | |||
| 1175 | dai_drv->probe = samsung_i2s_dai_probe; | 1175 | dai_drv->probe = samsung_i2s_dai_probe; |
| 1176 | dai_drv->remove = samsung_i2s_dai_remove; | 1176 | dai_drv->remove = samsung_i2s_dai_remove; |
| 1177 | 1177 | ||
| 1178 | dai_drv->symmetric_rates = 1; | 1178 | dai_drv->symmetric_rate = 1; |
| 1179 | dai_drv->ops = &samsung_i2s_dai_ops; | 1179 | dai_drv->ops = &samsung_i2s_dai_ops; |
| 1180 | 1180 | ||
| 1181 | dai_drv->playback.channels_min = 1; | 1181 | dai_drv->playback.channels_min = 1; |
| @@ -452,7 +452,7 @@ static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) · 451 unmodified lines | |||
| 452 | #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 | 452 | #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 |
| 453 | 453 | ||
| 454 | #define S3C_PCM_DAI_DECLARE \ | 454 | #define S3C_PCM_DAI_DECLARE \ |
| 455 | .symmetric_rates = 1, \ | 455 | .symmetric_rate = 1, \ |
| 456 | .probe = s3c_pcm_dai_probe, \ | 456 | .probe = s3c_pcm_dai_probe, \ |
| 457 | .ops = &s3c_pcm_dai_ops, \ | 457 | .ops = &s3c_pcm_dai_ops, \ |
| 458 | .playback = { \ | 458 | .playback = { \ |
| @@ -1320,8 +1320,8 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, · 1319 unmodified lines | |||
| 1320 | 1320 | ||
| 1321 | if (rsnd_ssi_is_pin_sharing(io_capture) || | 1321 | if (rsnd_ssi_is_pin_sharing(io_capture) || |
| 1322 | rsnd_ssi_is_pin_sharing(io_playback)) { | 1322 | rsnd_ssi_is_pin_sharing(io_playback)) { |
| 1323 | /* should have symmetric_rates if pin sharing */ | 1323 | /* should have symmetric_rate if pin sharing */ |
| 1324 | drv->symmetric_rates = 1; | 1324 | drv->symmetric_rate = 1; |
| 1325 | } | 1325 | } |
| 1326 | 1326 | ||
| 1327 | dev_dbg(dev, "%s (%s/%s)\n", rdai->name, | 1327 | dev_dbg(dev, "%s (%s/%s)\n", rdai->name, |
| @@ -1472,7 +1472,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, · 144 unmodified lines | |||
| 1472 | uinfo->value.enumerated.items = cfg->max; | 1472 | uinfo->value.enumerated.items = cfg->max; |
| 1473 | if (uinfo->value.enumerated.item >= cfg->max) | 1473 | if (uinfo->value.enumerated.item >= cfg->max) |
| 1474 | uinfo->value.enumerated.item = cfg->max - 1; | 1474 | uinfo->value.enumerated.item = cfg->max - 1; |
| 1475 | strlcpy(uinfo->value.enumerated.name, | 1475 | strscpy(uinfo->value.enumerated.name, |
| 1476 | cfg->texts[uinfo->value.enumerated.item], | 1476 | cfg->texts[uinfo->value.enumerated.item], |
| 1477 | sizeof(uinfo->value.enumerated.name)); | 1477 | sizeof(uinfo->value.enumerated.name)); |
| 1478 | } else { | 1478 | } else { |
| @@ -169,7 +169,7 @@ static inline u32 siu_read32(u32 __iomem *addr) · 168 unmodified lines | |||
| 169 | #define SIU_BRGBSEL (0x108 / sizeof(u32)) | 169 | #define SIU_BRGBSEL (0x108 / sizeof(u32)) |
| 170 | #define SIU_BRRB (0x10c / sizeof(u32)) | 170 | #define SIU_BRRB (0x10c / sizeof(u32)) |
| 171 | 171 | ||
| 172 | extern struct snd_soc_component_driver siu_component; | 172 | extern const struct snd_soc_component_driver siu_component; |
| 173 | extern struct siu_info *siu_i2s_data; | 173 | extern struct siu_info *siu_i2s_data; |
| 174 | 174 | ||
| 175 | int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); | 175 | int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); |
| @@ -543,7 +543,7 @@ static void siu_pcm_free(struct snd_soc_component *component, · 542 unmodified lines | |||
| 543 | dev_dbg(pcm->card->dev, "%s\n", __func__); | 543 | dev_dbg(pcm->card->dev, "%s\n", __func__); |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | struct const snd_soc_component_driver siu_component = { | 546 | const struct snd_soc_component_driver siu_component = { |
| 547 | .name = DRV_NAME, | 547 | .name = DRV_NAME, |
| 548 | .open = siu_pcm_open, | 548 | .open = siu_pcm_open, |
| 549 | .close = siu_pcm_close, | 549 | .close = siu_pcm_close, |
| @@ -1,21 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | config SND_SOC_SIRF | ||
| 3 | tristate "SoC Audio for the SiRF SoC chips" | ||
| 4 | depends on ARCH_SIRF || COMPILE_TEST | ||
| 5 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
| 6 | |||
| 7 | config SND_SOC_SIRF_AUDIO | ||
| 8 | tristate "SoC Audio support for SiRF internal audio codec" | ||
| 9 | depends on SND_SOC_SIRF | ||
| 10 | select SND_SOC_SIRF_AUDIO_CODEC | ||
| 11 | select SND_SOC_SIRF_AUDIO_PORT | ||
| 12 | |||
| 13 | config SND_SOC_SIRF_AUDIO_PORT | ||
| 14 | select REGMAP_MMIO | ||
| 15 | tristate | ||
| 16 | |||
| 17 | config SND_SOC_SIRF_USP | ||
| 18 | tristate "SoC Audio (I2S protocol) for SiRF SoC USP interface" | ||
| 19 | depends on SND_SOC_SIRF | ||
| 20 | select REGMAP_MMIO | ||
| 21 | tristate | ||
| @@ -1,8 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | snd-soc-sirf-audio-objs := sirf-audio.o | ||
| 3 | snd-soc-sirf-audio-port-objs := sirf-audio-port.o | ||
| 4 | snd-soc-sirf-usp-objs := sirf-usp.o | ||
| 5 | |||
| 6 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o | ||
| 7 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o | ||
| 8 | obj-$(CONFIG_SND_SOC_SIRF_USP) += snd-soc-sirf-usp.o | ||
| @@ -1,86 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | /* | ||
| 3 | * SiRF Audio port driver | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
| 6 | */ | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <sound/soc.h> | ||
| 9 | #include <sound/dmaengine_pcm.h> | ||
| 10 | |||
| 11 | struct sirf_audio_port { | ||
| 12 | struct regmap *regmap; | ||
| 13 | struct snd_dmaengine_dai_dma_data playback_dma_data; | ||
| 14 | struct snd_dmaengine_dai_dma_data capture_dma_data; | ||
| 15 | }; | ||
| 16 | |||
| 17 | |||
| 18 | static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) | ||
| 19 | { | ||
| 20 | struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); | ||
| 21 | |||
| 22 | snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, | ||
| 23 | &port->capture_dma_data); | ||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | static struct snd_soc_dai_driver sirf_audio_port_dai = { | ||
| 28 | .probe = sirf_audio_port_dai_probe, | ||
| 29 | .name = "sirf-audio-port", | ||
| 30 | .id = 0, | ||
| 31 | .playback = { | ||
| 32 | .channels_min = 2, | ||
| 33 | .channels_max = 2, | ||
| 34 | .rates = SNDRV_PCM_RATE_48000, | ||
| 35 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 36 | }, | ||
| 37 | .capture = { | ||
| 38 | .channels_min = 1, | ||
| 39 | .channels_max = 2, | ||
| 40 | .rates = SNDRV_PCM_RATE_48000, | ||
| 41 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 42 | }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static const struct snd_soc_component_driver sirf_audio_port_component = { | ||
| 46 | .name = "sirf-audio-port", | ||
| 47 | }; | ||
| 48 | |||
| 49 | static int sirf_audio_port_probe(struct platform_device *pdev) | ||
| 50 | { | ||
| 51 | int ret; | ||
| 52 | struct sirf_audio_port *port; | ||
| 53 | |||
| 54 | port = devm_kzalloc(&pdev->dev, | ||
| 55 | sizeof(struct sirf_audio_port), GFP_KERNEL); | ||
| 56 | if (!port) | ||
| 57 | return -ENOMEM; | ||
| 58 | |||
| 59 | ret = devm_snd_soc_register_component(&pdev->dev, | ||
| 60 | &sirf_audio_port_component, &sirf_audio_port_dai, 1); | ||
| 61 | if (ret) | ||
| 62 | return ret; | ||
| 63 | |||
| 64 | platform_set_drvdata(pdev, port); | ||
| 65 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); | ||
| 66 | } | ||
| 67 | |||
| 68 | static const struct of_device_id sirf_audio_port_of_match[] = { | ||
| 69 | { .compatible = "sirf,audio-port", }, | ||
| 70 | {} | ||
| 71 | }; | ||
| 72 | MODULE_DEVICE_TABLE(of, sirf_audio_port_of_match); | ||
| 73 | |||
| 74 | static struct platform_driver sirf_audio_port_driver = { | ||
| 75 | .driver = { | ||
| 76 | .name = "sirf-audio-port", | ||
| 77 | .of_match_table = sirf_audio_port_of_match, | ||
| 78 | }, | ||
| 79 | .probe = sirf_audio_port_probe, | ||
| 80 | }; | ||
| 81 | |||
| 82 | module_platform_driver(sirf_audio_port_driver); | ||
| 83 | |||
| 84 | MODULE_DESCRIPTION("SiRF Audio Port driver"); | ||
| 85 | MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); | ||
| 86 | MODULE_LICENSE("GPL v2"); | ||
| @@ -1,160 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | /* | ||
| 3 | * SiRF audio card driver | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/platform_device.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/of.h> | ||
| 11 | #include <linux/gpio.h> | ||
| 12 | #include <linux/of_gpio.h> | ||
| 13 | #include <sound/core.h> | ||
| 14 | #include <sound/pcm.h> | ||
| 15 | #include <sound/soc.h> | ||
| 16 | |||
| 17 | struct sirf_audio_card { | ||
| 18 | unsigned int gpio_hp_pa; | ||
| 19 | unsigned int gpio_spk_pa; | ||
| 20 | }; | ||
| 21 | |||
| 22 | static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w, | ||
| 23 | struct snd_kcontrol *ctrl, int event) | ||
| 24 | { | ||
| 25 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
| 26 | struct snd_soc_card *card = dapm->card; | ||
| 27 | struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); | ||
| 28 | int on = !SND_SOC_DAPM_EVENT_OFF(event); | ||
| 29 | |||
| 30 | if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) | ||
| 31 | gpio_set_value(sirf_audio_card->gpio_hp_pa, on); | ||
| 32 | return 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w, | ||
| 36 | struct snd_kcontrol *ctrl, int event) | ||
| 37 | { | ||
| 38 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
| 39 | struct snd_soc_card *card = dapm->card; | ||
| 40 | struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); | ||
| 41 | int on = !SND_SOC_DAPM_EVENT_OFF(event); | ||
| 42 | |||
| 43 | if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) | ||
| 44 | gpio_set_value(sirf_audio_card->gpio_spk_pa, on); | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = { | ||
| 49 | SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event), | ||
| 50 | SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event), | ||
| 51 | SND_SOC_DAPM_MIC("Ext Mic", NULL), | ||
| 52 | }; | ||
| 53 | |||
| 54 | static const struct snd_soc_dapm_route intercon[] = { | ||
| 55 | {"Hp", NULL, "HPOUTL"}, | ||
| 56 | {"Hp", NULL, "HPOUTR"}, | ||
| 57 | {"Ext Spk", NULL, "SPKOUT"}, | ||
| 58 | {"MICIN1", NULL, "Mic Bias"}, | ||
| 59 | {"Mic Bias", NULL, "Ext Mic"}, | ||
| 60 | }; | ||
| 61 | |||
| 62 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
| 63 | SND_SOC_DAILINK_DEFS(sirf, | ||
| 64 | DAILINK_COMP_ARRAY(COMP_EMPTY()), | ||
| 65 | DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "sirf-audio-codec")), | ||
| 66 | DAILINK_COMP_ARRAY(COMP_EMPTY())); | ||
| 67 | |||
| 68 | static struct snd_soc_dai_link sirf_audio_dai_link[] = { | ||
| 69 | { | ||
| 70 | .name = "SiRF audio card", | ||
| 71 | .stream_name = "SiRF audio HiFi", | ||
| 72 | SND_SOC_DAILINK_REG(sirf), | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | |||
| 76 | /* Audio machine driver */ | ||
| 77 | static struct snd_soc_card snd_soc_sirf_audio_card = { | ||
| 78 | .name = "SiRF audio card", | ||
| 79 | .owner = THIS_MODULE, | ||
| 80 | .dai_link = sirf_audio_dai_link, | ||
| 81 | .num_links = ARRAY_SIZE(sirf_audio_dai_link), | ||
| 82 | .dapm_widgets = sirf_audio_dapm_widgets, | ||
| 83 | .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets), | ||
| 84 | .dapm_routes = intercon, | ||
| 85 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
| 86 | }; | ||
| 87 | |||
| 88 | static int sirf_audio_probe(struct platform_device *pdev) | ||
| 89 | { | ||
| 90 | struct snd_soc_card *card = &snd_soc_sirf_audio_card; | ||
| 91 | struct sirf_audio_card *sirf_audio_card; | ||
| 92 | int ret; | ||
| 93 | |||
| 94 | sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card), | ||
| 95 | GFP_KERNEL); | ||
| 96 | if (sirf_audio_card == NULL) | ||
| 97 | return -ENOMEM; | ||
| 98 | |||
| 99 | sirf_audio_dai_link[0].cpus->of_node = | ||
| 100 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); | ||
| 101 | sirf_audio_dai_link[0].platforms->of_node = | ||
| 102 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); | ||
| 103 | sirf_audio_dai_link[0].codecs->of_node = | ||
| 104 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0); | ||
| 105 | sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node, | ||
| 106 | "spk-pa-gpios", 0); | ||
| 107 | sirf_audio_card->gpio_hp_pa = of_get_named_gpio(pdev->dev.of_node, | ||
| 108 | "hp-pa-gpios", 0); | ||
| 109 | if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) { | ||
| 110 | ret = devm_gpio_request_one(&pdev->dev, | ||
| 111 | sirf_audio_card->gpio_spk_pa, | ||
| 112 | GPIOF_OUT_INIT_LOW, "SPA_PA_SD"); | ||
| 113 | if (ret) { | ||
| 114 | dev_err(&pdev->dev, | ||
| 115 | "Failed to request GPIO_%d for reset: %d\n", | ||
| 116 | sirf_audio_card->gpio_spk_pa, ret); | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) { | ||
| 121 | ret = devm_gpio_request_one(&pdev->dev, | ||
| 122 | sirf_audio_card->gpio_hp_pa, | ||
| 123 | GPIOF_OUT_INIT_LOW, "HP_PA_SD"); | ||
| 124 | if (ret) { | ||
| 125 | dev_err(&pdev->dev, | ||
| 126 | "Failed to request GPIO_%d for reset: %d\n", | ||
| 127 | sirf_audio_card->gpio_hp_pa, ret); | ||
| 128 | return ret; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | card->dev = &pdev->dev; | ||
| 133 | snd_soc_card_set_drvdata(card, sirf_audio_card); | ||
| 134 | |||
| 135 | ret = devm_snd_soc_register_card(&pdev->dev, card); | ||
| 136 | if (ret) | ||
| 137 | dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); | ||
| 138 | |||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | static const struct of_device_id sirf_audio_of_match[] = { | ||
| 143 | {.compatible = "sirf,sirf-audio-card", }, | ||
| 144 | { }, | ||
| 145 | }; | ||
| 146 | MODULE_DEVICE_TABLE(of, sirf_audio_of_match); | ||
| 147 | |||
| 148 | static struct platform_driver sirf_audio_driver = { | ||
| 149 | .driver = { | ||
| 150 | .name = "sirf-audio-card", | ||
| 151 | .pm = &snd_soc_pm_ops, | ||
| 152 | .of_match_table = sirf_audio_of_match, | ||
| 153 | }, | ||
| 154 | .probe = sirf_audio_probe, | ||
| 155 | }; | ||
| 156 | module_platform_driver(sirf_audio_driver); | ||
| 157 | |||
| 158 | MODULE_AUTHOR("RongJun Ying <RongJun.Ying@csr.com>"); | ||
| 159 | MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver"); | ||
| 160 | MODULE_LICENSE("GPL v2"); | ||
| @@ -1,435 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | /* | ||
| 3 | * SiRF USP in I2S/DSP mode | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
| 6 | */ | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <linux/io.h> | ||
| 9 | #include <linux/of.h> | ||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/pm_runtime.h> | ||
| 12 | #include <sound/soc.h> | ||
| 13 | #include <sound/pcm_params.h> | ||
| 14 | #include <sound/dmaengine_pcm.h> | ||
| 15 | |||
| 16 | #include "sirf-usp.h" | ||
| 17 | |||
| 18 | struct sirf_usp { | ||
| 19 | struct regmap *regmap; | ||
| 20 | struct clk *clk; | ||
| 21 | u32 mode1_reg; | ||
| 22 | u32 mode2_reg; | ||
| 23 | int daifmt_format; | ||
| 24 | struct snd_dmaengine_dai_dma_data playback_dma_data; | ||
| 25 | struct snd_dmaengine_dai_dma_data capture_dma_data; | ||
| 26 | }; | ||
| 27 | |||
| 28 | static void sirf_usp_tx_enable(struct sirf_usp *usp) | ||
| 29 | { | ||
| 30 | regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, | ||
| 31 | USP_TX_FIFO_RESET, USP_TX_FIFO_RESET); | ||
| 32 | regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); | ||
| 33 | |||
| 34 | regmap_update_bits(usp->regmap, USP_TX_FIFO_OP, | ||
| 35 | USP_TX_FIFO_START, USP_TX_FIFO_START); | ||
| 36 | |||
| 37 | regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, | ||
| 38 | USP_TX_ENA, USP_TX_ENA); | ||
| 39 | } | ||
| 40 | |||
| 41 | static void sirf_usp_tx_disable(struct sirf_usp *usp) | ||
| 42 | { | ||
| 43 | regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, | ||
| 44 | USP_TX_ENA, ~USP_TX_ENA); | ||
| 45 | /* FIFO stop */ | ||
| 46 | regmap_write(usp->regmap, USP_TX_FIFO_OP, 0); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void sirf_usp_rx_enable(struct sirf_usp *usp) | ||
| 50 | { | ||
| 51 | regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, | ||
| 52 | USP_RX_FIFO_RESET, USP_RX_FIFO_RESET); | ||
| 53 | regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); | ||
| 54 | |||
| 55 | regmap_update_bits(usp->regmap, USP_RX_FIFO_OP, | ||
| 56 | USP_RX_FIFO_START, USP_RX_FIFO_START); | ||
| 57 | |||
| 58 | regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, | ||
| 59 | USP_RX_ENA, USP_RX_ENA); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void sirf_usp_rx_disable(struct sirf_usp *usp) | ||
| 63 | { | ||
| 64 | regmap_update_bits(usp->regmap, USP_TX_RX_ENABLE, | ||
| 65 | USP_RX_ENA, ~USP_RX_ENA); | ||
| 66 | /* FIFO stop */ | ||
| 67 | regmap_write(usp->regmap, USP_RX_FIFO_OP, 0); | ||
| 68 | } | ||
| 69 | |||
| 70 | static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) | ||
| 71 | { | ||
| 72 | struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); | ||
| 73 | |||
| 74 | snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, | ||
| 75 | &usp->capture_dma_data); | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai, | ||
| 80 | unsigned int fmt) | ||
| 81 | { | ||
| 82 | struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); | ||
| 83 | |||
| 84 | /* set master/slave audio interface */ | ||
| 85 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 86 | case SND_SOC_DAIFMT_CBM_CFM: | ||
| 87 | break; | ||
| 88 | default: | ||
| 89 | dev_err(dai->dev, "Only CBM and CFM supported\n"); | ||
| 90 | return -EINVAL; | ||
| 91 | } | ||
| 92 | |||
| 93 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 94 | case SND_SOC_DAIFMT_I2S: | ||
| 95 | case SND_SOC_DAIFMT_DSP_A: | ||
| 96 | usp->daifmt_format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
| 97 | break; | ||
| 98 | default: | ||
| 99 | dev_err(dai->dev, "Only I2S and DSP_A format supported\n"); | ||
| 100 | return -EINVAL; | ||
| 101 | } | ||
| 102 | |||
| 103 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 104 | case SND_SOC_DAIFMT_NB_NF: | ||
| 105 | break; | ||
| 106 | case SND_SOC_DAIFMT_IB_NF: | ||
| 107 | usp->daifmt_format |= (fmt & SND_SOC_DAIFMT_INV_MASK); | ||
| 108 | break; | ||
| 109 | default: | ||
| 110 | return -EINVAL; | ||
| 111 | } | ||
| 112 | |||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static void sirf_usp_i2s_init(struct sirf_usp *usp) | ||
| 117 | { | ||
| 118 | /* Configure RISC mode */ | ||
| 119 | regmap_update_bits(usp->regmap, USP_RISC_DSP_MODE, | ||
| 120 | USP_RISC_DSP_SEL, ~USP_RISC_DSP_SEL); | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Configure DMA IO Length register | ||
| 124 | * Set no limit, USP can receive data continuously until it is diabled | ||
| 125 | */ | ||
| 126 | regmap_write(usp->regmap, USP_TX_DMA_IO_LEN, 0); | ||
| 127 | regmap_write(usp->regmap, USP_RX_DMA_IO_LEN, 0); | ||
| 128 | |||
| 129 | /* Configure Mode2 register */ | ||
| 130 | regmap_write(usp->regmap, USP_MODE2, (1 << USP_RXD_DELAY_LEN_OFFSET) | | ||
| 131 | (0 << USP_TXD_DELAY_LEN_OFFSET) | | ||
| 132 | USP_TFS_CLK_SLAVE_MODE | USP_RFS_CLK_SLAVE_MODE); | ||
| 133 | |||
| 134 | /* Configure Mode1 register */ | ||
| 135 | regmap_write(usp->regmap, USP_MODE1, | ||
| 136 | USP_SYNC_MODE | USP_EN | USP_TXD_ACT_EDGE_FALLING | | ||
| 137 | USP_RFS_ACT_LEVEL_LOGIC1 | USP_TFS_ACT_LEVEL_LOGIC1 | | ||
| 138 | USP_TX_UFLOW_REPEAT_ZERO | USP_CLOCK_MODE_SLAVE); | ||
| 139 | |||
| 140 | /* Configure RX DMA IO Control register */ | ||
| 141 | regmap_write(usp->regmap, USP_RX_DMA_IO_CTRL, 0); | ||
| 142 | |||
| 143 | /* Congiure RX FIFO Control register */ | ||
| 144 | regmap_write(usp->regmap, USP_RX_FIFO_CTRL, | ||
| 145 | (USP_RX_FIFO_THRESHOLD << USP_RX_FIFO_THD_OFFSET) | | ||
| 146 | (USP_TX_RX_FIFO_WIDTH_DWORD << USP_RX_FIFO_WIDTH_OFFSET)); | ||
| 147 | |||
| 148 | /* Congiure RX FIFO Level Check register */ | ||
| 149 | regmap_write(usp->regmap, USP_RX_FIFO_LEVEL_CHK, | ||
| 150 | RX_FIFO_SC(0x04) | RX_FIFO_LC(0x0E) | RX_FIFO_HC(0x1B)); | ||
| 151 | |||
| 152 | /* Configure TX DMA IO Control register*/ | ||
| 153 | regmap_write(usp->regmap, USP_TX_DMA_IO_CTRL, 0); | ||
| 154 | |||
| 155 | /* Configure TX FIFO Control register */ | ||
| 156 | regmap_write(usp->regmap, USP_TX_FIFO_CTRL, | ||
| 157 | (USP_TX_FIFO_THRESHOLD << USP_TX_FIFO_THD_OFFSET) | | ||
| 158 | (USP_TX_RX_FIFO_WIDTH_DWORD << USP_TX_FIFO_WIDTH_OFFSET)); | ||
| 159 | /* Congiure TX FIFO Level Check register */ | ||
| 160 | regmap_write(usp->regmap, USP_TX_FIFO_LEVEL_CHK, | ||
| 161 | TX_FIFO_SC(0x1B) | TX_FIFO_LC(0x0E) | TX_FIFO_HC(0x04)); | ||
| 162 | } | ||
| 163 | |||
| 164 | static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, | ||
| 165 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
| 166 | { | ||
| 167 | struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); | ||
| 168 | u32 data_len, frame_len, shifter_len; | ||
| 169 | |||
| 170 | switch (params_format(params)) { | ||
| 171 | case SNDRV_PCM_FORMAT_S16_LE: | ||
| 172 | data_len = 16; | ||
| 173 | frame_len = 16; | ||
| 174 | break; | ||
| 175 | case SNDRV_PCM_FORMAT_S24_LE: | ||
| 176 | data_len = 24; | ||
| 177 | frame_len = 32; | ||
| 178 | break; | ||
| 179 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
| 180 | data_len = 24; | ||
| 181 | frame_len = 24; | ||
| 182 | break; | ||
| 183 | default: | ||
| 184 | dev_err(dai->dev, "Format unsupported\n"); | ||
| 185 | return -EINVAL; | ||
| 186 | } | ||
| 187 | |||
| 188 | shifter_len = data_len; | ||
| 189 | |||
| 190 | switch (usp->daifmt_format & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 191 | case SND_SOC_DAIFMT_I2S: | ||
| 192 | regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, | ||
| 193 | USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); | ||
| 194 | break; | ||
| 195 | case SND_SOC_DAIFMT_DSP_A: | ||
| 196 | regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, | ||
| 197 | USP_I2S_SYNC_CHG, 0); | ||
| 198 | frame_len = data_len * params_channels(params); | ||
| 199 | data_len = frame_len; | ||
| 200 | break; | ||
| 201 | default: | ||
| 202 | dev_err(dai->dev, "Only support I2S and DSP_A mode\n"); | ||
| 203 | return -EINVAL; | ||
| 204 | } | ||
| 205 | |||
| 206 | switch (usp->daifmt_format & SND_SOC_DAIFMT_INV_MASK) { | ||
| 207 | case SND_SOC_DAIFMT_NB_NF: | ||
| 208 | break; | ||
| 209 | case SND_SOC_DAIFMT_IB_NF: | ||
| 210 | regmap_update_bits(usp->regmap, USP_MODE1, | ||
| 211 | USP_RXD_ACT_EDGE_FALLING | USP_TXD_ACT_EDGE_FALLING, | ||
| 212 | USP_RXD_ACT_EDGE_FALLING); | ||
| 213 | break; | ||
| 214 | default: | ||
| 215 | return -EINVAL; | ||
| 216 | } | ||
| 217 | |||
| 218 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 219 | regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, | ||
| 220 | USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK | ||
| 221 | | USP_TXC_SHIFTER_LEN_MASK | USP_TXC_SLAVE_CLK_SAMPLE, | ||
| 222 | ((data_len - 1) << USP_TXC_DATA_LEN_OFFSET) | ||
| 223 | | ((frame_len - 1) << USP_TXC_FRAME_LEN_OFFSET) | ||
| 224 | | ((shifter_len - 1) << USP_TXC_SHIFTER_LEN_OFFSET) | ||
| 225 | | USP_TXC_SLAVE_CLK_SAMPLE); | ||
| 226 | else | ||
| 227 | regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, | ||
| 228 | USP_RXC_DATA_LEN_MASK | USP_RXC_FRAME_LEN_MASK | ||
| 229 | | USP_RXC_SHIFTER_LEN_MASK | USP_SINGLE_SYNC_MODE, | ||
| 230 | ((data_len - 1) << USP_RXC_DATA_LEN_OFFSET) | ||
| 231 | | ((frame_len - 1) << USP_RXC_FRAME_LEN_OFFSET) | ||
| 232 | | ((shifter_len - 1) << USP_RXC_SHIFTER_LEN_OFFSET) | ||
| 233 | | USP_SINGLE_SYNC_MODE); | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | static int sirf_usp_pcm_trigger(struct snd_pcm_substream *substream, int cmd, | ||
| 239 | struct snd_soc_dai *dai) | ||
| 240 | { | ||
| 241 | struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); | ||
| 242 | |||
| 243 | switch (cmd) { | ||
| 244 | case SNDRV_PCM_TRIGGER_START: | ||
| 245 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 246 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 247 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 248 | sirf_usp_tx_enable(usp); | ||
| 249 | else | ||
| 250 | sirf_usp_rx_enable(usp); | ||
| 251 | break; | ||
| 252 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 253 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 254 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 255 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 256 | sirf_usp_tx_disable(usp); | ||
| 257 | else | ||
| 258 | sirf_usp_rx_disable(usp); | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | |||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | |||
| 265 | static const struct snd_soc_dai_ops sirf_usp_pcm_dai_ops = { | ||
| 266 | .trigger = sirf_usp_pcm_trigger, | ||
| 267 | .set_fmt = sirf_usp_pcm_set_dai_fmt, | ||
| 268 | .hw_params = sirf_usp_pcm_hw_params, | ||
| 269 | }; | ||
| 270 | |||
| 271 | static struct snd_soc_dai_driver sirf_usp_pcm_dai = { | ||
| 272 | .probe = sirf_usp_pcm_dai_probe, | ||
| 273 | .name = "sirf-usp-pcm", | ||
| 274 | .id = 0, | ||
| 275 | .playback = { | ||
| 276 | .stream_name = "SiRF USP PCM Playback", | ||
| 277 | .channels_min = 1, | ||
| 278 | .channels_max = 2, | ||
| 279 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
| 280 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | | ||
| 281 | SNDRV_PCM_FMTBIT_S24_3LE, | ||
| 282 | }, | ||
| 283 | .capture = { | ||
| 284 | .stream_name = "SiRF USP PCM Capture", | ||
| 285 | .channels_min = 1, | ||
| 286 | .channels_max = 2, | ||
| 287 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
| 288 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | | ||
| 289 | SNDRV_PCM_FMTBIT_S24_3LE, | ||
| 290 | }, | ||
| 291 | .ops = &sirf_usp_pcm_dai_ops, | ||
| 292 | }; | ||
| 293 | |||
| 294 | static int sirf_usp_pcm_runtime_suspend(struct device *dev) | ||
| 295 | { | ||
| 296 | struct sirf_usp *usp = dev_get_drvdata(dev); | ||
| 297 | |||
| 298 | clk_disable_unprepare(usp->clk); | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int sirf_usp_pcm_runtime_resume(struct device *dev) | ||
| 303 | { | ||
| 304 | struct sirf_usp *usp = dev_get_drvdata(dev); | ||
| 305 | int ret; | ||
| 306 | |||
| 307 | ret = clk_prepare_enable(usp->clk); | ||
| 308 | if (ret) { | ||
| 309 | dev_err(dev, "clk_enable failed: %d\n", ret); | ||
| 310 | return ret; | ||
| 311 | } | ||
| 312 | sirf_usp_i2s_init(usp); | ||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | |||
| 316 | #ifdef CONFIG_PM_SLEEP | ||
| 317 | static int sirf_usp_pcm_suspend(struct device *dev) | ||
| 318 | { | ||
| 319 | struct sirf_usp *usp = dev_get_drvdata(dev); | ||
| 320 | |||
| 321 | if (!pm_runtime_status_suspended(dev)) { | ||
| 322 | regmap_read(usp->regmap, USP_MODE1, &usp->mode1_reg); | ||
| 323 | regmap_read(usp->regmap, USP_MODE2, &usp->mode2_reg); | ||
| 324 | sirf_usp_pcm_runtime_suspend(dev); | ||
| 325 | } | ||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int sirf_usp_pcm_resume(struct device *dev) | ||
| 330 | { | ||
| 331 | struct sirf_usp *usp = dev_get_drvdata(dev); | ||
| 332 | int ret; | ||
| 333 | |||
| 334 | if (!pm_runtime_status_suspended(dev)) { | ||
| 335 | ret = sirf_usp_pcm_runtime_resume(dev); | ||
| 336 | if (ret) | ||
| 337 | return ret; | ||
| 338 | regmap_write(usp->regmap, USP_MODE1, usp->mode1_reg); | ||
| 339 | regmap_write(usp->regmap, USP_MODE2, usp->mode2_reg); | ||
| 340 | } | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | #endif | ||
| 344 | |||
| 345 | static const struct snd_soc_component_driver sirf_usp_component = { | ||
| 346 | .name = "sirf-usp", | ||
| 347 | }; | ||
| 348 | |||
| 349 | static const struct regmap_config sirf_usp_regmap_config = { | ||
| 350 | .reg_bits = 32, | ||
| 351 | .reg_stride = 4, | ||
| 352 | .val_bits = 32, | ||
| 353 | .max_register = USP_RX_FIFO_DATA, | ||
| 354 | .cache_type = REGCACHE_NONE, | ||
| 355 | }; | ||
| 356 | |||
| 357 | static int sirf_usp_pcm_probe(struct platform_device *pdev) | ||
| 358 | { | ||
| 359 | int ret; | ||
| 360 | struct sirf_usp *usp; | ||
| 361 | void __iomem *base; | ||
| 362 | |||
| 363 | usp = devm_kzalloc(&pdev->dev, sizeof(struct sirf_usp), | ||
| 364 | GFP_KERNEL); | ||
| 365 | if (!usp) | ||
| 366 | return -ENOMEM; | ||
| 367 | |||
| 368 | platform_set_drvdata(pdev, usp); | ||
| 369 | |||
| 370 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 371 | if (IS_ERR(base)) | ||
| 372 | return PTR_ERR(base); | ||
| 373 | usp->regmap = devm_regmap_init_mmio(&pdev->dev, base, | ||
| 374 | &sirf_usp_regmap_config); | ||
| 375 | if (IS_ERR(usp->regmap)) | ||
| 376 | return PTR_ERR(usp->regmap); | ||
| 377 | |||
| 378 | usp->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 379 | if (IS_ERR(usp->clk)) { | ||
| 380 | dev_err(&pdev->dev, "Get clock failed.\n"); | ||
| 381 | return PTR_ERR(usp->clk); | ||
| 382 | } | ||
| 383 | |||
| 384 | pm_runtime_enable(&pdev->dev); | ||
| 385 | if (!pm_runtime_enabled(&pdev->dev)) { | ||
| 386 | ret = sirf_usp_pcm_runtime_resume(&pdev->dev); | ||
| 387 | if (ret) | ||
| 388 | return ret; | ||
| 389 | } | ||
| 390 | |||
| 391 | ret = devm_snd_soc_register_component(&pdev->dev, &sirf_usp_component, | ||
| 392 | &sirf_usp_pcm_dai, 1); | ||
| 393 | if (ret) { | ||
| 394 | dev_err(&pdev->dev, "Register Audio SoC dai failed.\n"); | ||
| 395 | return ret; | ||
| 396 | } | ||
| 397 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); | ||
| 398 | } | ||
| 399 | |||
| 400 | static int sirf_usp_pcm_remove(struct platform_device *pdev) | ||
| 401 | { | ||
| 402 | if (!pm_runtime_enabled(&pdev->dev)) | ||
| 403 | sirf_usp_pcm_runtime_suspend(&pdev->dev); | ||
| 404 | else | ||
| 405 | pm_runtime_disable(&pdev->dev); | ||
| 406 | return 0; | ||
| 407 | } | ||
| 408 | |||
| 409 | static const struct of_device_id sirf_usp_pcm_of_match[] = { | ||
| 410 | { .compatible = "sirf,prima2-usp-pcm", }, | ||
| 411 | {} | ||
| 412 | }; | ||
| 413 | MODULE_DEVICE_TABLE(of, sirf_usp_pcm_of_match); | ||
| 414 | |||
| 415 | static const struct dev_pm_ops sirf_usp_pcm_pm_ops = { | ||
| 416 | SET_RUNTIME_PM_OPS(sirf_usp_pcm_runtime_suspend, | ||
| 417 | sirf_usp_pcm_runtime_resume, NULL) | ||
| 418 | SET_SYSTEM_SLEEP_PM_OPS(sirf_usp_pcm_suspend, sirf_usp_pcm_resume) | ||
| 419 | }; | ||
| 420 | |||
| 421 | static struct platform_driver sirf_usp_pcm_driver = { | ||
| 422 | .driver = { | ||
| 423 | .name = "sirf-usp-pcm", | ||
| 424 | .of_match_table = sirf_usp_pcm_of_match, | ||
| 425 | .pm = &sirf_usp_pcm_pm_ops, | ||
| 426 | }, | ||
| 427 | .probe = sirf_usp_pcm_probe, | ||
| 428 | .remove = sirf_usp_pcm_remove, | ||
| 429 | }; | ||
| 430 | |||
| 431 | module_platform_driver(sirf_usp_pcm_driver); | ||
| 432 | |||
| 433 | MODULE_DESCRIPTION("SiRF SoC USP PCM bus driver"); | ||
| 434 | MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); | ||
| 435 | MODULE_LICENSE("GPL v2"); | ||
| @@ -1,292 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
| 2 | /* | ||
| 3 | * arch/arm/mach-prima2/include/mach/sirfsoc_usp.h | ||
| 4 | * | ||
| 5 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _SIRF_USP_H | ||
| 9 | #define _SIRF_USP_H | ||
| 10 | |||
| 11 | /* USP Registers */ | ||
| 12 | #define USP_MODE1 0x00 | ||
| 13 | #define USP_MODE2 0x04 | ||
| 14 | #define USP_TX_FRAME_CTRL 0x08 | ||
| 15 | #define USP_RX_FRAME_CTRL 0x0C | ||
| 16 | #define USP_TX_RX_ENABLE 0x10 | ||
| 17 | #define USP_INT_ENABLE 0x14 | ||
| 18 | #define USP_INT_STATUS 0x18 | ||
| 19 | #define USP_PIN_IO_DATA 0x1C | ||
| 20 | #define USP_RISC_DSP_MODE 0x20 | ||
| 21 | #define USP_AYSNC_PARAM_REG 0x24 | ||
| 22 | #define USP_IRDA_X_MODE_DIV 0x28 | ||
| 23 | #define USP_SM_CFG 0x2C | ||
| 24 | #define USP_TX_DMA_IO_CTRL 0x100 | ||
| 25 | #define USP_TX_DMA_IO_LEN 0x104 | ||
| 26 | #define USP_TX_FIFO_CTRL 0x108 | ||
| 27 | #define USP_TX_FIFO_LEVEL_CHK 0x10C | ||
| 28 | #define USP_TX_FIFO_OP 0x110 | ||
| 29 | #define USP_TX_FIFO_STATUS 0x114 | ||
| 30 | #define USP_TX_FIFO_DATA 0x118 | ||
| 31 | #define USP_RX_DMA_IO_CTRL 0x120 | ||
| 32 | #define USP_RX_DMA_IO_LEN 0x124 | ||
| 33 | #define USP_RX_FIFO_CTRL 0x128 | ||
| 34 | #define USP_RX_FIFO_LEVEL_CHK 0x12C | ||
| 35 | #define USP_RX_FIFO_OP 0x130 | ||
| 36 | #define USP_RX_FIFO_STATUS 0x134 | ||
| 37 | #define USP_RX_FIFO_DATA 0x138 | ||
| 38 | |||
| 39 | /* USP MODE register-1 */ | ||
| 40 | #define USP_SYNC_MODE 0x00000001 | ||
| 41 | #define USP_CLOCK_MODE_SLAVE 0x00000002 | ||
| 42 | #define USP_LOOP_BACK_EN 0x00000004 | ||
| 43 | #define USP_HPSIR_EN 0x00000008 | ||
| 44 | #define USP_ENDIAN_CTRL_LSBF 0x00000010 | ||
| 45 | #define USP_EN 0x00000020 | ||
| 46 | #define USP_RXD_ACT_EDGE_FALLING 0x00000040 | ||
| 47 | #define USP_TXD_ACT_EDGE_FALLING 0x00000080 | ||
| 48 | #define USP_RFS_ACT_LEVEL_LOGIC1 0x00000100 | ||
| 49 | #define USP_TFS_ACT_LEVEL_LOGIC1 0x00000200 | ||
| 50 | #define USP_SCLK_IDLE_MODE_TOGGLE 0x00000400 | ||
| 51 | #define USP_SCLK_IDLE_LEVEL_LOGIC1 0x00000800 | ||
| 52 | #define USP_SCLK_PIN_MODE_IO 0x00001000 | ||
| 53 | #define USP_RFS_PIN_MODE_IO 0x00002000 | ||
| 54 | #define USP_TFS_PIN_MODE_IO 0x00004000 | ||
| 55 | #define USP_RXD_PIN_MODE_IO 0x00008000 | ||
| 56 | #define USP_TXD_PIN_MODE_IO 0x00010000 | ||
| 57 | #define USP_SCLK_IO_MODE_INPUT 0x00020000 | ||
| 58 | #define USP_RFS_IO_MODE_INPUT 0x00040000 | ||
| 59 | #define USP_TFS_IO_MODE_INPUT 0x00080000 | ||
| 60 | #define USP_RXD_IO_MODE_INPUT 0x00100000 | ||
| 61 | #define USP_TXD_IO_MODE_INPUT 0x00200000 | ||
| 62 | #define USP_IRDA_WIDTH_DIV_MASK 0x3FC00000 | ||
| 63 | #define USP_IRDA_WIDTH_DIV_OFFSET 0 | ||
| 64 | #define USP_IRDA_IDLE_LEVEL_HIGH 0x40000000 | ||
| 65 | #define USP_TX_UFLOW_REPEAT_ZERO 0x80000000 | ||
| 66 | #define USP_TX_ENDIAN_MODE 0x00000020 | ||
| 67 | #define USP_RX_ENDIAN_MODE 0x00000020 | ||
| 68 | |||
| 69 | /* USP Mode Register-2 */ | ||
| 70 | #define USP_RXD_DELAY_LEN_MASK 0x000000FF | ||
| 71 | #define USP_RXD_DELAY_LEN_OFFSET 0 | ||
| 72 | |||
| 73 | #define USP_TXD_DELAY_LEN_MASK 0x0000FF00 | ||
| 74 | #define USP_TXD_DELAY_LEN_OFFSET 8 | ||
| 75 | |||
| 76 | #define USP_ENA_CTRL_MODE 0x00010000 | ||
| 77 | #define USP_FRAME_CTRL_MODE 0x00020000 | ||
| 78 | #define USP_TFS_SOURCE_MODE 0x00040000 | ||
| 79 | #define USP_TFS_MS_MODE 0x00080000 | ||
| 80 | #define USP_CLK_DIVISOR_MASK 0x7FE00000 | ||
| 81 | #define USP_CLK_DIVISOR_OFFSET 21 | ||
| 82 | |||
| 83 | #define USP_TFS_CLK_SLAVE_MODE (1<<20) | ||
| 84 | #define USP_RFS_CLK_SLAVE_MODE (1<<19) | ||
| 85 | |||
| 86 | #define USP_IRDA_DATA_WIDTH 0x80000000 | ||
| 87 | |||
| 88 | /* USP Transmit Frame Control Register */ | ||
| 89 | |||
| 90 | #define USP_TXC_DATA_LEN_MASK 0x000000FF | ||
| 91 | #define USP_TXC_DATA_LEN_OFFSET 0 | ||
| 92 | |||
| 93 | #define USP_TXC_SYNC_LEN_MASK 0x0000FF00 | ||
| 94 | #define USP_TXC_SYNC_LEN_OFFSET 8 | ||
| 95 | |||
| 96 | #define USP_TXC_FRAME_LEN_MASK 0x00FF0000 | ||
| 97 | #define USP_TXC_FRAME_LEN_OFFSET 16 | ||
| 98 | |||
| 99 | #define USP_TXC_SHIFTER_LEN_MASK 0x1F000000 | ||
| 100 | #define USP_TXC_SHIFTER_LEN_OFFSET 24 | ||
| 101 | |||
| 102 | #define USP_TXC_SLAVE_CLK_SAMPLE 0x20000000 | ||
| 103 | |||
| 104 | #define USP_TXC_CLK_DIVISOR_MASK 0xC0000000 | ||
| 105 | #define USP_TXC_CLK_DIVISOR_OFFSET 30 | ||
| 106 | |||
| 107 | /* USP Receive Frame Control Register */ | ||
| 108 | |||
| 109 | #define USP_RXC_DATA_LEN_MASK 0x000000FF | ||
| 110 | #define USP_RXC_DATA_LEN_OFFSET 0 | ||
| 111 | |||
| 112 | #define USP_RXC_FRAME_LEN_MASK 0x0000FF00 | ||
| 113 | #define USP_RXC_FRAME_LEN_OFFSET 8 | ||
| 114 | |||
| 115 | #define USP_RXC_SHIFTER_LEN_MASK 0x001F0000 | ||
| 116 | #define USP_RXC_SHIFTER_LEN_OFFSET 16 | ||
| 117 | |||
| 118 | #define USP_START_EDGE_MODE 0x00800000 | ||
| 119 | #define USP_I2S_SYNC_CHG 0x00200000 | ||
| 120 | |||
| 121 | #define USP_RXC_CLK_DIVISOR_MASK 0x0F000000 | ||
| 122 | #define USP_RXC_CLK_DIVISOR_OFFSET 24 | ||
| 123 | #define USP_SINGLE_SYNC_MODE 0x00400000 | ||
| 124 | |||
| 125 | /* Tx - RX Enable Register */ | ||
| 126 | |||
| 127 | #define USP_RX_ENA 0x00000001 | ||
| 128 | #define USP_TX_ENA 0x00000002 | ||
| 129 | |||
| 130 | /* USP Interrupt Enable and status Register */ | ||
| 131 | #define USP_RX_DONE_INT 0x00000001 | ||
| 132 | #define USP_TX_DONE_INT 0x00000002 | ||
| 133 | #define USP_RX_OFLOW_INT 0x00000004 | ||
| 134 | #define USP_TX_UFLOW_INT 0x00000008 | ||
| 135 | #define USP_RX_IO_DMA_INT 0x00000010 | ||
| 136 | #define USP_TX_IO_DMA_INT 0x00000020 | ||
| 137 | #define USP_RXFIFO_FULL_INT 0x00000040 | ||
| 138 | #define USP_TXFIFO_EMPTY_INT 0x00000080 | ||
| 139 | #define USP_RXFIFO_THD_INT 0x00000100 | ||
| 140 | #define USP_TXFIFO_THD_INT 0x00000200 | ||
| 141 | #define USP_UART_FRM_ERR_INT 0x00000400 | ||
| 142 | #define USP_RX_TIMEOUT_INT 0x00000800 | ||
| 143 | #define USP_TX_ALLOUT_INT 0x00001000 | ||
| 144 | #define USP_RXD_BREAK_INT 0x00008000 | ||
| 145 | |||
| 146 | /* All possible TX interruots */ | ||
| 147 | #define USP_TX_INTERRUPT (USP_TX_DONE_INT|USP_TX_UFLOW_INT|\ | ||
| 148 | USP_TX_IO_DMA_INT|\ | ||
| 149 | USP_TXFIFO_EMPTY_INT|\ | ||
| 150 | USP_TXFIFO_THD_INT) | ||
| 151 | /* All possible RX interruots */ | ||
| 152 | #define USP_RX_INTERRUPT (USP_RX_DONE_INT|USP_RX_OFLOW_INT|\ | ||
| 153 | USP_RX_IO_DMA_INT|\ | ||
| 154 | USP_RXFIFO_FULL_INT|\ | ||
| 155 | USP_RXFIFO_THD_INT|\ | ||
| 156 | USP_RX_TIMEOUT_INT) | ||
| 157 | |||
| 158 | #define USP_INT_ALL 0x1FFF | ||
| 159 | |||
| 160 | /* USP Pin I/O Data Register */ | ||
| 161 | |||
| 162 | #define USP_RFS_PIN_VALUE_MASK 0x00000001 | ||
| 163 | #define USP_TFS_PIN_VALUE_MASK 0x00000002 | ||
| 164 | #define USP_RXD_PIN_VALUE_MASK 0x00000004 | ||
| 165 | #define USP_TXD_PIN_VALUE_MASK 0x00000008 | ||
| 166 | #define USP_SCLK_PIN_VALUE_MASK 0x00000010 | ||
| 167 | |||
| 168 | /* USP RISC/DSP Mode Register */ | ||
| 169 | #define USP_RISC_DSP_SEL 0x00000001 | ||
| 170 | |||
| 171 | /* USP ASYNC PARAMETER Register*/ | ||
| 172 | |||
| 173 | #define USP_ASYNC_TIMEOUT_MASK 0x0000FFFF | ||
| 174 | #define USP_ASYNC_TIMEOUT_OFFSET 0 | ||
| 175 | #define USP_ASYNC_TIMEOUT(x) (((x)&USP_ASYNC_TIMEOUT_MASK) \ | ||
| 176 | <<USP_ASYNC_TIMEOUT_OFFSET) | ||
| 177 | |||
| 178 | #define USP_ASYNC_DIV2_MASK 0x003F0000 | ||
| 179 | #define USP_ASYNC_DIV2_OFFSET 16 | ||
| 180 | |||
| 181 | /* USP TX DMA I/O MODE Register */ | ||
| 182 | #define USP_TX_MODE_IO 0x00000001 | ||
| 183 | |||
| 184 | /* USP TX DMA I/O Length Register */ | ||
| 185 | #define USP_TX_DATA_LEN_MASK 0xFFFFFFFF | ||
| 186 | #define USP_TX_DATA_LEN_OFFSET 0 | ||
| 187 | |||
| 188 | /* USP TX FIFO Control Register */ | ||
| 189 | #define USP_TX_FIFO_WIDTH_MASK 0x00000003 | ||
| 190 | #define USP_TX_FIFO_WIDTH_OFFSET 0 | ||
| 191 | |||
| 192 | #define USP_TX_FIFO_THD_MASK 0x000001FC | ||
| 193 | #define USP_TX_FIFO_THD_OFFSET 2 | ||
| 194 | |||
| 195 | /* USP TX FIFO Level Check Register */ | ||
| 196 | #define USP_TX_FIFO_LEVEL_CHECK_MASK 0x1F | ||
| 197 | #define USP_TX_FIFO_SC_OFFSET 0 | ||
| 198 | #define USP_TX_FIFO_LC_OFFSET 10 | ||
| 199 | #define USP_TX_FIFO_HC_OFFSET 20 | ||
| 200 | |||
| 201 | #define TX_FIFO_SC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 202 | << USP_TX_FIFO_SC_OFFSET) | ||
| 203 | #define TX_FIFO_LC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 204 | << USP_TX_FIFO_LC_OFFSET) | ||
| 205 | #define TX_FIFO_HC(x) (((x) & USP_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 206 | << USP_TX_FIFO_HC_OFFSET) | ||
| 207 | |||
| 208 | /* USP TX FIFO Operation Register */ | ||
| 209 | #define USP_TX_FIFO_RESET 0x00000001 | ||
| 210 | #define USP_TX_FIFO_START 0x00000002 | ||
| 211 | |||
| 212 | /* USP TX FIFO Status Register */ | ||
| 213 | #define USP_TX_FIFO_LEVEL_MASK 0x0000007F | ||
| 214 | #define USP_TX_FIFO_LEVEL_OFFSET 0 | ||
| 215 | |||
| 216 | #define USP_TX_FIFO_FULL 0x00000080 | ||
| 217 | #define USP_TX_FIFO_EMPTY 0x00000100 | ||
| 218 | |||
| 219 | /* USP TX FIFO Data Register */ | ||
| 220 | #define USP_TX_FIFO_DATA_MASK 0xFFFFFFFF | ||
| 221 | #define USP_TX_FIFO_DATA_OFFSET 0 | ||
| 222 | |||
| 223 | /* USP RX DMA I/O MODE Register */ | ||
| 224 | #define USP_RX_MODE_IO 0x00000001 | ||
| 225 | #define USP_RX_DMA_FLUSH 0x00000004 | ||
| 226 | |||
| 227 | /* USP RX DMA I/O Length Register */ | ||
| 228 | #define USP_RX_DATA_LEN_MASK 0xFFFFFFFF | ||
| 229 | #define USP_RX_DATA_LEN_OFFSET 0 | ||
| 230 | |||
| 231 | /* USP RX FIFO Control Register */ | ||
| 232 | #define USP_RX_FIFO_WIDTH_MASK 0x00000003 | ||
| 233 | #define USP_RX_FIFO_WIDTH_OFFSET 0 | ||
| 234 | |||
| 235 | #define USP_RX_FIFO_THD_MASK 0x000001FC | ||
| 236 | #define USP_RX_FIFO_THD_OFFSET 2 | ||
| 237 | |||
| 238 | /* USP RX FIFO Level Check Register */ | ||
| 239 | |||
| 240 | #define USP_RX_FIFO_LEVEL_CHECK_MASK 0x1F | ||
| 241 | #define USP_RX_FIFO_SC_OFFSET 0 | ||
| 242 | #define USP_RX_FIFO_LC_OFFSET 10 | ||
| 243 | #define USP_RX_FIFO_HC_OFFSET 20 | ||
| 244 | |||
| 245 | #define RX_FIFO_SC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 246 | << USP_RX_FIFO_SC_OFFSET) | ||
| 247 | #define RX_FIFO_LC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 248 | << USP_RX_FIFO_LC_OFFSET) | ||
| 249 | #define RX_FIFO_HC(x) (((x) & USP_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
| 250 | << USP_RX_FIFO_HC_OFFSET) | ||
| 251 | |||
| 252 | /* USP RX FIFO Operation Register */ | ||
| 253 | #define USP_RX_FIFO_RESET 0x00000001 | ||
| 254 | #define USP_RX_FIFO_START 0x00000002 | ||
| 255 | |||
| 256 | /* USP RX FIFO Status Register */ | ||
| 257 | |||
| 258 | #define USP_RX_FIFO_LEVEL_MASK 0x0000007F | ||
| 259 | #define USP_RX_FIFO_LEVEL_OFFSET 0 | ||
| 260 | |||
| 261 | #define USP_RX_FIFO_FULL 0x00000080 | ||
| 262 | #define USP_RX_FIFO_EMPTY 0x00000100 | ||
| 263 | |||
| 264 | /* USP RX FIFO Data Register */ | ||
| 265 | |||
| 266 | #define USP_RX_FIFO_DATA_MASK 0xFFFFFFFF | ||
| 267 | #define USP_RX_FIFO_DATA_OFFSET 0 | ||
| 268 | |||
| 269 | /* | ||
| 270 | * When rx thd irq occur, sender just disable tx empty irq, | ||
| 271 | * Remaining data in tx fifo wil also be sent out. | ||
| 272 | */ | ||
| 273 | #define USP_FIFO_SIZE 128 | ||
| 274 | #define USP_TX_FIFO_THRESHOLD (USP_FIFO_SIZE/2) | ||
| 275 | #define USP_RX_FIFO_THRESHOLD (USP_FIFO_SIZE/2) | ||
| 276 | |||
| 277 | /* FIFO_WIDTH for the USP_TX_FIFO_CTRL and USP_RX_FIFO_CTRL registers */ | ||
| 278 | #define USP_FIFO_WIDTH_BYTE 0x00 | ||
| 279 | #define USP_FIFO_WIDTH_WORD 0x01 | ||
| 280 | #define USP_FIFO_WIDTH_DWORD 0x02 | ||
| 281 | |||
| 282 | #define USP_ASYNC_DIV2 16 | ||
| 283 | |||
| 284 | #define USP_PLUGOUT_RETRY_CNT 2 | ||
| 285 | |||
| 286 | #define USP_TX_RX_FIFO_WIDTH_DWORD 2 | ||
| 287 | |||
| 288 | #define SIRF_USP_DIV_MCLK 0 | ||
| 289 | |||
| 290 | #define SIRF_USP_I2S_TFS_SYNC 0 | ||
| 291 | #define SIRF_USP_I2S_RFS_SYNC 1 | ||
| 292 | #endif | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/pm_runtime.h> | 12 | #include <linux/pm_runtime.h> |
| 13 | #include <sound/soc.h> | 13 | #include <sound/soc.h> |
| 14 | #include <linux/bitops.h> | ||
| 14 | 15 | ||
| 15 | #define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret) | 16 | #define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret) |
| 16 | static inline int _soc_component_ret(struct snd_soc_component *component, | 17 | static inline int _soc_component_ret(struct snd_soc_component *component, |
| @@ -34,6 +35,18 @@ static inline int _soc_component_ret(struct snd_soc_component *component, · 17 unmodified lines | |||
| 34 | return ret; | 35 | return ret; |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 38 | static inline int soc_component_field_shift(struct snd_soc_component *component, | ||
| 39 | unsigned int mask) | ||
| 40 | { | ||
| 41 | if (!mask) { | ||
| 42 | dev_err(component->dev, "ASoC: error field mask is zero for %s\n", | ||
| 43 | component->name); | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | return (ffs(mask) - 1); | ||
| 48 | } | ||
| 49 | |||
| 37 | /* | 50 | /* |
| 38 | * We might want to check substream by using list. | 51 | * We might want to check substream by using list. |
| 39 | * In such case, we can update these macros. | 52 | * In such case, we can update these macros. |
| @@ -839,6 +852,47 @@ int snd_soc_component_update_bits_async(struct snd_soc_component *component, · 799 unmodified lines | |||
| 839 | } | 852 | } |
| 840 | EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async); | 853 | EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async); |
| 841 | 854 | ||
| 855 | /** | ||
| 856 | * snd_soc_component_read_field() - Read register field value | ||
| 857 | * @component: Component to read from | ||
| 858 | * @reg: Register to read | ||
| 859 | * @mask: mask of the register field | ||
| 860 | * | ||
| 861 | * Return: read value of register field. | ||
| 862 | */ | ||
| 863 | unsigned int snd_soc_component_read_field(struct snd_soc_component *component, | ||
| 864 | unsigned int reg, unsigned int mask) | ||
| 865 | { | ||
| 866 | unsigned int val; | ||
| 867 | |||
| 868 | val = snd_soc_component_read(component, reg); | ||
| 869 | |||
| 870 | val = (val & mask) >> soc_component_field_shift(component, mask); | ||
| 871 | |||
| 872 | return val; | ||
| 873 | } | ||
| 874 | EXPORT_SYMBOL_GPL(snd_soc_component_read_field); | ||
| 875 | |||
| 876 | /** | ||
| 877 | * snd_soc_component_write_field() - write to register field | ||
| 878 | * @component: Component to write to | ||
| 879 | * @reg: Register to write | ||
| 880 | * @mask: mask of the register field to update | ||
| 881 | * @val: value of the field to write | ||
| 882 | * | ||
| 883 | * Return: 1 for change, otherwise 0. | ||
| 884 | */ | ||
| 885 | int snd_soc_component_write_field(struct snd_soc_component *component, | ||
| 886 | unsigned int reg, unsigned int mask, | ||
| 887 | unsigned int val) | ||
| 888 | { | ||
| 889 | |||
| 890 | val = (val << soc_component_field_shift(component, mask)) & mask; | ||
| 891 | |||
| 892 | return snd_soc_component_update_bits(component, reg, mask, val); | ||
| 893 | } | ||
| 894 | EXPORT_SYMBOL_GPL(snd_soc_component_write_field); | ||
| 895 | |||
| 842 | /** | 896 | /** |
| 843 | * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed | 897 | * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed |
| 844 | * @component: Component for which to wait | 898 | * @component: Component for which to wait |
| @@ -2528,9 +2528,20 @@ static struct snd_soc_dapm_widget *dapm_find_widget( · 2527 unmodified lines | |||
| 2528 | { | 2528 | { |
| 2529 | struct snd_soc_dapm_widget *w; | 2529 | struct snd_soc_dapm_widget *w; |
| 2530 | struct snd_soc_dapm_widget *fallback = NULL; | 2530 | struct snd_soc_dapm_widget *fallback = NULL; |
| 2531 | char prefixed_pin[80]; | ||
| 2532 | const char *pin_name; | ||
| 2533 | const char *prefix = soc_dapm_prefix(dapm); | ||
| 2534 | |||
| 2535 | if (prefix) { | ||
| 2536 | snprintf(prefixed_pin, sizeof(prefixed_pin), "%s %s", | ||
| 2537 | prefix, pin); | ||
| 2538 | pin_name = prefixed_pin; | ||
| 2539 | } else { | ||
| 2540 | pin_name = pin; | ||
| 2541 | } | ||
| 2531 | 2542 | ||
| 2532 | for_each_card_widgets(dapm->card, w) { | 2543 | for_each_card_widgets(dapm->card, w) { |
| 2533 | if (!strcmp(w->name, pin)) { | 2544 | if (!strcmp(w->name, pin_name)) { |
| 2534 | if (w->dapm == dapm) | 2545 | if (w->dapm == dapm) |
| 2535 | return w; | 2546 | return w; |
| 2536 | else | 2547 | else |
| @@ -203,6 +203,34 @@ static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm) · 202 unmodified lines | |||
| 203 | } | 203 | } |
| 204 | #endif | 204 | #endif |
| 205 | 205 | ||
| 206 | /* Set FE's runtime_update state; the state is protected via PCM stream lock | ||
| 207 | * for avoiding the race with trigger callback. | ||
| 208 | * If the state is unset and a trigger is pending while the previous operation, | ||
| 209 | * process the pending trigger action here. | ||
| 210 | */ | ||
| 211 | static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); | ||
| 212 | static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe, | ||
| 213 | int stream, enum snd_soc_dpcm_update state) | ||
| 214 | { | ||
| 215 | struct snd_pcm_substream *substream = | ||
| 216 | snd_soc_dpcm_get_substream(fe, stream); | ||
| 217 | |||
| 218 | snd_pcm_stream_lock_irq(substream); | ||
| 219 | if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { | ||
| 220 | dpcm_fe_dai_do_trigger(substream, | ||
| 221 | fe->dpcm[stream].trigger_pending - 1); | ||
| 222 | fe->dpcm[stream].trigger_pending = 0; | ||
| 223 | } | ||
| 224 | fe->dpcm[stream].runtime_update = state; | ||
| 225 | snd_pcm_stream_unlock_irq(substream); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void dpcm_set_be_update_state(struct snd_soc_pcm_runtime *be, | ||
| 229 | int stream, enum snd_soc_dpcm_update state) | ||
| 230 | { | ||
| 231 | be->dpcm[stream].runtime_update = state; | ||
| 232 | } | ||
| 233 | |||
| 206 | /** | 234 | /** |
| 207 | * snd_soc_runtime_action() - Increment/Decrement active count for | 235 | * snd_soc_runtime_action() - Increment/Decrement active count for |
| 208 | * PCM runtime components | 236 | * PCM runtime components |
| @@ -301,59 +329,46 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, · 92 unmodified lines | |||
| 301 | return 0; | 329 | return 0; |
| 302 | } | 330 | } |
| 303 | 331 | ||
| 332 | static void soc_pcm_set_dai_params(struct snd_soc_dai *dai, | ||
| 333 | struct snd_pcm_hw_params *params) | ||
| 334 | { | ||
| 335 | if (params) { | ||
| 336 | dai->rate = params_rate(params); | ||
| 337 | dai->channels = params_channels(params); | ||
| 338 | dai->sample_bits = snd_pcm_format_physical_width(params_format(params)); | ||
| 339 | } else { | ||
| 340 | dai->rate = 0; | ||
| 341 | dai->channels = 0; | ||
| 342 | dai->sample_bits = 0; | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 304 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, | 346 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, |
| 305 | struct snd_soc_dai *soc_dai) | 347 | struct snd_soc_dai *soc_dai) |
| 306 | { | 348 | { |
| 307 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 349 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 308 | int ret; | 350 | int ret; |
| 309 | 351 | ||
| 310 | if (soc_dai->rate && (soc_dai->driver->symmetric_rates || | 352 | #define __soc_pcm_apply_symmetry(name, NAME) \ |
| 311 | rtd->dai_link->symmetric_rates)) { | 353 | if (soc_dai->name && (soc_dai->driver->symmetric_##name || \ |
| 312 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", | 354 | rtd->dai_link->symmetric_##name)) { \ |
| 313 | soc_dai->rate); | 355 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ |
| 314 | 356 | #name, soc_dai->name); \ | |
| 315 | ret = snd_pcm_hw_constraint_single(substream->runtime, | 357 | \ |
| 316 | SNDRV_PCM_HW_PARAM_RATE, | 358 | ret = snd_pcm_hw_constraint_single(substream->runtime, \ |
| 317 | soc_dai->rate); | 359 | SNDRV_PCM_HW_PARAM_##NAME,\ |
| 318 | if (ret < 0) { | 360 | soc_dai->name); \ |
| 319 | dev_err(soc_dai->dev, | 361 | if (ret < 0) { \ |
| 320 | "ASoC: Unable to apply rate constraint: %d\n", | 362 | dev_err(soc_dai->dev, \ |
| 321 | ret); | 363 | "ASoC: Unable to apply %s constraint: %d\n",\ |
| 322 | return ret; | 364 | #name, ret); \ |
| 323 | } | 365 | return ret; \ |
| 324 | } | 366 | } \ |
| 325 | 367 | } | |
| 326 | if (soc_dai->channels && (soc_dai->driver->symmetric_channels || | 368 | |
| 327 | rtd->dai_link->symmetric_channels)) { | 369 | __soc_pcm_apply_symmetry(rate, RATE); |
| 328 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", | 370 | __soc_pcm_apply_symmetry(channels, CHANNELS); |
| 329 | soc_dai->channels); | 371 | __soc_pcm_apply_symmetry(sample_bits, SAMPLE_BITS); |
| 330 | |||
| 331 | ret = snd_pcm_hw_constraint_single(substream->runtime, | ||
| 332 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
| 333 | soc_dai->channels); | ||
| 334 | if (ret < 0) { | ||
| 335 | dev_err(soc_dai->dev, | ||
| 336 | "ASoC: Unable to apply channel symmetry constraint: %d\n", | ||
| 337 | ret); | ||
| 338 | return ret; | ||
| 339 | } | ||
| 340 | } | ||
| 341 | |||
| 342 | if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || | ||
| 343 | rtd->dai_link->symmetric_samplebits)) { | ||
| 344 | dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", | ||
| 345 | soc_dai->sample_bits); | ||
| 346 | |||
| 347 | ret = snd_pcm_hw_constraint_single(substream->runtime, | ||
| 348 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | ||
| 349 | soc_dai->sample_bits); | ||
| 350 | if (ret < 0) { | ||
| 351 | dev_err(soc_dai->dev, | ||
| 352 | "ASoC: Unable to apply sample bits symmetry constraint: %d\n", | ||
| 353 | ret); | ||
| 354 | return ret; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | 372 | ||
| 358 | return 0; | 373 | return 0; |
| 359 | } | 374 | } |
| @@ -362,61 +377,30 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 362 | struct snd_pcm_hw_params *params) | 377 | struct snd_pcm_hw_params *params) |
| 363 | { | 378 | { |
| 364 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 379 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 380 | struct snd_soc_dai d; | ||
| 365 | struct snd_soc_dai *dai; | 381 | struct snd_soc_dai *dai; |
| 366 | struct snd_soc_dai *cpu_dai; | 382 | struct snd_soc_dai *cpu_dai; |
| 367 | unsigned int rate, channels, sample_bits, symmetry, i; | 383 | unsigned int symmetry, i; |
| 368 | |||
| 369 | rate = params_rate(params); | ||
| 370 | channels = params_channels(params); | ||
| 371 | sample_bits = snd_pcm_format_physical_width(params_format(params)); | ||
| 372 | |||
| 373 | /* reject unmatched parameters when applying symmetry */ | ||
| 374 | symmetry = rtd->dai_link->symmetric_rates; | ||
| 375 | |||
| 376 | for_each_rtd_cpu_dais(rtd, i, dai) | ||
| 377 | symmetry |= dai->driver->symmetric_rates; | ||
| 378 | |||
| 379 | if (symmetry) { | ||
| 380 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) { | ||
| 381 | if (cpu_dai->rate && cpu_dai->rate != rate) { | ||
| 382 | dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", | ||
| 383 | cpu_dai->rate, rate); | ||
| 384 | return -EINVAL; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | symmetry = rtd->dai_link->symmetric_channels; | ||
| 390 | 384 | ||
| 391 | for_each_rtd_dais(rtd, i, dai) | 385 | soc_pcm_set_dai_params(&d, params); |
| 392 | symmetry |= dai->driver->symmetric_channels; | 386 | |
| 393 | 387 | #define __soc_pcm_params_symmetry(name) \ | |
| 394 | if (symmetry) { | 388 | symmetry = rtd->dai_link->symmetric_##name; \ |
| 395 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) { | 389 | for_each_rtd_dais(rtd, i, dai) \ |
| 396 | if (cpu_dai->channels && | 390 | symmetry |= dai->driver->symmetric_##name; \ |
| 397 | cpu_dai->channels != channels) { | 391 | \ |
| 398 | dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", | 392 | if (symmetry) \ |
| 399 | cpu_dai->channels, channels); | 393 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ |
| 400 | return -EINVAL; | 394 | if (cpu_dai->name && cpu_dai->name != d.name) { \ |
| 395 | dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %d - %d\n", \ | ||
| 396 | #name, cpu_dai->name, d.name); \ | ||
| 397 | return -EINVAL; \ | ||
| 401 | } | 398 | } |
| 402 | } | ||
| 403 | } | ||
| 404 | 399 | ||
| 405 | symmetry = rtd->dai_link->symmetric_samplebits; | 400 | /* reject unmatched parameters when applying symmetry */ |
| 406 | 401 | __soc_pcm_params_symmetry(rate); | |
| 407 | for_each_rtd_dais(rtd, i, dai) | 402 | __soc_pcm_params_symmetry(channels); |
| 408 | symmetry |= dai->driver->symmetric_samplebits; | 403 | __soc_pcm_params_symmetry(sample_bits); |
| 409 | |||
| 410 | if (symmetry) { | ||
| 411 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) { | ||
| 412 | if (cpu_dai->sample_bits && | ||
| 413 | cpu_dai->sample_bits != sample_bits) { | ||
| 414 | dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", | ||
| 415 | cpu_dai->sample_bits, sample_bits); | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | 404 | ||
| 421 | return 0; | 405 | return 0; |
| 422 | } | 406 | } |
| @@ -428,15 +412,15 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) · 5 unmodified lines | |||
| 428 | struct snd_soc_dai *dai; | 412 | struct snd_soc_dai *dai; |
| 429 | unsigned int symmetry, i; | 413 | unsigned int symmetry, i; |
| 430 | 414 | ||
| 431 | symmetry = link->symmetric_rates || | 415 | symmetry = link->symmetric_rate || |
| 432 | link->symmetric_channels || | 416 | link->symmetric_channels || |
| 433 | link->symmetric_samplebits; | 417 | link->symmetric_sample_bits; |
| 434 | 418 | ||
| 435 | for_each_rtd_dais(rtd, i, dai) | 419 | for_each_rtd_dais(rtd, i, dai) |
| 436 | symmetry = symmetry || | 420 | symmetry = symmetry || |
| 437 | dai->driver->symmetric_rates || | 421 | dai->driver->symmetric_rate || |
| 438 | dai->driver->symmetric_channels || | 422 | dai->driver->symmetric_channels || |
| 439 | dai->driver->symmetric_samplebits; | 423 | dai->driver->symmetric_sample_bits; |
| 440 | 424 | ||
| 441 | return symmetry; | 425 | return symmetry; |
| 442 | } | 426 | } |
| @@ -489,6 +473,42 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) · 46 unmodified lines | |||
| 489 | soc_pcm_set_msb(substream, cpu_bits); | 473 | soc_pcm_set_msb(substream, cpu_bits); |
| 490 | } | 474 | } |
| 491 | 475 | ||
| 476 | static void soc_pcm_hw_init(struct snd_pcm_hardware *hw) | ||
| 477 | { | ||
| 478 | hw->rates = UINT_MAX; | ||
| 479 | hw->rate_min = 0; | ||
| 480 | hw->rate_max = UINT_MAX; | ||
| 481 | hw->channels_min = 0; | ||
| 482 | hw->channels_max = UINT_MAX; | ||
| 483 | hw->formats = ULLONG_MAX; | ||
| 484 | } | ||
| 485 | |||
| 486 | static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, | ||
| 487 | struct snd_soc_pcm_stream *p) | ||
| 488 | { | ||
| 489 | hw->rates = snd_pcm_rate_mask_intersect(hw->rates, p->rates); | ||
| 490 | |||
| 491 | /* setup hw->rate_min/max via hw->rates first */ | ||
| 492 | snd_pcm_hw_limit_rates(hw); | ||
| 493 | |||
| 494 | /* update hw->rate_min/max by snd_soc_pcm_stream */ | ||
| 495 | hw->rate_min = max(hw->rate_min, p->rate_min); | ||
| 496 | hw->rate_max = min_not_zero(hw->rate_max, p->rate_max); | ||
| 497 | } | ||
| 498 | |||
| 499 | static void soc_pcm_hw_update_chan(struct snd_pcm_hardware *hw, | ||
| 500 | struct snd_soc_pcm_stream *p) | ||
| 501 | { | ||
| 502 | hw->channels_min = max(hw->channels_min, p->channels_min); | ||
| 503 | hw->channels_max = min(hw->channels_max, p->channels_max); | ||
| 504 | } | ||
| 505 | |||
| 506 | static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw, | ||
| 507 | struct snd_soc_pcm_stream *p) | ||
| 508 | { | ||
| 509 | hw->formats &= p->formats; | ||
| 510 | } | ||
| 511 | |||
| 492 | /** | 512 | /** |
| 493 | * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream | 513 | * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream |
| 494 | * @rtd: ASoC PCM runtime | 514 | * @rtd: ASoC PCM runtime |
| @@ -505,14 +525,11 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, · 10 unmodified lines | |||
| 505 | struct snd_soc_dai *cpu_dai; | 525 | struct snd_soc_dai *cpu_dai; |
| 506 | struct snd_soc_pcm_stream *codec_stream; | 526 | struct snd_soc_pcm_stream *codec_stream; |
| 507 | struct snd_soc_pcm_stream *cpu_stream; | 527 | struct snd_soc_pcm_stream *cpu_stream; |
| 508 | unsigned int chan_min = 0, chan_max = UINT_MAX; | ||
| 509 | unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; | 528 | unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; |
| 510 | unsigned int rate_min = 0, rate_max = UINT_MAX; | ||
| 511 | unsigned int cpu_rate_min = 0, cpu_rate_max = UINT_MAX; | ||
| 512 | unsigned int rates = UINT_MAX, cpu_rates = UINT_MAX; | ||
| 513 | u64 formats = ULLONG_MAX; | ||
| 514 | int i; | 529 | int i; |
| 515 | 530 | ||
| 531 | soc_pcm_hw_init(hw); | ||
| 532 | |||
| 516 | /* first calculate min/max only for CPUs in the DAI link */ | 533 | /* first calculate min/max only for CPUs in the DAI link */ |
| 517 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) { | 534 | for_each_rtd_cpu_dais(rtd, i, cpu_dai) { |
| 518 | 535 | ||
| @@ -527,14 +544,12 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, · 8 unmodified lines | |||
| 527 | 544 | ||
| 528 | cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream); | 545 | cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream); |
| 529 | 546 | ||
| 530 | cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); | 547 | soc_pcm_hw_update_chan(hw, cpu_stream); |
| 531 | cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); | 548 | soc_pcm_hw_update_rate(hw, cpu_stream); |
| 532 | cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min); | 549 | soc_pcm_hw_update_format(hw, cpu_stream); |
| 533 | cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max); | ||
| 534 | formats &= cpu_stream->formats; | ||
| 535 | cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates, | ||
| 536 | cpu_rates); | ||
| 537 | } | 550 | } |
| 551 | cpu_chan_min = hw->channels_min; | ||
| 552 | cpu_chan_max = hw->channels_max; | ||
| 538 | 553 | ||
| 539 | /* second calculate min/max only for CODECs in the DAI link */ | 554 | /* second calculate min/max only for CODECs in the DAI link */ |
| 540 | for_each_rtd_codec_dais(rtd, i, codec_dai) { | 555 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| @@ -550,16 +565,13 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, · 9 unmodified lines | |||
| 550 | 565 | ||
| 551 | codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream); | 566 | codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream); |
| 552 | 567 | ||
| 553 | chan_min = max(chan_min, codec_stream->channels_min); | 568 | soc_pcm_hw_update_chan(hw, codec_stream); |
| 554 | chan_max = min(chan_max, codec_stream->channels_max); | 569 | soc_pcm_hw_update_rate(hw, codec_stream); |
| 555 | rate_min = max(rate_min, codec_stream->rate_min); | 570 | soc_pcm_hw_update_format(hw, codec_stream); |
| 556 | rate_max = min_not_zero(rate_max, codec_stream->rate_max); | ||
| 557 | formats &= codec_stream->formats; | ||
| 558 | rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates); | ||
| 559 | } | 571 | } |
| 560 | 572 | ||
| 561 | /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ | 573 | /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ |
| 562 | if (!chan_min || !cpu_chan_min) | 574 | if (!hw->channels_min) |
| 563 | return -EINVAL; | 575 | return -EINVAL; |
| 564 | 576 | ||
| 565 | /* | 577 | /* |
| @@ -568,23 +580,10 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, · 2 unmodified lines | |||
| 568 | * channel allocation be fixed up later | 580 | * channel allocation be fixed up later |
| 569 | */ | 581 | */ |
| 570 | if (rtd->num_codecs > 1) { | 582 | if (rtd->num_codecs > 1) { |
| 571 | chan_min = cpu_chan_min; | 583 | hw->channels_min = cpu_chan_min; |
| 572 | chan_max = cpu_chan_max; | 584 | hw->channels_max = cpu_chan_max; |
| 573 | } | 585 | } |
| 574 | 586 | ||
| 575 | /* finally find a intersection between CODECs and CPUs */ | ||
| 576 | hw->channels_min = max(chan_min, cpu_chan_min); | ||
| 577 | hw->channels_max = min(chan_max, cpu_chan_max); | ||
| 578 | hw->formats = formats; | ||
| 579 | hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_rates); | ||
| 580 | |||
| 581 | snd_pcm_hw_limit_rates(hw); | ||
| 582 | |||
| 583 | hw->rate_min = max(hw->rate_min, cpu_rate_min); | ||
| 584 | hw->rate_min = max(hw->rate_min, rate_min); | ||
| 585 | hw->rate_max = min_not_zero(hw->rate_max, cpu_rate_max); | ||
| 586 | hw->rate_max = min_not_zero(hw->rate_max, rate_max); | ||
| 587 | |||
| 588 | return 0; | 587 | return 0; |
| 589 | } | 588 | } |
| 590 | EXPORT_SYMBOL_GPL(snd_soc_runtime_calc_hw); | 589 | EXPORT_SYMBOL_GPL(snd_soc_runtime_calc_hw); |
| @@ -870,11 +869,8 @@ static int soc_pcm_hw_clean(struct snd_pcm_substream *substream, int rollback) · 279 unmodified lines | |||
| 870 | for_each_rtd_dais(rtd, i, dai) { | 869 | for_each_rtd_dais(rtd, i, dai) { |
| 871 | int active = snd_soc_dai_stream_active(dai, substream->stream); | 870 | int active = snd_soc_dai_stream_active(dai, substream->stream); |
| 872 | 871 | ||
| 873 | if (snd_soc_dai_active(dai) == 1) { | 872 | if (snd_soc_dai_active(dai) == 1) |
| 874 | dai->rate = 0; | 873 | soc_pcm_set_dai_params(dai, NULL); |
| 875 | dai->channels = 0; | ||
| 876 | dai->sample_bits = 0; | ||
| 877 | } | ||
| 878 | 874 | ||
| 879 | if (active == 1) | 875 | if (active == 1) |
| 880 | snd_soc_dai_digital_mute(dai, 1, substream->stream); | 876 | snd_soc_dai_digital_mute(dai, 1, substream->stream); |
| @@ -971,11 +967,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, · 90 unmodified lines | |||
| 971 | if(ret < 0) | 967 | if(ret < 0) |
| 972 | goto out; | 968 | goto out; |
| 973 | 969 | ||
| 974 | codec_dai->rate = params_rate(&codec_params); | 970 | soc_pcm_set_dai_params(codec_dai, &codec_params); |
| 975 | codec_dai->channels = params_channels(&codec_params); | ||
| 976 | codec_dai->sample_bits = snd_pcm_format_physical_width( | ||
| 977 | params_format(&codec_params)); | ||
| 978 | |||
| 979 | snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); | 971 | snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); |
| 980 | } | 972 | } |
| 981 | 973 | ||
| @@ -992,11 +984,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, · 10 unmodified lines | |||
| 992 | goto out; | 984 | goto out; |
| 993 | 985 | ||
| 994 | /* store the parameters for each DAI */ | 986 | /* store the parameters for each DAI */ |
| 995 | cpu_dai->rate = params_rate(params); | 987 | soc_pcm_set_dai_params(cpu_dai, params); |
| 996 | cpu_dai->channels = params_channels(params); | ||
| 997 | cpu_dai->sample_bits = | ||
| 998 | snd_pcm_format_physical_width(params_format(params)); | ||
| 999 | |||
| 1000 | snd_soc_dapm_update_dai(substream, params, cpu_dai); | 988 | snd_soc_dapm_update_dai(substream, params, cpu_dai); |
| 1001 | } | 989 | } |
| 1002 | 990 | ||
| @@ -1335,7 +1323,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, · 332 unmodified lines | |||
| 1335 | stream ? "capture" : "playback", | 1323 | stream ? "capture" : "playback", |
| 1336 | dpcm->be->dai_link->name, fe->dai_link->name); | 1324 | dpcm->be->dai_link->name, fe->dai_link->name); |
| 1337 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; | 1325 | dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; |
| 1338 | dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1326 | dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_BE); |
| 1339 | prune++; | 1327 | prune++; |
| 1340 | } | 1328 | } |
| 1341 | 1329 | ||
| @@ -1371,8 +1359,8 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, · 29 unmodified lines | |||
| 1371 | /* is there a valid BE rtd for this widget */ | 1359 | /* is there a valid BE rtd for this widget */ |
| 1372 | be = dpcm_get_be(card, widget, stream); | 1360 | be = dpcm_get_be(card, widget, stream); |
| 1373 | if (!be) { | 1361 | if (!be) { |
| 1374 | dev_err(fe->dev, "ASoC: no BE found for %s\n", | 1362 | dev_dbg(fe->dev, "ASoC: no BE found for %s\n", |
| 1375 | widget->name); | 1363 | widget->name); |
| 1376 | continue; | 1364 | continue; |
| 1377 | } | 1365 | } |
| 1378 | 1366 | ||
| @@ -1390,7 +1378,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, · 11 unmodified lines | |||
| 1390 | continue; | 1378 | continue; |
| 1391 | 1379 | ||
| 1392 | /* new */ | 1380 | /* new */ |
| 1393 | be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; | 1381 | dpcm_set_be_update_state(be, stream, SND_SOC_DPCM_UPDATE_BE); |
| 1394 | new++; | 1382 | new++; |
| 1395 | } | 1383 | } |
| 1396 | 1384 | ||
| @@ -1418,8 +1406,7 @@ void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) · 21 unmodified lines | |||
| 1418 | 1406 | ||
| 1419 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); | 1407 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); |
| 1420 | for_each_dpcm_be(fe, stream, dpcm) | 1408 | for_each_dpcm_be(fe, stream, dpcm) |
| 1421 | dpcm->be->dpcm[stream].runtime_update = | 1409 | dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO); |
| 1422 | SND_SOC_DPCM_UPDATE_NO; | ||
| 1423 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); | 1410 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); |
| 1424 | } | 1411 | } |
| 1425 | 1412 | ||
| @@ -1542,21 +1529,21 @@ unwind: · 116 unmodified lines | |||
| 1542 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, | 1529 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, |
| 1543 | struct snd_soc_pcm_stream *stream) | 1530 | struct snd_soc_pcm_stream *stream) |
| 1544 | { | 1531 | { |
| 1545 | runtime->hw.rate_min = stream->rate_min; | 1532 | struct snd_pcm_hardware *hw = &runtime->hw; |
| 1546 | runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); | 1533 | |
| 1547 | runtime->hw.channels_min = stream->channels_min; | 1534 | soc_pcm_hw_update_rate(hw, stream); |
| 1548 | runtime->hw.channels_max = stream->channels_max; | 1535 | soc_pcm_hw_update_chan(hw, stream); |
| 1549 | if (runtime->hw.formats) | 1536 | if (runtime->hw.formats) |
| 1550 | runtime->hw.formats &= stream->formats; | 1537 | runtime->hw.formats &= stream->formats; |
| 1551 | else | 1538 | else |
| 1552 | runtime->hw.formats = stream->formats; | 1539 | runtime->hw.formats = stream->formats; |
| 1553 | runtime->hw.rates = stream->rates; | ||
| 1554 | } | 1540 | } |
| 1555 | 1541 | ||
| 1556 | static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, | 1542 | static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, |
| 1557 | u64 *formats) | 1543 | struct snd_pcm_runtime *runtime) |
| 1558 | { | 1544 | { |
| 1559 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); | 1545 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1546 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
| 1560 | struct snd_soc_dpcm *dpcm; | 1547 | struct snd_soc_dpcm *dpcm; |
| 1561 | struct snd_soc_dai *dai; | 1548 | struct snd_soc_dai *dai; |
| 1562 | int stream = substream->stream; | 1549 | int stream = substream->stream; |
| @@ -1584,16 +1571,16 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, · 21 unmodified lines | |||
| 1584 | 1571 | ||
| 1585 | codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); | 1572 | codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); |
| 1586 | 1573 | ||
| 1587 | *formats &= codec_stream->formats; | 1574 | soc_pcm_hw_update_format(hw, codec_stream); |
| 1588 | } | 1575 | } |
| 1589 | } | 1576 | } |
| 1590 | } | 1577 | } |
| 1591 | 1578 | ||
| 1592 | static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, | 1579 | static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, |
| 1593 | unsigned int *channels_min, | 1580 | struct snd_pcm_runtime *runtime) |
| 1594 | unsigned int *channels_max) | ||
| 1595 | { | 1581 | { |
| 1596 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); | 1582 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1583 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
| 1597 | struct snd_soc_dpcm *dpcm; | 1584 | struct snd_soc_dpcm *dpcm; |
| 1598 | int stream = substream->stream; | 1585 | int stream = substream->stream; |
| 1599 | 1586 | ||
| @@ -1622,10 +1609,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, · 22 unmodified lines | |||
| 1622 | 1609 | ||
| 1623 | cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); | 1610 | cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); |
| 1624 | 1611 | ||
| 1625 | *channels_min = max(*channels_min, | 1612 | soc_pcm_hw_update_chan(hw, cpu_stream); |
| 1626 | cpu_stream->channels_min); | ||
| 1627 | *channels_max = min(*channels_max, | ||
| 1628 | cpu_stream->channels_max); | ||
| 1629 | } | 1613 | } |
| 1630 | 1614 | ||
| 1631 | /* | 1615 | /* |
| @@ -1635,20 +1619,16 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, · 3 unmodified lines | |||
| 1635 | if (be->num_codecs == 1) { | 1619 | if (be->num_codecs == 1) { |
| 1636 | codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream); | 1620 | codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream); |
| 1637 | 1621 | ||
| 1638 | *channels_min = max(*channels_min, | 1622 | soc_pcm_hw_update_chan(hw, codec_stream); |
| 1639 | codec_stream->channels_min); | ||
| 1640 | *channels_max = min(*channels_max, | ||
| 1641 | codec_stream->channels_max); | ||
| 1642 | } | 1623 | } |
| 1643 | } | 1624 | } |
| 1644 | } | 1625 | } |
| 1645 | 1626 | ||
| 1646 | static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, | 1627 | static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, |
| 1647 | unsigned int *rates, | 1628 | struct snd_pcm_runtime *runtime) |
| 1648 | unsigned int *rate_min, | ||
| 1649 | unsigned int *rate_max) | ||
| 1650 | { | 1629 | { |
| 1651 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); | 1630 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1631 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
| 1652 | struct snd_soc_dpcm *dpcm; | 1632 | struct snd_soc_dpcm *dpcm; |
| 1653 | int stream = substream->stream; | 1633 | int stream = substream->stream; |
| 1654 | 1634 | ||
| @@ -1676,9 +1656,7 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, · 21 unmodified lines | |||
| 1676 | 1656 | ||
| 1677 | pcm = snd_soc_dai_get_pcm_stream(dai, stream); | 1657 | pcm = snd_soc_dai_get_pcm_stream(dai, stream); |
| 1678 | 1658 | ||
| 1679 | *rate_min = max(*rate_min, pcm->rate_min); | 1659 | soc_pcm_hw_update_rate(hw, pcm); |
| 1680 | *rate_max = min_not_zero(*rate_max, pcm->rate_max); | ||
| 1681 | *rates = snd_pcm_rate_mask_intersect(*rates, pcm->rates); | ||
| 1682 | } | 1660 | } |
| 1683 | } | 1661 | } |
| 1684 | } | 1662 | } |
| @@ -1686,10 +1664,13 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, · 1 unmodified line | |||
| 1686 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) | 1664 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) |
| 1687 | { | 1665 | { |
| 1688 | struct snd_pcm_runtime *runtime = substream->runtime; | 1666 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1667 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
| 1689 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | 1668 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
267 more lines aren’t shown here.
This diff is large: its 844 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 411 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 420 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 423 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 453 lines aren’t shown here.
This diff is large: its 364 lines aren’t shown here.
This diff is large: its 459 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 16 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 115 lines aren’t shown here.
This diff is large: its 463 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.