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 | 71 | description: CPU to Codec rate channels. |
| 72 | 72 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 73 | 73 | |
| 74 | − required: | |
| 75 | − - remote-endpoint | |
| 76 | − | |
| 77 | 74 | ports: |
| 78 | 75 | description: multi OF-Graph subnode |
| 79 | 76 | type: object |
| @@ -15,9 +15,14 @@ properties: · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | compatible: |
| 17 | 17 | oneOf: |
| 18 | − - const: ingenic,jz4770-codec | |
| 19 | − - const: ingenic,jz4725b-codec | |
| 20 | − - const: ingenic,jz4740-codec | |
| 18 | + - enum: | |
| 19 | + - ingenic,jz4770-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 | 27 | reg: |
| 23 | 28 | maxItems: 1 |
| @@ -18,6 +18,7 @@ properties: · 17 unmodified lines | ||
| 18 | 18 | enum: |
| 19 | 19 | - intel,keembay-i2s |
| 20 | 20 | - intel,keembay-tdm |
| 21 | + - intel,keembay-hdmi-i2s | |
| 21 | 22 | |
| 22 | 23 | "#sound-dai-cells": |
| 23 | 24 | const: 0 |
| @@ -45,6 +46,16 @@ properties: · 21 unmodified lines | ||
| 45 | 46 | - const: osc |
| 46 | 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 | 59 | required: |
| 49 | 60 | - compatible |
| 50 | 61 | - "#sound-dai-cells" |
| @@ -70,4 +81,6 @@ examples: · 19 unmodified lines | ||
| 70 | 81 | interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; |
| 71 | 82 | clock-names = "osc", "apb_clk"; |
| 72 | 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 | 23 | $ref: "/schemas/types.yaml#/definitions/phandle" |
| 24 | 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 | 30 | additionalProperties: false |
| 27 | 31 | |
| 28 | 32 | required: |
| @@ -35,6 +39,7 @@ examples: · 6 unmodified lines | ||
| 35 | 39 | sound: mt8192-sound { |
| 36 | 40 | compatible = "mediatek,mt8192_mt6359_rt1015_rt5682"; |
| 37 | 41 | mediatek,platform = <&afe>; |
| 42 | + mediatek,hdmi-codec = <&anx_bridge_dp>; | |
| 38 | 43 | pinctrl-names = "aud_clk_mosi_off", |
| 39 | 44 | "aud_clk_mosi_on"; |
| 40 | 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 | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | |
| 20 | +allOf: | |
| 21 | + - $ref: audio-graph-port.yaml# | |
| 22 | + | |
| 20 | 23 | properties: |
| 21 | 24 | $nodename: |
| 22 | 25 | pattern: "^dspk@[0-9a-f]*$" |
| @@ -55,6 +58,19 @@ properties: · 32 unmodified lines | ||
| 55 | 58 | The name can be "DSPK1" or "DSPKx", where x depends on the maximum |
| 56 | 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 | 74 | required: |
| 59 | 75 | - compatible |
| 60 | 76 | - reg |
| @@ -64,7 +80,7 @@ required: · 3 unmodified lines | ||
| 64 | 80 | - assigned-clock-parents |
| 65 | 81 | - sound-name-prefix |
| 66 | 82 | |
| 67 | −additionalProperties: false | |
| 83 | +unevaluatedProperties: false | |
| 68 | 84 | |
| 69 | 85 | examples: |
| 70 | 86 | - | |
| @@ -17,6 +17,9 @@ maintainers: · 16 unmodified lines | ||
| 17 | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | |
| 20 | +allOf: | |
| 21 | + - $ref: audio-graph-port.yaml# | |
| 22 | + | |
| 20 | 23 | properties: |
| 21 | 24 | $nodename: |
| 22 | 25 | pattern: "^admaif@[0-9a-f]*$" |
| @@ -37,6 +40,14 @@ properties: · 14 unmodified lines | ||
| 37 | 40 | |
| 38 | 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 | 51 | if: |
| 41 | 52 | properties: |
| 42 | 53 | compatible: |
| @@ -81,7 +92,7 @@ required: · 38 unmodified lines | ||
| 81 | 92 | - dmas |
| 82 | 93 | - dma-names |
| 83 | 94 | |
| 84 | −additionalProperties: false | |
| 95 | +unevaluatedProperties: false | |
| 85 | 96 | |
| 86 | 97 | examples: |
| 87 | 98 | - | |
| @@ -17,6 +17,9 @@ maintainers: · 16 unmodified lines | ||
| 17 | 17 | - Jon Hunter <jonathanh@nvidia.com> |
| 18 | 18 | - Sameer Pujar <spujar@nvidia.com> |
| 19 | 19 | |
| 20 | +allOf: | |
| 21 | + - $ref: audio-graph-port.yaml# | |
| 22 | + | |
| 20 | 23 | properties: |
| 21 | 24 | $nodename: |
| 22 | 25 | pattern: "^ahub@[0-9a-f]*$" |
| @@ -56,6 +59,13 @@ properties: · 33 unmodified lines | ||
| 56 | 59 | |
| 57 | 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 | 69 | required: |
| 60 | 70 | - compatible |
| 61 | 71 | - reg |
| @@ -67,8 +77,7 @@ required: · 5 unmodified lines | ||
| 67 | 77 | - "#size-cells" |
| 68 | 78 | - ranges |
| 69 | 79 | |
| 70 | −additionalProperties: | |
| 71 | − type: object | |
| 80 | +unevaluatedProperties: false | |
| 72 | 81 | |
| 73 | 82 | examples: |
| 74 | 83 | - | |
| @@ -16,6 +16,9 @@ maintainers: · 15 unmodified lines | ||
| 16 | 16 | - Jon Hunter <jonathanh@nvidia.com> |
| 17 | 17 | - Sameer Pujar <spujar@nvidia.com> |
| 18 | 18 | |
| 19 | +allOf: | |
| 20 | + - $ref: audio-graph-port.yaml# | |
| 21 | + | |
| 19 | 22 | properties: |
| 20 | 23 | $nodename: |
| 21 | 24 | pattern: "^dmic@[0-9a-f]*$" |
| @@ -56,6 +59,19 @@ properties: · 34 unmodified lines | ||
| 56 | 59 | The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends |
| 57 | 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 | 75 | required: |
| 60 | 76 | - compatible |
| 61 | 77 | - reg |
| @@ -64,7 +80,7 @@ required: · 2 unmodified lines | ||
| 64 | 80 | - assigned-clocks |
| 65 | 81 | - assigned-clock-parents |
| 66 | 82 | |
| 67 | −additionalProperties: false | |
| 83 | +unevaluatedProperties: false | |
| 68 | 84 | |
| 69 | 85 | examples: |
| 70 | 86 | - | |
| @@ -16,6 +16,9 @@ maintainers: · 15 unmodified lines | ||
| 16 | 16 | - Jon Hunter <jonathanh@nvidia.com> |
| 17 | 17 | - Sameer Pujar <spujar@nvidia.com> |
| 18 | 18 | |
| 19 | +allOf: | |
| 20 | + - $ref: audio-graph-port.yaml# | |
| 21 | + | |
| 19 | 22 | properties: |
| 20 | 23 | $nodename: |
| 21 | 24 | pattern: "^i2s@[0-9a-f]*$" |
| @@ -74,6 +77,19 @@ properties: · 52 unmodified lines | ||
| 74 | 77 | The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends |
| 75 | 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 | 93 | required: |
| 78 | 94 | - compatible |
| 79 | 95 | - reg |
| @@ -82,7 +98,7 @@ required: · 2 unmodified lines | ||
| 82 | 98 | - assigned-clocks |
| 83 | 99 | - assigned-clock-parents |
| 84 | 100 | |
| 85 | −additionalProperties: false | |
| 101 | +unevaluatedProperties: false | |
| 86 | 102 | |
| 87 | 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 | 404 | /* DAI base */ |
| 405 | 405 | rcar_sound,dai { |
| 406 | 406 | dai0 { |
| 407 | − playback = <&ssi5 &src5>; | |
| 407 | + playback = <&ssi5>, <&src5>; | |
| 408 | 408 | capture = <&ssi6>; |
| 409 | 409 | }; |
| 410 | 410 | dai1 { |
| @@ -430,8 +430,8 @@ examples: · 19 unmodified lines | ||
| 430 | 430 | bitclock-master = <&rsnd_endpoint0>; |
| 431 | 431 | frame-master = <&rsnd_endpoint0>; |
| 432 | 432 | |
| 433 | − playback = <&ssi0 &src0 &dvc0>; | |
| 434 | − capture = <&ssi1 &src1 &dvc1>; | |
| 433 | + playback = <&ssi0>, <&src0>, <&dvc0>; | |
| 434 | + capture = <&ssi1>, <&src1>, <&dvc1>; | |
| 435 | 435 | }; |
| 436 | 436 | }; |
| 437 | 437 | }; |
| @@ -37,10 +37,21 @@ Optional properties: · 36 unmodified lines | ||
| 37 | 37 | - realtek,jd-src |
| 38 | 38 | 0: No JD is used |
| 39 | 39 | 1: using JD3 as JD source |
| 40 | + 2: JD source for Intel HDA header | |
| 40 | 41 | |
| 41 | 42 | - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. |
| 42 | 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 | 55 | Pins on the device (for linking into audio routes) for RT5659/RT5658: |
| 45 | 56 | |
| 46 | 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 | 54 | resets: |
| 55 | 55 | maxItems: 1 |
| 56 | 56 | |
| 57 | + "#clock-cells": | |
| 58 | + description: Configure the I2S device as MCLK clock provider. | |
| 59 | + const: 0 | |
| 60 | + | |
| 57 | 61 | required: |
| 58 | 62 | - compatible |
| 59 | 63 | - "#sound-dai-cells" |
| @@ -9,6 +9,9 @@ Required properties: · 8 unmodified lines | ||
| 9 | 9 | - reg : the I2C address of the device. |
| 10 | 10 | |
| 11 | 11 | Optional properties: |
| 12 | + | |
| 13 | + - clocks : The clock source of the mclk | |
| 14 | + | |
| 12 | 15 | - spk-mono: This is a boolean property. If present, the SPK_MONO bit |
| 13 | 16 | of R51 (Class D Control 2) gets set, indicating that the speaker is |
| 14 | 17 | in mono mode. |
| @@ -27,6 +30,7 @@ Example: · 12 unmodified lines | ||
| 27 | 30 | wm8962: codec@1a { |
| 28 | 31 | compatible = "wlf,wm8962"; |
| 29 | 32 | reg = <0x1a>; |
| 33 | + clocks = <&clks IMX6QDL_CLK_CKO>; | |
| 30 | 34 | |
| 31 | 35 | gpio-cfg = < |
| 32 | 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 | 14 | powersave |
| 15 | 15 | oss-emulation |
| 16 | 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 | 51 | struct isa_driver *isa_driver = dev->platform_data; |
| 52 | 52 | |
| 53 | 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 | 56 | return 0; |
| 57 | 57 | } |
| @@ -282,7 +282,7 @@ static int elektor_probe(struct device *dev, unsigned int id) · 281 unmodified lines | ||
| 282 | 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 | 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 | 298 | iounmap(base_iomem); |
| 299 | 299 | release_mem_region(base, 2); |
| 300 | 300 | } |
| 301 | − | |
| 302 | − return 0; | |
| 303 | 301 | } |
| 304 | 302 | |
| 305 | 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 | 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 | 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 | 170 | free_irq(irq, &pca_isa_ops); |
| 171 | 171 | } |
| 172 | 172 | release_region(base, IO_SIZE); |
| 173 | − | |
| 174 | − return 0; | |
| 175 | 173 | } |
| 176 | 174 | |
| 177 | 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 | 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 | 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 | 182 | release_region(HTCPEN_PORT_INDEX, 2); |
| 183 | 183 | release_region(HTCPEN_PORT_INIT, 1); |
| 184 | 184 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); |
| 185 | − | |
| 186 | − return 0; | |
| 187 | 185 | } |
| 188 | 186 | |
| 189 | 187 | #ifdef CONFIG_PM |
| @@ -273,8 +273,8 @@ err_dev_reg: · 272 unmodified lines | ||
| 273 | 273 | return res; |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | −static int radio_isa_common_remove(struct radio_isa_card *isa, | |
| 277 | − unsigned region_size) | |
| 276 | +static void radio_isa_common_remove(struct radio_isa_card *isa, | |
| 277 | + unsigned region_size) | |
| 278 | 278 | { |
| 279 | 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 | 285 | release_region(isa->io, region_size); |
| 286 | 286 | v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card); |
| 287 | 287 | kfree(isa); |
| 288 | − return 0; | |
| 289 | 288 | } |
| 290 | 289 | |
| 291 | 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 | 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 | 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 | 346 | EXPORT_SYMBOL_GPL(radio_isa_remove); |
| 348 | 347 | |
| @@ -91,7 +91,7 @@ struct radio_isa_driver { · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | int radio_isa_match(struct device *pdev, unsigned int dev); |
| 93 | 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 | 95 | #ifdef CONFIG_PNP |
| 96 | 96 | int radio_isa_pnp_probe(struct pnp_dev *dev, |
| 97 | 97 | const struct pnp_device_id *dev_id); |
| @@ -293,11 +293,9 @@ static void fmr2_remove(struct fmr2 *fmr2) · 292 unmodified lines | ||
| 293 | 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 | 298 | fmr2_remove(dev_get_drvdata(pdev)); |
| 299 | − | |
| 300 | − return 0; | |
| 301 | 299 | } |
| 302 | 300 | |
| 303 | 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 | 797 | EXPORT_SYMBOL_GPL(arizona_pm_ops); |
| 798 | 798 | |
| 799 | 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 | 800 | static int arizona_of_get_core_pdata(struct arizona *arizona) |
| 812 | 801 | { |
| 813 | 802 | struct arizona_pdata *pdata = &arizona->pdata; |
| @@ -23,14 +23,16 @@ · 22 unmodified lines | ||
| 23 | 23 | static int arizona_i2c_probe(struct i2c_client *i2c, |
| 24 | 24 | const struct i2c_device_id *id) |
| 25 | 25 | { |
| 26 | + const void *match_data; | |
| 26 | 27 | struct arizona *arizona; |
| 27 | 28 | const struct regmap_config *regmap_config = NULL; |
| 28 | − unsigned long type; | |
| 29 | + unsigned long type = 0; | |
| 29 | 30 | int ret; |
| 30 | 31 | |
| 31 | − if (i2c->dev.of_node) | |
| 32 | − type = arizona_of_get_type(&i2c->dev); | |
| 33 | − else | |
| 32 | + match_data = device_get_match_data(&i2c->dev); | |
| 33 | + if (match_data) | |
| 34 | + type = (unsigned long)match_data; | |
| 35 | + else if (id) | |
| 34 | 36 | type = id->driver_data; |
| 35 | 37 | |
| 36 | 38 | switch (type) { |
| @@ -115,6 +117,7 @@ static struct i2c_driver arizona_i2c_driver = { · 78 unmodified lines | ||
| 115 | 117 | |
| 116 | 118 | module_i2c_driver(arizona_i2c_driver); |
| 117 | 119 | |
| 120 | +MODULE_SOFTDEP("pre: arizona_ldo1"); | |
| 118 | 121 | MODULE_DESCRIPTION("Arizona I2C bus interface"); |
| 119 | 122 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 120 | 123 | MODULE_LICENSE("GPL"); |
| @@ -7,7 +7,10 @@ · 6 unmodified lines | ||
| 7 | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <linux/acpi.h> | |
| 10 | 11 | #include <linux/err.h> |
| 12 | +#include <linux/gpio/consumer.h> | |
| 13 | +#include <linux/gpio/machine.h> | |
| 11 | 14 | #include <linux/module.h> |
| 12 | 15 | #include <linux/pm_runtime.h> |
| 13 | 16 | #include <linux/regmap.h> |
| @@ -15,22 +18,141 @@ · 1 unmodified line | ||
| 15 | 18 | #include <linux/slab.h> |
| 16 | 19 | #include <linux/spi/spi.h> |
| 17 | 20 | #include <linux/of.h> |
| 21 | +#include <uapi/linux/input-event-codes.h> | |
| 18 | 22 | |
| 19 | 23 | #include <linux/mfd/arizona/core.h> |
| 20 | 24 | |
| 21 | 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 | 143 | static int arizona_spi_probe(struct spi_device *spi) |
| 24 | 144 | { |
| 25 | 145 | const struct spi_device_id *id = spi_get_device_id(spi); |
| 146 | + const void *match_data; | |
| 26 | 147 | struct arizona *arizona; |
| 27 | 148 | const struct regmap_config *regmap_config = NULL; |
| 28 | − unsigned long type; | |
| 149 | + unsigned long type = 0; | |
| 29 | 150 | int ret; |
| 30 | 151 | |
| 31 | − if (spi->dev.of_node) | |
| 32 | − type = arizona_of_get_type(&spi->dev); | |
| 33 | − else | |
| 152 | + match_data = device_get_match_data(&spi->dev); | |
| 153 | + if (match_data) | |
| 154 | + type = (unsigned long)match_data; | |
| 155 | + else if (id) | |
| 34 | 156 | type = id->driver_data; |
| 35 | 157 | |
| 36 | 158 | switch (type) { |
| @@ -75,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi) · 38 unmodified lines | ||
| 75 | 197 | arizona->dev = &spi->dev; |
| 76 | 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 | 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 | 230 | .name = "arizona", |
| 103 | 231 | .pm = &arizona_pm_ops, |
| 104 | 232 | .of_match_table = of_match_ptr(arizona_of_match), |
| 233 | + .acpi_match_table = ACPI_PTR(arizona_acpi_match), | |
| 105 | 234 | }, |
| 106 | 235 | .probe = arizona_spi_probe, |
| 107 | 236 | .remove = arizona_spi_remove, |
| @@ -110,6 +239,7 @@ static struct spi_driver arizona_spi_driver = { · 2 unmodified lines | ||
| 110 | 239 | |
| 111 | 240 | module_spi_driver(arizona_spi_driver); |
| 112 | 241 | |
| 242 | +MODULE_SOFTDEP("pre: arizona_ldo1"); | |
| 113 | 243 | MODULE_DESCRIPTION("Arizona SPI bus interface"); |
| 114 | 244 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 115 | 245 | MODULE_LICENSE("GPL"); |
| @@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona); · 49 unmodified lines | ||
| 50 | 50 | int arizona_irq_init(struct arizona *arizona); |
| 51 | 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 | 53 | #endif |
| @@ -159,7 +159,7 @@ static int tscan1_probe(struct device *dev, unsigned id) · 158 unmodified lines | ||
| 159 | 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 | 164 | struct net_device *netdev; |
| 165 | 165 | struct sja1000_priv *priv; |
| @@ -179,8 +179,6 @@ static int tscan1_remove(struct device *dev, unsigned id /*unused*/) · 13 unmodified lines | ||
| 179 | 179 | release_region(pld_base, TSCAN1_PLD_SIZE); |
| 180 | 180 | |
| 181 | 181 | free_sja1000dev(netdev); |
| 182 | − | |
| 183 | − return 0; | |
| 184 | 182 | } |
| 185 | 183 | |
| 186 | 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 | 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 | 339 | unsigned int ndev) |
| 340 | 340 | { |
| 341 | 341 | el3_device_remove(pdev); |
| 342 | 342 | dev_set_drvdata(pdev, NULL); |
| 343 | − return 0; | |
| 344 | 343 | } |
| 345 | 344 | |
| 346 | 345 | #ifdef CONFIG_PM |
| @@ -11459,12 +11459,11 @@ static int advansys_isa_probe(struct device *dev, unsigned int id) · 11458 unmodified lines | ||
| 11459 | 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 | 11464 | int ioport = _asc_def_iop_base[id]; |
| 11465 | 11465 | advansys_release(dev_get_drvdata(dev)); |
| 11466 | 11466 | release_region(ioport, ASC_IOADR_GAP); |
| 11467 | − return 0; | |
| 11468 | 11467 | } |
| 11469 | 11468 | |
| 11470 | 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 | 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 | 1029 | unsigned int ndev) |
| 1030 | 1030 | { |
| 1031 | 1031 | aha1542_release(dev_get_drvdata(pdev)); |
| 1032 | 1032 | dev_set_drvdata(pdev, NULL); |
| 1033 | − return 0; | |
| 1034 | 1033 | } |
| 1035 | 1034 | |
| 1036 | 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 | 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 | 180 | struct Scsi_Host *sh = dev_get_drvdata(dev); |
| 181 | 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 | 183 | fdomain_destroy(sh); |
| 184 | 184 | release_region(base, FDOMAIN_REGION_SIZE); |
| 185 | 185 | dev_set_drvdata(dev, NULL); |
| 186 | − return 0; | |
| 187 | 186 | } |
| 188 | 187 | |
| 189 | 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 | 720 | return 1; |
| 721 | 721 | } |
| 722 | 722 | |
| 723 | −static int generic_NCR5380_isa_remove(struct device *pdev, | |
| 724 | − unsigned int ndev) | |
| 723 | +static void generic_NCR5380_isa_remove(struct device *pdev, | |
| 724 | + unsigned int ndev) | |
| 725 | 725 | { |
| 726 | 726 | generic_NCR5380_release_resources(dev_get_drvdata(pdev)); |
| 727 | 727 | dev_set_drvdata(pdev, NULL); |
| 728 | − return 0; | |
| 729 | 728 | } |
| 730 | 729 | |
| 731 | 730 | static struct isa_driver generic_NCR5380_isa_driver = { |
| @@ -951,14 +951,11 @@ error_request_region: · 950 unmodified lines | ||
| 951 | 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 | 956 | if (debug >= DEBUG) |
| 957 | 957 | pr_debug("pcwd_isa_remove id=%d\n", id); |
| 958 | 958 | |
| 959 | − if (!pcwd_private.io_addr) | |
| 960 | − return 1; | |
| 961 | − | |
| 962 | 959 | /* Disable the board */ |
| 963 | 960 | if (!nowayout) |
| 964 | 961 | pcwd_stop(); |
| @@ -971,8 +968,6 @@ static int pcwd_isa_remove(struct device *dev, unsigned int id) · 6 unmodified lines | ||
| 971 | 968 | (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
| 972 | 969 | pcwd_private.io_addr = 0x0000; |
| 973 | 970 | cards_found--; |
| 974 | − | |
| 975 | − return 0; | |
| 976 | 971 | } |
| 977 | 972 | |
| 978 | 973 | static void pcwd_isa_shutdown(struct device *dev, unsigned int id) |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | struct isa_driver { |
| 14 | 14 | int (*match)(struct device *, unsigned int); |
| 15 | 15 | int (*probe)(struct device *, unsigned int); |
| 16 | − int (*remove)(struct device *, unsigned int); | |
| 16 | + void (*remove)(struct device *, unsigned int); | |
| 17 | 17 | void (*shutdown)(struct device *, unsigned int); |
| 18 | 18 | int (*suspend)(struct device *, unsigned int, pm_message_t); |
| 19 | 19 | int (*resume)(struct device *, unsigned int); |
| @@ -4610,6 +4610,7 @@ enum ec_codec_i2s_rx_subcmd { · 4609 unmodified lines | ||
| 4610 | 4610 | EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, |
| 4611 | 4611 | EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, |
| 4612 | 4612 | EC_CODEC_I2S_RX_SET_BCLK = 0x4, |
| 4613 | + EC_CODEC_I2S_RX_RESET = 0x5, | |
| 4613 | 4614 | EC_CODEC_I2S_RX_SUBCMD_COUNT, |
| 4614 | 4615 | }; |
| 4615 | 4616 | |
| @@ -122,6 +122,9 @@ struct snd_card { · 121 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */ |
| 124 | 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 | 129 | #ifdef CONFIG_PM |
| 127 | 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 | 183 | extern int snd_major; |
| 181 | 184 | extern int snd_ecards_limit; |
| 182 | 185 | extern struct class *sound_class; |
| 186 | +#ifdef CONFIG_SND_DEBUG | |
| 187 | +extern struct dentry *sound_debugfs_root; | |
| 188 | +#endif | |
| 183 | 189 | |
| 184 | 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 | 66 | * @chan_name: Custom channel name to use when requesting DMA channel. |
| 67 | 67 | * @fifo_size: FIFO size of the DAI controller in bytes |
| 68 | 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 | 73 | struct snd_dmaengine_dai_dma_data { |
| 71 | 74 | dma_addr_t addr; |
| @@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data { · 4 unmodified lines | ||
| 76 | 79 | const char *chan_name; |
| 77 | 80 | unsigned int fifo_size; |
| 78 | 81 | unsigned int flags; |
| 82 | + void *peripheral_config; | |
| 83 | + size_t peripheral_size; | |
| 79 | 84 | }; |
| 80 | 85 | |
| 81 | 86 | void snd_dmaengine_pcm_set_config_from_dai_data( |
| @@ -9,8 +9,10 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 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 | 18 | #endif /* __GRAPH_CARD_H */ |
| @@ -241,6 +241,8 @@ struct hdac_bus_ops { · 240 unmodified lines | ||
| 241 | 241 | /* get a response from the last command */ |
| 242 | 242 | int (*get_response)(struct hdac_bus *bus, unsigned int addr, |
| 243 | 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 | 380 | int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr, |
| 379 | 381 | unsigned int cmd, unsigned int *res); |
| 380 | 382 | |
| 381 | −static inline void snd_hdac_codec_link_up(struct hdac_device *codec) | |
| 382 | −{ | |
| 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 | −} | |
| 383 | +void snd_hdac_codec_link_up(struct hdac_device *codec); | |
| 384 | +void snd_hdac_codec_link_down(struct hdac_device *codec); | |
| 390 | 385 | |
| 391 | 386 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); |
| 392 | 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 | 395 | void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus); |
| 401 | 396 | void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus); |
| 402 | 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 | 400 | void snd_hdac_bus_update_rirb(struct hdac_bus *bus); |
| 405 | 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 | 131 | int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link); |
| 132 | 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 | 136 | /* update register macro */ |
| 135 | 137 | #define snd_hdac_updatel(addr, reg, mask, val) \ |
| 136 | 138 | writel(((readl(addr + reg) & ~(mask)) | (val)), \ |
| @@ -34,6 +34,11 @@ struct hdmi_codec_daifmt { · 33 unmodified lines | ||
| 34 | 34 | unsigned int frame_clk_inv:1; |
| 35 | 35 | unsigned int bit_clk_master:1; |
| 36 | 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 | 67 | char name[100]; |
| 68 | 68 | unsigned int key[6]; /* Keep in sync with definitions above */ |
| 69 | 69 | #endif /* CONFIG_SND_JACK_INPUT_DEV */ |
| 70 | + int hw_status_cache; | |
| 70 | 71 | void *private_data; |
| 71 | 72 | void (*private_free)(struct snd_jack *); |
| 72 | 73 | }; |
| @@ -22,6 +22,8 @@ struct rt5645_platform_data { · 21 unmodified lines | ||
| 22 | 22 | bool level_trigger_irq; |
| 23 | 23 | /* Invert JD1_1 status polarity */ |
| 24 | 24 | bool inv_jd1_1; |
| 25 | + /* Invert HP detect status polarity */ | |
| 26 | + bool inv_hp_pol; | |
| 25 | 27 | |
| 26 | 28 | /* Value to asign to snd_soc_card.long_name */ |
| 27 | 29 | const char *long_name; |
| @@ -353,6 +353,12 @@ int snd_soc_component_test_bits(struct snd_soc_component *component, · 352 unmodified lines | ||
| 353 | 353 | unsigned int reg, unsigned int mask, |
| 354 | 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 | 362 | /* component wide operations */ |
| 357 | 363 | int snd_soc_component_set_sysclk(struct snd_soc_component *component, |
| 358 | 364 | int clk_id, int source, |
| @@ -353,9 +353,9 @@ struct snd_soc_dai_driver { · 352 unmodified lines | ||
| 353 | 353 | /* DAI capabilities */ |
| 354 | 354 | struct snd_soc_pcm_stream capture; |
| 355 | 355 | struct snd_soc_pcm_stream playback; |
| 356 | − unsigned int symmetric_rates:1; | |
| 356 | + unsigned int symmetric_rate:1; | |
| 357 | 357 | unsigned int symmetric_channels:1; |
| 358 | − unsigned int symmetric_samplebits:1; | |
| 358 | + unsigned int symmetric_sample_bits:1; | |
| 359 | 359 | |
| 360 | 360 | /* probe ordering - for components with runtime dependencies */ |
| 361 | 361 | int probe_order; |
| @@ -685,9 +685,9 @@ struct snd_soc_dai_link { · 684 unmodified lines | ||
| 685 | 685 | unsigned int ignore_suspend:1; |
| 686 | 686 | |
| 687 | 687 | /* Symmetry requirements */ |
| 688 | − unsigned int symmetric_rates:1; | |
| 688 | + unsigned int symmetric_rate:1; | |
| 689 | 689 | unsigned int symmetric_channels:1; |
| 690 | − unsigned int symmetric_samplebits:1; | |
| 690 | + unsigned int symmetric_sample_bits:1; | |
| 691 | 691 | |
| 692 | 692 | /* Do not create a PCM for this DAI link (Backend link) */ |
| 693 | 693 | unsigned int no_pcm:1; |
| @@ -58,9 +58,9 @@ struct sof_ext_man_header { · 57 unmodified lines | ||
| 58 | 58 | /* Extended manifest elements types */ |
| 59 | 59 | enum sof_ext_man_elem_type { |
| 60 | 60 | SOF_EXT_MAN_ELEM_FW_VERSION = 0, |
| 61 | − SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW, | |
| 62 | − SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO, | |
| 63 | − SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO, | |
| 61 | + SOF_EXT_MAN_ELEM_WINDOW = 1, | |
| 62 | + SOF_EXT_MAN_ELEM_CC_VERSION = 2, | |
| 63 | + SOF_EXT_MAN_ELEM_DBG_ABI = 4, | |
| 64 | 64 | SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */ |
| 65 | 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 | 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 | 277 | .name = "ac97_operations", |
| 278 | 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 | 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 | 1017 | onyx->codec.owner = THIS_MODULE; |
| 1018 | 1018 | onyx->codec.init = onyx_init_codec; |
| 1019 | 1019 | onyx->codec.exit = onyx_exit_codec; |
| @@ -894,7 +894,7 @@ static int tas_i2c_probe(struct i2c_client *client, · 893 unmodified lines | ||
| 894 | 894 | /* seems that half is a saner default */ |
| 895 | 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 | 898 | tas->codec.owner = THIS_MODULE; |
| 899 | 899 | tas->codec.init = tas_init_codec; |
| 900 | 900 | tas->codec.exit = tas_exit_codec; |
| @@ -126,7 +126,7 @@ static int __init toonie_init(void) · 125 unmodified lines | ||
| 126 | 126 | if (!toonie) |
| 127 | 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 | 130 | toonie->codec.owner = THIS_MODULE; |
| 131 | 131 | toonie->codec.init = toonie_init_codec; |
| 132 | 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 | 28 | return err; |
| 29 | 29 | aoa_card = alsa_card->private_data; |
| 30 | 30 | aoa_card->alsa_card = alsa_card; |
| 31 | − strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver)); | |
| 32 | − strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname)); | |
| 33 | − strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname)); | |
| 34 | − strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername)); | |
| 31 | + strscpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver)); | |
| 32 | + strscpy(alsa_card->shortname, name, sizeof(alsa_card->shortname)); | |
| 33 | + strscpy(alsa_card->longname, name, sizeof(alsa_card->longname)); | |
| 34 | + strscpy(alsa_card->mixername, name, sizeof(alsa_card->mixername)); | |
| 35 | 35 | err = snd_card_register(aoa_card->alsa_card); |
| 36 | 36 | if (err < 0) { |
| 37 | 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 | 948 | ldev->gpio.methods->set_lineout(codec->gpio, 1); |
| 949 | 949 | ctl = snd_ctl_new1(&lineout_ctl, codec->gpio); |
| 950 | 950 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 951 | − strlcpy(ctl->id.name, | |
| 951 | + strscpy(ctl->id.name, | |
| 952 | 952 | "Headphone Switch", sizeof(ctl->id.name)); |
| 953 | 953 | ldev->lineout_ctrl = ctl; |
| 954 | 954 | aoa_snd_ctl_add(ctl); |
| @@ -962,14 +962,14 @@ static void layout_attached_codec(struct aoa_codec *codec) · 7 unmodified lines | ||
| 962 | 962 | ctl = snd_ctl_new1(&lineout_detect_choice, |
| 963 | 963 | ldev); |
| 964 | 964 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 965 | − strlcpy(ctl->id.name, | |
| 965 | + strscpy(ctl->id.name, | |
| 966 | 966 | "Headphone Detect Autoswitch", |
| 967 | 967 | sizeof(ctl->id.name)); |
| 968 | 968 | aoa_snd_ctl_add(ctl); |
| 969 | 969 | ctl = snd_ctl_new1(&lineout_detected, |
| 970 | 970 | ldev); |
| 971 | 971 | if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE) |
| 972 | − strlcpy(ctl->id.name, | |
| 972 | + strscpy(ctl->id.name, | |
| 973 | 973 | "Headphone Detected", |
| 974 | 974 | sizeof(ctl->id.name)); |
| 975 | 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 | 13 | int length; |
| 14 | 14 | |
| 15 | 15 | if (*sdev->modalias) { |
| 16 | − strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1); | |
| 16 | + strscpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1); | |
| 17 | 17 | strcat(buf, "\n"); |
| 18 | 18 | length = strlen(buf); |
| 19 | 19 | } else { |
| @@ -890,8 +890,8 @@ static struct aaci *aaci_init_card(struct amba_device *dev) · 889 unmodified lines | ||
| 890 | 890 | |
| 891 | 891 | card->private_free = aaci_free_card; |
| 892 | 892 | |
| 893 | − strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); | |
| 894 | − strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); | |
| 893 | + strscpy(card->driver, DRIVER_NAME, sizeof(card->driver)); | |
| 894 | + strscpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); | |
| 895 | 895 | snprintf(card->longname, sizeof(card->longname), |
| 896 | 896 | "%s PL%03x rev%u at 0x%08llx, irq %d", |
| 897 | 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 | 921 | pcm->private_data = aaci; |
| 922 | 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 | 926 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); |
| 927 | 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 | 235 | if (ret < 0) |
| 236 | 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 | 240 | ret = pxa2xx_ac97_pcm_new(card); |
| 241 | 241 | if (ret) |
| @@ -187,6 +187,15 @@ config SND_CTL_VALIDATION · 186 unmodified lines | ||
| 187 | 187 | from the driver are in the proper ranges or the check of the invalid |
| 188 | 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 | 199 | config SND_VMASTER |
| 191 | 200 | bool |
| 192 | 201 | |
| @@ -1132,7 +1132,7 @@ static void snd_compress_proc_done(struct snd_compr *compr) · 1131 unmodified lines | ||
| 1132 | 1132 | |
| 1133 | 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 | 1137 | #else |
| 1138 | 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 | 261 | kctl->id.device = ncontrol->device; |
| 262 | 262 | kctl->id.subdevice = ncontrol->subdevice; |
| 263 | 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 | 265 | if (strcmp(ncontrol->name, kctl->id.name) != 0) |
| 266 | 266 | pr_warn("ALSA: Control name '%s' truncated to '%s'\n", |
| 267 | 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 | 701 | return -ENOMEM; |
| 702 | 702 | down_read(&snd_ioctl_rwsem); |
| 703 | 703 | info->card = card->number; |
| 704 | − strlcpy(info->id, card->id, sizeof(info->id)); | |
| 705 | − strlcpy(info->driver, card->driver, sizeof(info->driver)); | |
| 706 | − strlcpy(info->name, card->shortname, sizeof(info->name)); | |
| 707 | − strlcpy(info->longname, card->longname, sizeof(info->longname)); | |
| 708 | − strlcpy(info->mixername, card->mixername, sizeof(info->mixername)); | |
| 709 | − strlcpy(info->components, card->components, sizeof(info->components)); | |
| 704 | + strscpy(info->id, card->id, sizeof(info->id)); | |
| 705 | + strscpy(info->driver, card->driver, sizeof(info->driver)); | |
| 706 | + strscpy(info->name, card->shortname, sizeof(info->name)); | |
| 707 | + strscpy(info->longname, card->longname, sizeof(info->longname)); | |
| 708 | + strscpy(info->mixername, card->mixername, sizeof(info->mixername)); | |
| 709 | + strscpy(info->components, card->components, sizeof(info->components)); | |
| 710 | 710 | up_read(&snd_ioctl_rwsem); |
| 711 | 711 | if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) { |
| 712 | 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 | 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 | 840 | memset32((u32 *)control->value.bytes.data + offset, pattern, |
| 841 | 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 | 929 | /* check whether the remaining area kept untouched */ |
| 930 | 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 | 932 | p = (u32 *)control->value.bytes.data + offset; |
| 933 | 933 | for (; offset < sizeof(control->value) / sizeof(u32); offset++, p++) { |
| 934 | 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 | 2137 | WARN(strlen(names[info->value.enumerated.item]) >= sizeof(info->value.enumerated.name), |
| 2138 | 2138 | "ALSA: too long item name '%s'\n", |
| 2139 | 2139 | names[info->value.enumerated.item]); |
| 2140 | − strlcpy(info->value.enumerated.name, | |
| 2140 | + strscpy(info->value.enumerated.name, | |
| 2141 | 2141 | names[info->value.enumerated.item], |
| 2142 | 2142 | sizeof(info->value.enumerated.name)); |
| 2143 | 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 | 36 | sid.index = 0; |
| 37 | 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 | 40 | while (snd_ctl_find_id(card, &sid)) { |
| 41 | 41 | sid.index++; |
| @@ -177,8 +177,8 @@ static int snd_hwdep_info(struct snd_hwdep *hw, · 176 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | memset(&info, 0, sizeof(info)); |
| 179 | 179 | info.card = hw->card->number; |
| 180 | − strlcpy(info.id, hw->id, sizeof(info.id)); | |
| 181 | − strlcpy(info.name, hw->name, sizeof(info.name)); | |
| 180 | + strscpy(info.id, hw->id, sizeof(info.id)); | |
| 181 | + strscpy(info.name, hw->name, sizeof(info.name)); | |
| 182 | 182 | info.iface = hw->iface; |
| 183 | 183 | if (copy_to_user(_info, &info, sizeof(info))) |
| 184 | 184 | return -EFAULT; |
| @@ -379,7 +379,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, · 194 unmodified lines | ||
| 379 | 379 | hwdep->card = card; |
| 380 | 380 | hwdep->device = device; |
| 381 | 381 | if (id) |
| 382 | − strlcpy(hwdep->id, id, sizeof(hwdep->id)); | |
| 382 | + strscpy(hwdep->id, id, sizeof(hwdep->id)); | |
| 383 | 383 | |
| 384 | 384 | snd_device_initialize(&hwdep->dev, card); |
| 385 | 385 | hwdep->dev.release = release_hwdep_device; |
| @@ -13,7 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/time.h> |
| 14 | 14 | #include <linux/ctype.h> |
| 15 | 15 | #include <linux/pm.h> |
| 16 | +#include <linux/debugfs.h> | |
| 16 | 17 | #include <linux/completion.h> |
| 18 | +#include <linux/interrupt.h> | |
| 17 | 19 | |
| 18 | 20 | #include <sound/core.h> |
| 19 | 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 | 164 | struct snd_card *card; |
| 163 | 165 | int err; |
| 166 | +#ifdef CONFIG_SND_DEBUG | |
| 167 | + char name[8]; | |
| 168 | +#endif | |
| 164 | 169 | |
| 165 | 170 | if (snd_BUG_ON(!card_ret)) |
| 166 | 171 | return -EINVAL; |
| @@ -174,7 +179,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid, · 7 unmodified lines | ||
| 174 | 179 | if (extra_size > 0) |
| 175 | 180 | card->private_data = (char *)card + sizeof(struct snd_card); |
| 176 | 181 | if (xid) |
| 177 | − strlcpy(card->id, xid, sizeof(card->id)); | |
| 182 | + strscpy(card->id, xid, sizeof(card->id)); | |
| 178 | 183 | err = 0; |
| 179 | 184 | mutex_lock(&snd_card_mutex); |
| 180 | 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 | 249 | dev_err(parent, "unable to create card info\n"); |
| 245 | 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 | 258 | *card_ret = card; |
| 248 | 259 | return 0; |
| 249 | 260 | |
| @@ -416,6 +427,9 @@ int snd_card_disconnect(struct snd_card *card) · 166 unmodified lines | ||
| 416 | 427 | /* notify all devices that we are disconnected */ |
| 417 | 428 | snd_device_disconnect_all(card); |
| 418 | 429 | |
| 430 | + if (card->sync_irq > 0) | |
| 431 | + synchronize_irq(card->sync_irq); | |
| 432 | + | |
| 419 | 433 | snd_info_card_disconnect(card); |
| 420 | 434 | if (card->registered) { |
| 421 | 435 | device_del(&card->card_dev); |
| @@ -477,6 +491,10 @@ static int snd_card_do_free(struct snd_card *card) · 55 unmodified lines | ||
| 477 | 491 | dev_warn(card->dev, "unable to free card info\n"); |
| 478 | 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 | 498 | if (card->release_completion) |
| 481 | 499 | complete(card->release_completion); |
| 482 | 500 | kfree(card); |
| @@ -526,6 +544,7 @@ int snd_card_free(struct snd_card *card) · 43 unmodified lines | ||
| 526 | 544 | return ret; |
| 527 | 545 | /* wait, until all devices are ready for the free operation */ |
| 528 | 546 | wait_for_completion(&released); |
| 547 | + | |
| 529 | 548 | return 0; |
| 530 | 549 | } |
| 531 | 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 | 642 | /* last resort... */ |
| 624 | 643 | dev_err(card->dev, "unable to set card id (%s)\n", id); |
| 625 | 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 | 8 | #include <linux/input.h> |
| 9 | 9 | #include <linux/slab.h> |
| 10 | 10 | #include <linux/module.h> |
| 11 | +#include <linux/ctype.h> | |
| 12 | +#include <linux/mm.h> | |
| 13 | +#include <linux/debugfs.h> | |
| 11 | 14 | #include <sound/jack.h> |
| 12 | 15 | #include <sound/core.h> |
| 13 | 16 | #include <sound/control.h> |
| @@ -16,6 +19,11 @@ struct snd_jack_kctl { · 2 unmodified lines | ||
| 16 | 19 | struct snd_kcontrol *kctl; |
| 17 | 20 | struct list_head list; /* list of controls belong to the same jack */ |
| 18 | 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 | 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 | 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 | 398 | static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl) |
| 113 | 399 | { |
| 114 | 400 | struct snd_jack_kctl *jack_kctl; |
| 115 | 401 | |
| 116 | 402 | jack_kctl = kctl->private_data; |
| 117 | 403 | if (jack_kctl) { |
| 404 | + snd_jack_debugfs_clear_inject_node(jack_kctl); | |
| 118 | 405 | list_del(&jack_kctl->list); |
| 119 | 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 | 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 | 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 | 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 | 629 | void snd_jack_report(struct snd_jack *jack, int status) |
| 341 | 630 | { |
| 342 | 631 | struct snd_jack_kctl *jack_kctl; |
| 632 | + unsigned int mask_bits = 0; | |
| 343 | 633 | #ifdef CONFIG_SND_JACK_INPUT_DEV |
| 344 | 634 | int i; |
| 345 | 635 | #endif |
| @@ -347,16 +637,21 @@ void snd_jack_report(struct snd_jack *jack, int status) · 1 unmodified line | ||
| 347 | 637 | if (!jack) |
| 348 | 638 | return; |
| 349 | 639 | |
| 640 | + jack->hw_status_cache = status; | |
| 641 | + | |
| 350 | 642 | list_for_each_entry(jack_kctl, &jack->kctl_list, list) |
| 351 | − snd_kctl_jack_report(jack->card, jack_kctl->kctl, | |
| 352 | − status & jack_kctl->mask_bits); | |
| 643 | + if (jack_kctl->sw_inject_enable) | |
| 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 | 649 | #ifdef CONFIG_SND_JACK_INPUT_DEV |
| 355 | 650 | if (!jack->input_dev) |
| 356 | 651 | return; |
| 357 | 652 | |
| 358 | 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 | 656 | if (jack->type & testbit) |
| 362 | 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 | 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 | 664 | if (jack->type & testbit) |
| 369 | 665 | input_report_switch(jack->input_dev, |
| 370 | 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 | 87 | struct mixer_info info; |
| 88 | 88 | |
| 89 | 89 | memset(&info, 0, sizeof(info)); |
| 90 | − strlcpy(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)); | |
| 90 | + strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); | |
| 91 | + strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); | |
| 92 | 92 | info.modify_counter = card->mixer_oss_change_count; |
| 93 | 93 | if (copy_to_user(_info, &info, sizeof(info))) |
| 94 | 94 | return -EFAULT; |
| @@ -103,8 +103,8 @@ static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer, · 8 unmodified lines | ||
| 103 | 103 | _old_mixer_info info; |
| 104 | 104 | |
| 105 | 105 | memset(&info, 0, sizeof(info)); |
| 106 | − strlcpy(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)); | |
| 106 | + strscpy(info.id, mixer && mixer->id[0] ? mixer->id : card->driver, sizeof(info.id)); | |
| 107 | + strscpy(info.name, mixer && mixer->name[0] ? mixer->name : card->mixername, sizeof(info.name)); | |
| 108 | 108 | if (copy_to_user(_info, &info, sizeof(info))) |
| 109 | 109 | return -EFAULT; |
| 110 | 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 | 419 | if (orange == 0) |
| 420 | 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 | 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 | 500 | memset(&id, 0, sizeof(id)); |
| 501 | 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 | 503 | id.index = index; |
| 504 | 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 | 1355 | mixer->oss_dev_alloc = 1; |
| 1356 | 1356 | mixer->card = card; |
| 1357 | 1357 | if (*card->mixername) |
| 1358 | − strlcpy(mixer->name, card->mixername, sizeof(mixer->name)); | |
| 1358 | + strscpy(mixer->name, card->mixername, sizeof(mixer->name)); | |
| 1359 | 1359 | else |
| 1360 | 1360 | snprintf(mixer->name, sizeof(mixer->name), |
| 1361 | 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 | 193 | if (plugin->src_format.rate < plugin->dst_format.rate) { |
| 194 | 194 | res = (((frames * data->pitch) + (BITS/2)) >> SHIFT); |
| 195 | 195 | } else { |
| 196 | − res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch); | |
| 196 | + res = DIV_ROUND_CLOSEST(frames << SHIFT, data->pitch); | |
| 197 | 197 | } |
| 198 | 198 | if (data->old_src_frames > 0) { |
| 199 | 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 | 224 | return 0; |
| 225 | 225 | data = (struct rate_priv *)plugin->extra_data; |
| 226 | 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 | 228 | } else { |
| 229 | 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 | 729 | init_waitqueue_head(&pcm->open_wait); |
| 730 | 730 | INIT_LIST_HEAD(&pcm->list); |
| 731 | 731 | if (id) |
| 732 | − strlcpy(pcm->id, id, sizeof(pcm->id)); | |
| 732 | + strscpy(pcm->id, id, sizeof(pcm->id)); | |
| 733 | 733 | |
| 734 | 734 | err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
| 735 | 735 | playback_count); |
| @@ -1095,22 +1095,23 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) · 359 unmodified lines | ||
| 1095 | 1095 | mutex_lock(&pcm->open_mutex); |
| 1096 | 1096 | wake_up(&pcm->open_wait); |
| 1097 | 1097 | list_del_init(&pcm->list); |
| 1098 | − for (cidx = 0; cidx < 2; cidx++) { | |
| 1099 | − for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) { | |
| 1100 | − snd_pcm_stream_lock_irq(substream); | |
| 1101 | − if (substream->runtime) { | |
| 1102 | − if (snd_pcm_running(substream)) | |
| 1103 | − snd_pcm_stop(substream, | |
| 1104 | − SNDRV_PCM_STATE_DISCONNECTED); | |
| 1105 | − /* to be sure, set the state unconditionally */ | |
| 1106 | − substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; | |
| 1107 | − wake_up(&substream->runtime->sleep); | |
| 1108 | − wake_up(&substream->runtime->tsleep); | |
| 1109 | − } | |
| 1110 | − snd_pcm_stream_unlock_irq(substream); | |
| 1098 | + | |
| 1099 | + for_each_pcm_substream(pcm, cidx, substream) { | |
| 1100 | + snd_pcm_stream_lock_irq(substream); | |
| 1101 | + if (substream->runtime) { | |
| 1102 | + if (snd_pcm_running(substream)) | |
| 1103 | + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); | |
| 1104 | + /* to be sure, set the state unconditionally */ | |
| 1105 | + substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED; | |
| 1106 | + wake_up(&substream->runtime->sleep); | |
| 1107 | + wake_up(&substream->runtime->tsleep); | |
| 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 | 1115 | pcm_call_notify(pcm, n_disconnect); |
| 1115 | 1116 | for (cidx = 0; cidx < 2; cidx++) { |
| 1116 | 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 | 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 | 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 | 64 | void __snd_pcm_xrun(struct snd_pcm_substream *substream); |
| 65 | 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 | 68 | #ifdef CONFIG_SND_DMA_SGBUF |
| 68 | 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 | 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 | 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 | 111 | struct snd_pcm_substream *substream; |
| 112 | 112 | int stream; |
| 113 | 113 | |
| 114 | − for (stream = 0; stream < 2; stream++) | |
| 115 | − for (substream = pcm->streams[stream].substream; substream; substream = substream->next) | |
| 116 | − snd_pcm_lib_preallocate_free(substream); | |
| 114 | + for_each_pcm_substream(pcm, stream, substream) | |
| 115 | + snd_pcm_lib_preallocate_free(substream); | |
| 117 | 116 | } |
| 118 | 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 | 245 | struct snd_pcm_substream *substream; |
| 247 | 246 | int stream; |
| 248 | 247 | |
| 249 | − for (stream = 0; stream < 2; stream++) | |
| 250 | − for (substream = pcm->streams[stream].substream; substream; | |
| 251 | − substream = substream->next) | |
| 252 | − preallocate_pages(substream, type, data, size, max, | |
| 253 | − managed); | |
| 248 | + for_each_pcm_substream(pcm, stream, substream) | |
| 249 | + preallocate_pages(substream, type, data, size, max, 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 | 209 | info->device = pcm->device; |
| 210 | 210 | info->stream = substream->stream; |
| 211 | 211 | info->subdevice = substream->number; |
| 212 | − strlcpy(info->id, pcm->id, sizeof(info->id)); | |
| 213 | − strlcpy(info->name, pcm->name, sizeof(info->name)); | |
| 212 | + strscpy(info->id, pcm->id, sizeof(info->id)); | |
| 213 | + strscpy(info->name, pcm->name, sizeof(info->name)); | |
| 214 | 214 | info->dev_class = pcm->dev_class; |
| 215 | 215 | info->dev_subclass = pcm->dev_subclass; |
| 216 | 216 | info->subdevices_count = pstr->substream_count; |
| 217 | 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 | 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 | 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 | 589 | substream->runtime->stop_operating = false; |
| 590 | − if (substream->ops->sync_stop) | |
| 590 | + if (substream->ops && substream->ops->sync_stop) | |
| 591 | 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 | 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 | 686 | if (atomic_read(&substream->mmap_count)) |
| 687 | 687 | return -EBADFD; |
| 688 | 688 | |
| 689 | − snd_pcm_sync_stop(substream); | |
| 689 | + snd_pcm_sync_stop(substream, true); | |
| 690 | 690 | |
| 691 | 691 | params->rmask = ~0U; |
| 692 | 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 | 810 | int result = 0; |
| 811 | 811 | |
| 812 | − snd_pcm_sync_stop(substream); | |
| 812 | + snd_pcm_sync_stop(substream, true); | |
| 813 | 813 | if (substream->ops->hw_free) |
| 814 | 814 | result = substream->ops->hw_free(substream); |
| 815 | 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 | 1421 | snd_pcm_state_t state) |
| 1422 | 1422 | { |
| 1423 | 1423 | if (substream->runtime->trigger_master == substream && |
| 1424 | − snd_pcm_running(substream)) | |
| 1424 | + snd_pcm_running(substream)) { | |
| 1425 | 1425 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); |
| 1426 | + substream->runtime->stop_operating = true; | |
| 1427 | + } | |
| 1426 | 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 | 1437 | runtime->status->state = state; |
| 1436 | 1438 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP); |
| 1437 | 1439 | } |
| 1438 | − runtime->stop_operating = true; | |
| 1439 | 1440 | wake_up(&runtime->sleep); |
| 1440 | 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 | 1616 | if (! snd_pcm_running(substream)) |
| 1616 | 1617 | return 0; |
| 1617 | 1618 | substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND); |
| 1619 | + runtime->stop_operating = true; | |
| 1618 | 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 | 1674 | if (! pcm) |
| 1673 | 1675 | return 0; |
| 1674 | 1676 | |
| 1675 | − for (stream = 0; stream < 2; stream++) { | |
| 1676 | − for (substream = pcm->streams[stream].substream; | |
| 1677 | − substream; substream = substream->next) { | |
| 1678 | − /* FIXME: the open/close code should lock this as well */ | |
| 1679 | − if (substream->runtime == NULL) | |
| 1680 | − continue; | |
| 1677 | + for_each_pcm_substream(pcm, stream, substream) { | |
| 1678 | + /* FIXME: the open/close code should lock this as well */ | |
| 1679 | + if (!substream->runtime) | |
| 1680 | + continue; | |
| 1681 | 1681 | |
| 1682 | − /* | |
| 1683 | − * Skip BE dai link PCM's that are internal and may | |
| 1684 | − * not have their substream ops set. | |
| 1685 | − */ | |
| 1686 | − if (!substream->ops) | |
| 1687 | − continue; | |
| 1682 | + /* | |
| 1683 | + * Skip BE dai link PCM's that are internal and may | |
| 1684 | + * not have their substream ops set. | |
| 1685 | + */ | |
| 1686 | + if (!substream->ops) | |
| 1687 | + continue; | |
| 1688 | 1688 | |
| 1689 | − err = snd_pcm_suspend(substream); | |
| 1690 | − if (err < 0 && err != -EBUSY) | |
| 1691 | − return err; | |
| 1692 | − } | |
| 1689 | + err = snd_pcm_suspend(substream); | |
| 1690 | + if (err < 0 && err != -EBUSY) | |
| 1691 | + return err; | |
| 1693 | 1692 | } |
| 1693 | + | |
| 1694 | + for_each_pcm_substream(pcm, stream, substream) | |
| 1695 | + snd_pcm_sync_stop(substream, false); | |
| 1696 | + | |
| 1694 | 1697 | return 0; |
| 1695 | 1698 | } |
| 1696 | 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 | 1739 | snd_pcm_trigger_tstamp(substream); |
| 1737 | 1740 | runtime->status->state = runtime->status->suspended_state; |
| 1738 | 1741 | snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); |
| 1739 | − snd_pcm_sync_stop(substream); | |
| 1740 | 1742 | } |
| 1741 | 1743 | |
| 1742 | 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 | 1868 | snd_pcm_state_t state) |
| 1867 | 1869 | { |
| 1868 | 1870 | int err; |
| 1869 | − snd_pcm_sync_stop(substream); | |
| 1871 | + snd_pcm_sync_stop(substream, true); | |
| 1870 | 1872 | err = substream->ops->prepare(substream); |
| 1871 | 1873 | if (err < 0) |
| 1872 | 1874 | return err; |
| @@ -1686,7 +1686,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, · 1685 unmodified lines | ||
| 1686 | 1686 | INIT_LIST_HEAD(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams); |
| 1687 | 1687 | |
| 1688 | 1688 | if (id != NULL) |
| 1689 | − strlcpy(rmidi->id, id, sizeof(rmidi->id)); | |
| 1689 | + strscpy(rmidi->id, id, sizeof(rmidi->id)); | |
| 1690 | 1690 | |
| 1691 | 1691 | snd_device_initialize(&rmidi->dev, card); |
| 1692 | 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 | 173 | snd_use_lock_init(&mdev->use_lock); |
| 174 | 174 | |
| 175 | 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 | 178 | /* create MIDI coder */ |
| 179 | 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 | 647 | inf->device = dev; |
| 648 | 648 | inf->dev_type = 0; /* FIXME: ?? */ |
| 649 | 649 | inf->capabilities = 0; /* FIXME: ?? */ |
| 650 | − strlcpy(inf->name, mdev->name, sizeof(inf->name)); | |
| 650 | + strscpy(inf->name, mdev->name, sizeof(inf->name)); | |
| 651 | 651 | snd_use_lock_free(&mdev->use_lock); |
| 652 | 652 | return 0; |
| 653 | 653 | } |
| @@ -107,7 +107,7 @@ snd_seq_oss_synth_probe(struct device *_dev) · 106 unmodified lines | ||
| 107 | 107 | snd_use_lock_init(&rec->use_lock); |
| 108 | 108 | |
| 109 | 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 | 112 | /* registration */ |
| 113 | 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 | 617 | inf->synth_subtype = 0; |
| 618 | 618 | inf->nr_voices = 16; |
| 619 | 619 | inf->device = dev; |
| 620 | − strlcpy(inf->name, minf.name, sizeof(inf->name)); | |
| 620 | + strscpy(inf->name, minf.name, sizeof(inf->name)); | |
| 621 | 621 | } else { |
| 622 | 622 | if ((rec = get_synthdev(dp, dev)) == NULL) |
| 623 | 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 | 625 | inf->synth_subtype = rec->synth_subtype; |
| 626 | 626 | inf->nr_voices = rec->nr_voices; |
| 627 | 627 | inf->device = dev; |
| 628 | − strlcpy(inf->name, rec->name, sizeof(inf->name)); | |
| 628 | + strscpy(inf->name, rec->name, sizeof(inf->name)); | |
| 629 | 629 | snd_use_lock_free(&rec->use_lock); |
| 630 | 630 | } |
| 631 | 631 | return 0; |
| @@ -1584,7 +1584,7 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, · 1583 unmodified lines | ||
| 1584 | 1584 | info->queue = q->queue; |
| 1585 | 1585 | info->owner = q->owner; |
| 1586 | 1586 | info->locked = q->locked; |
| 1587 | − strlcpy(info->name, q->name, sizeof(info->name)); | |
| 1587 | + strscpy(info->name, q->name, sizeof(info->name)); | |
| 1588 | 1588 | queuefree(q); |
| 1589 | 1589 | |
| 1590 | 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 | 290 | extlen = 0; |
| 291 | 291 | if (snd_seq_ev_is_variable(event)) { |
| 292 | 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 | 295 | if (ncells >= pool->total_elements) |
| 296 | 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 | 328 | /* set port name */ |
| 329 | 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 | 332 | /* set capabilities */ |
| 333 | 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 | 356 | return -EINVAL; |
| 357 | 357 | |
| 358 | 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 | 361 | /* get capabilities */ |
| 362 | 362 | info->capability = port->capability; |
| @@ -654,7 +654,7 @@ int snd_seq_event_port_attach(int client, · 291 unmodified lines | ||
| 654 | 654 | /* Set up the port */ |
| 655 | 655 | memset(&portinfo, 0, sizeof(portinfo)); |
| 656 | 656 | portinfo.addr.client = client; |
| 657 | − strlcpy(portinfo.name, portname ? portname : "Unnamed port", | |
| 657 | + strscpy(portinfo.name, portname ? portname : "Unnamed port", | |
| 658 | 658 | sizeof(portinfo.name)); |
| 659 | 659 | |
| 660 | 660 | portinfo.capability = cap; |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/time.h> |
| 10 | 10 | #include <linux/device.h> |
| 11 | 11 | #include <linux/module.h> |
| 12 | +#include <linux/debugfs.h> | |
| 12 | 13 | #include <sound/core.h> |
| 13 | 14 | #include <sound/minors.h> |
| 14 | 15 | #include <sound/info.h> |
| @@ -39,6 +40,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); · 24 unmodified lines | ||
| 39 | 40 | int snd_ecards_limit; |
| 40 | 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 | 48 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
| 43 | 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 | 343 | return "sequencer"; |
| 338 | 344 | case SNDRV_DEVICE_TYPE_TIMER: |
| 339 | 345 | return "timer"; |
| 346 | + case SNDRV_DEVICE_TYPE_COMPRESS: | |
| 347 | + return "compress"; | |
| 340 | 348 | default: |
| 341 | 349 | return "?"; |
| 342 | 350 | } |
| @@ -395,6 +403,10 @@ static int __init alsa_sound_init(void) · 52 unmodified lines | ||
| 395 | 403 | unregister_chrdev(major, "alsa"); |
| 396 | 404 | return -ENOMEM; |
| 397 | 405 | } |
| 406 | + | |
| 407 | +#ifdef CONFIG_SND_DEBUG | |
| 408 | + sound_debugfs_root = debugfs_create_dir("sound", NULL); | |
| 409 | +#endif | |
| 398 | 410 | #ifndef MODULE |
| 399 | 411 | pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); |
| 400 | 412 | #endif |
| @@ -403,6 +415,9 @@ static int __init alsa_sound_init(void) · 2 unmodified lines | ||
| 403 | 415 | |
| 404 | 416 | static void __exit alsa_sound_exit(void) |
| 405 | 417 | { |
| 418 | +#ifdef CONFIG_SND_DEBUG | |
| 419 | + debugfs_remove(sound_debugfs_root); | |
| 420 | +#endif | |
| 406 | 421 | snd_info_done(); |
| 407 | 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 | 959 | timer->tmr_device = tid->device; |
| 960 | 960 | timer->tmr_subdevice = tid->subdevice; |
| 961 | 961 | if (id) |
| 962 | − strlcpy(timer->id, id, sizeof(timer->id)); | |
| 962 | + strscpy(timer->id, id, sizeof(timer->id)); | |
| 963 | 963 | timer->sticks = 1; |
| 964 | 964 | INIT_LIST_HEAD(&timer->device_list); |
| 965 | 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 | 1659 | ginfo->card = t->card ? t->card->number : -1; |
| 1660 | 1660 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 1661 | 1661 | ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; |
| 1662 | − strlcpy(ginfo->id, t->id, sizeof(ginfo->id)); | |
| 1663 | − strlcpy(ginfo->name, t->name, sizeof(ginfo->name)); | |
| 1662 | + strscpy(ginfo->id, t->id, sizeof(ginfo->id)); | |
| 1663 | + strscpy(ginfo->name, t->name, sizeof(ginfo->name)); | |
| 1664 | 1664 | ginfo->resolution = t->hw.resolution; |
| 1665 | 1665 | if (t->hw.resolution_min > 0) { |
| 1666 | 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 | 1814 | info->card = t->card ? t->card->number : -1; |
| 1815 | 1815 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 1816 | 1816 | info->flags |= SNDRV_TIMER_FLG_SLAVE; |
| 1817 | − strlcpy(info->id, t->id, sizeof(info->id)); | |
| 1818 | − strlcpy(info->name, t->name, sizeof(info->name)); | |
| 1817 | + strscpy(info->id, t->id, sizeof(info->id)); | |
| 1818 | + strscpy(info->name, t->name, sizeof(info->name)); | |
| 1819 | 1819 | info->resolution = t->hw.resolution; |
| 1820 | 1820 | if (copy_to_user(_info, info, sizeof(*_info))) |
| 1821 | 1821 | err = -EFAULT; |
| @@ -61,8 +61,8 @@ static int snd_timer_user_info_compat(struct file *file, · 60 unmodified lines | ||
| 61 | 61 | info.card = t->card ? t->card->number : -1; |
| 62 | 62 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
| 63 | 63 | info.flags |= SNDRV_TIMER_FLG_SLAVE; |
| 64 | − strlcpy(info.id, t->id, sizeof(info.id)); | |
| 65 | − strlcpy(info.name, t->name, sizeof(info.name)); | |
| 64 | + strscpy(info.id, t->id, sizeof(info.id)); | |
| 65 | + strscpy(info.name, t->name, sizeof(info.name)); | |
| 66 | 66 | info.resolution = t->hw.resolution; |
| 67 | 67 | if (copy_to_user(_info, &info, sizeof(*_info))) |
| 68 | 68 | return -EFAULT; |
| @@ -219,7 +219,7 @@ static int loopback_jiffies_timer_start(struct loopback_pcm *dpcm) · 218 unmodified lines | ||
| 219 | 219 | dpcm->period_update_pending = 1; |
| 220 | 220 | } |
| 221 | 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 | 223 | mod_timer(&dpcm->timer, jiffies + tick); |
| 224 | 224 | |
| 225 | 225 | return 0; |
| @@ -236,7 +236,7 @@ struct dummy_systimer_pcm { · 235 unmodified lines | ||
| 236 | 236 | static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) |
| 237 | 237 | { |
| 238 | 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 | 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 | 97 | return; |
| 98 | 98 | |
| 99 | 99 | opl3->oss_seq_dev = dev; |
| 100 | − strlcpy(dev->name, name, sizeof(dev->name)); | |
| 100 | + strscpy(dev->name, name, sizeof(dev->name)); | |
| 101 | 101 | arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); |
| 102 | 102 | arg->type = SYNTH_TYPE_FM; |
| 103 | 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 | 292 | if (name) |
| 293 | − strlcpy(patch->name, name, sizeof(patch->name)); | |
| 293 | + strscpy(patch->name, name, sizeof(patch->name)); | |
| 294 | 294 | |
| 295 | 295 | return 0; |
| 296 | 296 | } |
| @@ -1154,8 +1154,7 @@ static int vx_init_audio_io(struct vx_core *chip) · 1153 unmodified lines | ||
| 1154 | 1154 | chip->ibl.size = 0; |
| 1155 | 1155 | vx_set_ibl(chip, &chip->ibl); /* query the info */ |
| 1156 | 1156 | if (preferred > 0) { |
| 1157 | − chip->ibl.size = ((preferred + chip->ibl.granularity - 1) / | |
| 1158 | − chip->ibl.granularity) * chip->ibl.granularity; | |
| 1157 | + chip->ibl.size = roundup(preferred, chip->ibl.granularity); | |
| 1159 | 1158 | if (chip->ibl.size > chip->ibl.max_size) |
| 1160 | 1159 | chip->ibl.size = chip->ibl.max_size; |
| 1161 | 1160 | } else |
| @@ -37,11 +37,9 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | memset(&event, 0, sizeof(event)); |
| 39 | 39 | count = min_t(long, count, sizeof(event.lock_status)); |
| 40 | − if (bebob->dev_lock_changed) { | |
| 41 | − event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 42 | − event.lock_status.status = (bebob->dev_lock_count > 0); | |
| 43 | − bebob->dev_lock_changed = false; | |
| 44 | − } | |
| 40 | + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 41 | + event.lock_status.status = (bebob->dev_lock_count > 0); | |
| 42 | + bebob->dev_lock_changed = false; | |
| 45 | 43 | |
| 46 | 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 | 78 | info.card = dev->card->index; |
| 81 | 79 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 82 | 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 | 82 | sizeof(info.device_name)); |
| 85 | 83 | |
| 86 | 84 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ |
| 3 | 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 | 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 | 79 | info.card = dev->card->index; |
| 80 | 80 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | 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 | 83 | sizeof(info.device_name)); |
| 84 | 84 | |
| 85 | 85 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -20,10 +20,12 @@ MODULE_LICENSE("GPL v2"); · 19 unmodified lines | ||
| 20 | 20 | #define OUI_MYTEK 0x001ee8 |
| 21 | 21 | #define OUI_SSL 0x0050c2 // Actually ID reserved by IEEE. |
| 22 | 22 | #define OUI_PRESONUS 0x000a92 |
| 23 | +#define OUI_HARMAN 0x000fd7 | |
| 23 | 24 | |
| 24 | 25 | #define DICE_CATEGORY_ID 0x04 |
| 25 | 26 | #define WEISS_CATEGORY_ID 0x00 |
| 26 | 27 | #define LOUD_CATEGORY_ID 0x10 |
| 28 | +#define HARMAN_CATEGORY_ID 0x20 | |
| 27 | 29 | |
| 28 | 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 | 58 | category = WEISS_CATEGORY_ID; |
| 57 | 59 | else if (vendor == OUI_LOUD) |
| 58 | 60 | category = LOUD_CATEGORY_ID; |
| 61 | + else if (vendor == OUI_HARMAN) | |
| 62 | + category = HARMAN_CATEGORY_ID; | |
| 59 | 63 | else |
| 60 | 64 | category = DICE_CATEGORY_ID; |
| 61 | 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 | 392 | .model_id = 0x000008, |
| 389 | 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 | 404 | .match_flags = IEEE1394_MATCH_VERSION, |
| 393 | 405 | .version = DICE_INTERFACE, |
| @@ -233,5 +233,6 @@ int snd_dice_detect_alesis_mastercontrol_formats(struct snd_dice *dice); · 232 unmodified lines | ||
| 233 | 233 | int snd_dice_detect_extension_formats(struct snd_dice *dice); |
| 234 | 234 | int snd_dice_detect_mytek_formats(struct snd_dice *dice); |
| 235 | 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 | 238 | #endif |
| @@ -87,7 +87,7 @@ static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg) · 86 unmodified lines | ||
| 87 | 87 | info.card = dev->card->index; |
| 88 | 88 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 89 | 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 | 91 | sizeof(info.device_name)); |
| 92 | 92 | |
| 93 | 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 | 37 | memset(&event, 0, sizeof(event)); |
| 38 | − if (ff->dev_lock_changed) { | |
| 39 | − event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 40 | − event.lock_status.status = (ff->dev_lock_count > 0); | |
| 41 | − ff->dev_lock_changed = false; | |
| 38 | + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 39 | + event.lock_status.status = (ff->dev_lock_count > 0); | |
| 40 | + ff->dev_lock_changed = false; | |
| 42 | 41 | |
| 43 | − count = min_t(long, count, sizeof(event.lock_status)); | |
| 44 | − } | |
| 42 | + count = min_t(long, count, sizeof(event.lock_status)); | |
| 45 | 43 | |
| 46 | 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 | 77 | info.card = dev->card->index; |
| 80 | 78 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | 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 | 81 | sizeof(info.device_name)); |
| 84 | 82 | |
| 85 | 83 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -15,6 +15,61 @@ · 14 unmodified lines | ||
| 15 | 15 | #define LATTER_FETCH_MODE 0xffff00000010ULL |
| 16 | 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 | 73 | static int parse_clock_bits(u32 data, unsigned int *rate, |
| 19 | 74 | enum snd_ff_clock_src *src, |
| 20 | 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 | 78 | unsigned int rate; |
| 24 | 79 | u32 flag; |
| 25 | 80 | } *rate_entry, rate_entries[] = { |
| 26 | − { 32000, 0x00000000, }, | |
| 27 | − { 44100, 0x01000000, }, | |
| 28 | − { 48000, 0x02000000, }, | |
| 29 | − { 64000, 0x04000000, }, | |
| 30 | − { 88200, 0x05000000, }, | |
| 31 | − { 96000, 0x06000000, }, | |
| 32 | − { 128000, 0x08000000, }, | |
| 33 | − { 176400, 0x09000000, }, | |
| 34 | − { 192000, 0x0a000000, }, | |
| 81 | + { 32000, 0x00, }, | |
| 82 | + { 44100, 0x01, }, | |
| 83 | + { 48000, 0x02, }, | |
| 84 | + { 64000, 0x04, }, | |
| 85 | + { 88200, 0x05, }, | |
| 86 | + { 96000, 0x06, }, | |
| 87 | + { 128000, 0x08, }, | |
| 88 | + { 176400, 0x09, }, | |
| 89 | + { 192000, 0x0a, }, | |
| 35 | 90 | }; |
| 36 | 91 | static const struct { |
| 37 | 92 | enum snd_ff_clock_src src; |
| 38 | 93 | u32 flag; |
| 39 | − } *clk_entry, clk_entries[] = { | |
| 94 | + } *clk_entry, *clk_entries, ucx_clk_entries[] = { | |
| 40 | 95 | { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, }, |
| 41 | 96 | { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, }, |
| 42 | 97 | { SND_FF_CLOCK_SRC_WORD, 0x00000600, }, |
| 43 | 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 | 108 | int i; |
| 46 | 109 | |
| 47 | − if (unit_version != SND_FF_UNIT_VERSION_UCX) { | |
| 48 | − // e.g. 0x00fe0f20 but expected 0x00eff002. | |
| 49 | − data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4); | |
| 110 | + if (unit_version == SND_FF_UNIT_VERSION_UCX) { | |
| 111 | + rate_bits = (data & 0x0f000000) >> 24; | |
| 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 | 120 | for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) { |
| 53 | 121 | rate_entry = rate_entries + i; |
| 54 | − if ((data & 0x0f000000) == rate_entry->flag) { | |
| 122 | + if (rate_bits == rate_entry->flag) { | |
| 55 | 123 | *rate = rate_entry->rate; |
| 56 | 124 | break; |
| 57 | 125 | } |
| @@ -59,14 +127,14 @@ static int parse_clock_bits(u32 data, unsigned int *rate, · 1 unmodified line | ||
| 59 | 127 | if (i == ARRAY_SIZE(rate_entries)) |
| 60 | 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 | 131 | clk_entry = clk_entries + i; |
| 64 | 132 | if ((data & 0x000e00) == clk_entry->flag) { |
| 65 | 133 | *src = clk_entry->src; |
| 66 | 134 | break; |
| 67 | 135 | } |
| 68 | 136 | } |
| 69 | − if (i == ARRAY_SIZE(clk_entries)) | |
| 137 | + if (i == clk_entry_count) | |
| 70 | 138 | return -EIO; |
| 71 | 139 | |
| 72 | 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 | 317 | char *const label; |
| 250 | 318 | u32 locked_mask; |
| 251 | 319 | u32 synced_mask; |
| 252 | − } *clk_entry, clk_entries[] = { | |
| 320 | + } *clk_entry, *clk_entries, ucx_clk_entries[] = { | |
| 253 | 321 | { "S/PDIF", 0x00000001, 0x00000010, }, |
| 254 | 322 | { "ADAT", 0x00000002, 0x00000020, }, |
| 255 | 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 | 330 | __le32 reg; |
| 258 | 331 | u32 data; |
| 259 | 332 | unsigned int rate; |
| 260 | 333 | enum snd_ff_clock_src src; |
| 261 | 334 | const char *label; |
| 335 | + unsigned int clk_entry_count; | |
| 262 | 336 | int i; |
| 263 | 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 | 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 | 356 | clk_entry = clk_entries + i; |
| 275 | 357 | snd_iprintf(buffer, "%s: ", clk_entry->label); |
| 276 | 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 | 212 | info.card = dev->card->index; |
| 213 | 213 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 214 | 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 | 216 | sizeof(info.device_name)); |
| 217 | 217 | |
| 218 | 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 | 86 | info.card = dev->card->index; |
| 87 | 87 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 88 | 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 | 90 | sizeof(info.device_name)); |
| 91 | 91 | |
| 92 | 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 | 37 | memset(&event, 0, sizeof(event)); |
| 38 | − if (oxfw->dev_lock_changed) { | |
| 39 | − event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 40 | − event.lock_status.status = (oxfw->dev_lock_count > 0); | |
| 41 | − oxfw->dev_lock_changed = false; | |
| 38 | + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; | |
| 39 | + event.lock_status.status = (oxfw->dev_lock_count > 0); | |
| 40 | + oxfw->dev_lock_changed = false; | |
| 42 | 41 | |
| 43 | − count = min_t(long, count, sizeof(event.lock_status)); | |
| 44 | − } | |
| 42 | + count = min_t(long, count, sizeof(event.lock_status)); | |
| 45 | 43 | |
| 46 | 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 | 77 | info.card = dev->card->index; |
| 80 | 78 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 81 | 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 | 81 | sizeof(info.device_name)); |
| 84 | 82 | |
| 85 | 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 | 154 | info.card = dev->card->index; |
| 155 | 155 | *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); |
| 156 | 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 | 158 | sizeof(info.device_name)); |
| 159 | 159 | |
| 160 | 160 | if (copy_to_user(arg, &info, sizeof(info))) |
| @@ -46,3 +46,17 @@ config SND_INTEL_DSP_CONFIG · 45 unmodified lines | ||
| 46 | 46 | select SND_INTEL_NHLT if ACPI |
| 47 | 47 | # this config should be selected only for Intel DSP platforms. |
| 48 | 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 | 332 | return ret; |
| 333 | 333 | } |
| 334 | 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 | 17 | static const struct hdac_bus_ops default_ops = { |
| 18 | 18 | .command = snd_hdac_bus_send_cmd, |
| 19 | 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 | 266 | EXPORT_SYMBOL_GPL(snd_hdac_aligned_write); |
| 266 | 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 | 648 | snd_dma_free_pages(&bus->posbuf); |
| 649 | 649 | } |
| 650 | 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 | 435 | pos_adj = bus->bdl_pos_adj; |
| 436 | 436 | if (!azx_dev->no_period_wakeup && pos_adj > 0) { |
| 437 | 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 | 439 | if (!pos_adj) |
| 440 | 440 | pos_adj = pos_align; |
| 441 | 441 | else |
| 442 | − pos_adj = ((pos_adj + pos_align - 1) / pos_align) * | |
| 443 | − pos_align; | |
| 442 | + pos_adj = roundup(pos_adj, pos_align); | |
| 444 | 443 | pos_adj = frames_to_bytes(runtime, pos_adj); |
| 445 | 444 | if (pos_adj >= period_bytes) { |
| 446 | 445 | dev_warn(bus->dev, "Too big adjustment %d\n", |
| @@ -66,7 +66,7 @@ static struct attribute *hdac_dev_attrs[] = { · 65 unmodified lines | ||
| 66 | 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 | 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 | 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 | 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 | 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 | 476 | * configuration table |
| 457 | 477 | * - the order of similar ACPI ID entries is important! |
| 458 | 478 | * - the first successful match will win |
| 459 | 479 | */ |
| 460 | 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 | 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 | 486 | .acpi_hid = "80860F28", |
| 472 | 487 | }, |
| 473 | −#endif | |
| 474 | 488 | /* CherryTrail */ |
| 475 | −#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) | |
| 476 | 489 | { |
| 477 | − .flags = FLAG_SST, | |
| 478 | − .acpi_hid = "808622A8", | |
| 479 | − }, | |
| 480 | −#endif | |
| 481 | −#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) | |
| 482 | − { | |
| 483 | − .flags = FLAG_SOF, | |
| 490 | + .flags = FLAG_SST_OR_SOF_BYT, | |
| 484 | 491 | .acpi_hid = "808622A8", |
| 485 | 492 | }, |
| 486 | 493 | #endif |
| @@ -84,7 +84,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name, · 83 unmodified lines | ||
| 84 | 84 | list_add_tail(&bus->buses, &master->buses); |
| 85 | 85 | bus->master = master; |
| 86 | 86 | } |
| 87 | − strlcpy(bus->name, name, sizeof(bus->name)); | |
| 87 | + strscpy(bus->name, name, sizeof(bus->name)); | |
| 88 | 88 | err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops); |
| 89 | 89 | if (err < 0) { |
| 90 | 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 | 108 | if (device == NULL) |
| 109 | 109 | return -ENOMEM; |
| 110 | 110 | device->addr = addr; |
| 111 | − strlcpy(device->name, name, sizeof(device->name)); | |
| 111 | + strscpy(device->name, name, sizeof(device->name)); | |
| 112 | 112 | list_add_tail(&device->list, &bus->devices); |
| 113 | 113 | device->bus = bus; |
| 114 | 114 | *rdevice = device; |
| @@ -95,8 +95,8 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) · 94 unmodified lines | ||
| 95 | 95 | if (error < 0) |
| 96 | 96 | goto out; |
| 97 | 97 | |
| 98 | − strlcpy(card->driver, "AD1848", sizeof(card->driver)); | |
| 99 | − strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 98 | + strscpy(card->driver, "AD1848", sizeof(card->driver)); | |
| 99 | + strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 100 | 100 | |
| 101 | 101 | if (!thinkpad[n]) |
| 102 | 102 | snprintf(card->longname, sizeof(card->longname), |
| @@ -118,10 +118,9 @@ out: snd_card_free(card); · 15 unmodified lines | ||
| 118 | 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 | 123 | snd_card_free(dev_get_drvdata(dev)); |
| 124 | − return 0; | |
| 125 | 124 | } |
| 126 | 125 | |
| 127 | 126 | #ifdef CONFIG_PM |
| @@ -97,10 +97,9 @@ out: snd_card_free(card); · 96 unmodified lines | ||
| 97 | 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 | 102 | snd_card_free(dev_get_drvdata(dev)); |
| 103 | − return 0; | |
| 104 | 103 | } |
| 105 | 104 | |
| 106 | 105 | static struct isa_driver snd_adlib_driver = { |
| @@ -403,7 +403,7 @@ error: · 402 unmodified lines | ||
| 403 | 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 | 408 | struct snd_card *card = dev_get_drvdata(pdev); |
| 409 | 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 | 420 | snd_cmi8328_cfg_write(cmi->port, CFG2, 0); |
| 421 | 421 | snd_cmi8328_cfg_write(cmi->port, CFG3, 0); |
| 422 | 422 | snd_card_free(card); |
| 423 | − return 0; | |
| 424 | 423 | } |
| 425 | 424 | |
| 426 | 425 | #ifdef CONFIG_PM |
| @@ -631,11 +631,10 @@ static int snd_cmi8330_isa_probe(struct device *pdev, · 630 unmodified lines | ||
| 631 | 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 | 635 | unsigned int dev) |
| 636 | 636 | { |
| 637 | 637 | snd_card_free(dev_get_drvdata(devptr)); |
| 638 | − return 0; | |
| 639 | 638 | } |
| 640 | 639 | |
| 641 | 640 | #ifdef CONFIG_PM |
| @@ -95,8 +95,8 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) · 94 unmodified lines | ||
| 95 | 95 | if (error < 0) |
| 96 | 96 | goto out; |
| 97 | 97 | |
| 98 | − strlcpy(card->driver, "CS4231", sizeof(card->driver)); | |
| 99 | − strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 98 | + strscpy(card->driver, "CS4231", sizeof(card->driver)); | |
| 99 | + strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 100 | 100 | |
| 101 | 101 | if (dma2[n] < 0) |
| 102 | 102 | snprintf(card->longname, sizeof(card->longname), |
| @@ -135,10 +135,9 @@ out: snd_card_free(card); · 32 unmodified lines | ||
| 135 | 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 | 140 | snd_card_free(dev_get_drvdata(dev)); |
| 141 | − return 0; | |
| 142 | 141 | } |
| 143 | 142 | |
| 144 | 143 | #ifdef CONFIG_PM |
| @@ -405,8 +405,8 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) · 404 unmodified lines | ||
| 405 | 405 | if (err < 0) |
| 406 | 406 | return err; |
| 407 | 407 | } |
| 408 | − strlcpy(card->driver, chip->pcm->name, sizeof(card->driver)); | |
| 409 | − strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 408 | + strscpy(card->driver, chip->pcm->name, sizeof(card->driver)); | |
| 409 | + strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 410 | 410 | if (dma2[dev] < 0) |
| 411 | 411 | snprintf(card->longname, sizeof(card->longname), |
| 412 | 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 | 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 | 491 | unsigned int dev) |
| 492 | 492 | { |
| 493 | 493 | snd_card_free(dev_get_drvdata(pdev)); |
| 494 | − return 0; | |
| 495 | 494 | } |
| 496 | 495 | |
| 497 | 496 | #ifdef CONFIG_PM |
| @@ -133,8 +133,8 @@ static int snd_es1688_probe(struct snd_card *card, unsigned int n) · 132 unmodified lines | ||
| 133 | 133 | if (error < 0) |
| 134 | 134 | return error; |
| 135 | 135 | |
| 136 | − strlcpy(card->driver, "ES1688", sizeof(card->driver)); | |
| 137 | − strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 136 | + strscpy(card->driver, "ES1688", sizeof(card->driver)); | |
| 137 | + strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); | |
| 138 | 138 | snprintf(card->longname, sizeof(card->longname), |
| 139 | 139 | "%s at 0x%lx, irq %i, dma %i", chip->pcm->name, chip->port, |
| 140 | 140 | chip->irq, chip->dma8); |
| @@ -192,10 +192,9 @@ out: · 51 unmodified lines | ||
| 192 | 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 | 197 | snd_card_free(dev_get_drvdata(dev)); |
| 198 | − return 0; | |
| 199 | 198 | } |
| 200 | 199 | |
| 201 | 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, | |
| 2214 | − unsigned int dev) | |
| 2213 | +static void snd_es18xx_isa_remove(struct device *devptr, | |
| 2214 | + unsigned int dev) | |
| 2215 | 2215 | { |
| 2216 | 2216 | snd_card_free(dev_get_drvdata(devptr)); |
| 2217 | − return 0; | |
| 2218 | 2217 | } |
| 2219 | 2218 | |
| 2220 | 2219 | #ifdef CONFIG_PM |
| @@ -608,10 +608,9 @@ error: · 607 unmodified lines | ||
| 608 | 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 | 613 | snd_card_free(dev_get_drvdata(dev)); |
| 614 | − return 0; | |
| 615 | 614 | } |
| 616 | 615 | |
| 617 | 616 | static struct isa_driver snd_galaxy_driver = { |
| @@ -195,10 +195,9 @@ out: snd_card_free(card); · 194 unmodified lines | ||
| 195 | 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 | 200 | snd_card_free(dev_get_drvdata(dev)); |
| 201 | − return 0; | |
| 202 | 201 | } |
| 203 | 202 | |
| 204 | 203 | static struct isa_driver snd_gusclassic_driver = { |
| @@ -324,10 +324,9 @@ out: snd_card_free(card); · 323 unmodified lines | ||
| 324 | 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 | 329 | snd_card_free(dev_get_drvdata(dev)); |
| 330 | − return 0; | |
| 331 | 330 | } |
| 332 | 331 | |
| 333 | 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 | 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 | 343 | snd_card_free(dev_get_drvdata(devptr)); |
| 344 | − return 0; | |
| 345 | 344 | } |
| 346 | 345 | |
| 347 | 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 | 830 | snd_card_free(dev_get_drvdata(devptr)); |
| 831 | − return 0; | |
| 832 | 831 | } |
| 833 | 832 | |
| 834 | 833 | static struct isa_driver snd_interwave_driver = { |
| @@ -1049,10 +1049,9 @@ cfg_error: · 1048 unmodified lines | ||
| 1049 | 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 | 1054 | snd_msnd_unload(dev_get_drvdata(pdev)); |
| 1055 | − return 0; | |
| 1056 | 1055 | } |
| 1057 | 1056 | |
| 1058 | 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 | 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 | 882 | unsigned int dev) |
| 883 | 883 | { |
| 884 | 884 | snd_card_free(dev_get_drvdata(devptr)); |
| 885 | − return 0; | |
| 886 | 885 | } |
| 887 | 886 | |
| 888 | 887 | #ifdef CONFIG_PM |
| @@ -1480,11 +1480,10 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n) · 1479 unmodified lines | ||
| 1480 | 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 | 1484 | unsigned int dev) |
| 1485 | 1485 | { |
| 1486 | 1486 | snd_card_free(dev_get_drvdata(devptr)); |
| 1487 | − return 0; | |
| 1488 | 1487 | } |
| 1489 | 1488 | |
| 1490 | 1489 | #define DEV_NAME "miro" |
| @@ -1024,11 +1024,10 @@ static int snd_opti9xx_isa_probe(struct device *devptr, · 1023 unmodified lines | ||
| 1024 | 1024 | return 0; |
| 1025 | 1025 | } |
| 1026 | 1026 | |
| 1027 | −static int snd_opti9xx_isa_remove(struct device *devptr, | |
| 1028 | − unsigned int dev) | |
| 1027 | +static void snd_opti9xx_isa_remove(struct device *devptr, | |
| 1028 | + unsigned int dev) | |
| 1029 | 1029 | { |
| 1030 | 1030 | snd_card_free(dev_get_drvdata(devptr)); |
| 1031 | − return 0; | |
| 1032 | 1031 | } |
| 1033 | 1032 | |
| 1034 | 1033 | #ifdef CONFIG_PM |
| @@ -339,12 +339,11 @@ err_free: · 338 unmodified lines | ||
| 339 | 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 | 344 | struct snd_card *card = dev_get_drvdata(devptr); |
| 345 | 345 | |
| 346 | 346 | snd_card_free(card); |
| 347 | − return 0; | |
| 348 | 347 | } |
| 349 | 348 | |
| 350 | 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 | 552 | snd_card_free(dev_get_drvdata(pdev)); |
| 553 | − return 0; | |
| 554 | 553 | } |
| 555 | 554 | |
| 556 | 555 | #ifdef CONFIG_PM |
| @@ -388,7 +388,7 @@ static int snd_sb_csp_riff_load(struct snd_sb_csp * p, · 387 unmodified lines | ||
| 388 | 388 | return err; |
| 389 | 389 | |
| 390 | 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 | 392 | p->func_nr = func_nr; |
| 393 | 393 | p->mode = le16_to_cpu(funcdesc_h.flags_play_rec); |
| 394 | 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 | 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 | 197 | snd_card_free(dev_get_drvdata(pdev)); |
| 198 | − return 0; | |
| 199 | 198 | } |
| 200 | 199 | |
| 201 | 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 | 482 | ctl = snd_ctl_new1(&newctls[type], chip); |
| 483 | 483 | if (! ctl) |
| 484 | 484 | return -ENOMEM; |
| 485 | − strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); | |
| 485 | + strscpy(ctl->id.name, name, sizeof(ctl->id.name)); | |
| 486 | 486 | ctl->id.index = index; |
| 487 | 487 | ctl->private_value = value; |
| 488 | 488 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) |
| @@ -672,7 +672,7 @@ err_exit: · 671 unmodified lines | ||
| 672 | 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 | 677 | struct snd_card *card = dev_get_drvdata(devptr); |
| 678 | 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 | 684 | release_region(mss_port[dev], 4); |
| 685 | 685 | |
| 686 | 686 | snd_card_free(card); |
| 687 | − return 0; | |
| 688 | 687 | } |
| 689 | 688 | |
| 690 | 689 | static struct isa_driver snd_sc6000_driver = { |
| @@ -1183,10 +1183,9 @@ _release_card: · 1182 unmodified lines | ||
| 1183 | 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 | 1188 | snd_card_free(dev_get_drvdata(devptr)); |
| 1189 | − return 0; | |
| 1190 | 1189 | } |
| 1191 | 1190 | |
| 1192 | 1191 | #define DEV_NAME "sscape" |
| @@ -565,11 +565,10 @@ static int snd_wavefront_isa_probe(struct device *pdev, · 564 unmodified lines | ||
| 565 | 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 | 569 | unsigned int dev) |
| 570 | 570 | { |
| 571 | 571 | snd_card_free(dev_get_drvdata(devptr)); |
| 572 | − return 0; | |
| 573 | 572 | } |
| 574 | 573 | |
| 575 | 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 | 356 | mixer_info info; |
| 357 | 357 | memset(&info, 0, sizeof(info)); |
| 358 | − strlcpy(info.id, dmasound.mach.name2, sizeof(info.id)); | |
| 359 | − strlcpy(info.name, dmasound.mach.name2, sizeof(info.name)); | |
| 358 | + strscpy(info.id, dmasound.mach.name2, sizeof(info.id)); | |
| 359 | + strscpy(info.name, dmasound.mach.name2, sizeof(info.name)); | |
| 360 | 360 | info.modify_counter = mixer.modify_counter; |
| 361 | 361 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) |
| 362 | 362 | return -EFAULT; |
| @@ -857,8 +857,7 @@ snd_ad1889_create(struct snd_card *card, · 856 unmodified lines | ||
| 857 | 857 | return err; |
| 858 | 858 | |
| 859 | 859 | /* check PCI availability (32bit DMA) */ |
| 860 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | |
| 861 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | |
| 860 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { | |
| 862 | 861 | dev_err(card->dev, "error setting 32-bit DMA mask.\n"); |
| 863 | 862 | pci_disable_device(pci); |
| 864 | 863 | return -ENXIO; |
| @@ -2057,8 +2057,7 @@ static int snd_ali_create(struct snd_card *card, · 2056 unmodified lines | ||
| 2057 | 2057 | if (err < 0) |
| 2058 | 2058 | return err; |
| 2059 | 2059 | /* check, if we can restrict PCI DMA transfers to 31 bits */ |
| 2060 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(31)) < 0 || | |
| 2061 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(31)) < 0) { | |
| 2060 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31))) { | |
| 2062 | 2061 | dev_err(card->dev, |
| 2063 | 2062 | "architecture does not support 31bit PCI busmaster DMA\n"); |
| 2064 | 2063 | pci_disable_device(pci); |
| @@ -625,8 +625,7 @@ static int snd_als300_create(struct snd_card *card, · 624 unmodified lines | ||
| 625 | 625 | if ((err = pci_enable_device(pci)) < 0) |
| 626 | 626 | return err; |
| 627 | 627 | |
| 628 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | |
| 629 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | |
| 628 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { | |
| 630 | 629 | dev_err(card->dev, "error setting 28bit DMA mask\n"); |
| 631 | 630 | pci_disable_device(pci); |
| 632 | 631 | return -ENXIO; |
| @@ -837,8 +837,7 @@ static int snd_card_als4000_probe(struct pci_dev *pci, · 836 unmodified lines | ||
| 837 | 837 | return err; |
| 838 | 838 | } |
| 839 | 839 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 840 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | |
| 841 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | |
| 840 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { | |
| 842 | 841 | dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n"); |
| 843 | 842 | pci_disable_device(pci); |
| 844 | 843 | return -ENXIO; |
| @@ -52,7 +52,7 @@ void hpi_debug_data(u16 *pdata, u32 len) · 51 unmodified lines | ||
| 52 | 52 | int lines; |
| 53 | 53 | int cols = 8; |
| 54 | 54 | |
| 55 | − lines = (len + cols - 1) / cols; | |
| 55 | + lines = DIV_ROUND_UP(len, cols); | |
| 56 | 56 | if (lines > 8) |
| 57 | 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 | 151 | // check PCI availability (DMA). |
| 152 | 152 | if ((err = pci_enable_device(pci)) < 0) |
| 153 | 153 | return err; |
| 154 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | |
| 155 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | |
| 154 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { | |
| 156 | 155 | dev_err(card->dev, "error to set DMA mask\n"); |
| 157 | 156 | pci_disable_device(pci); |
| 158 | 157 | return -ENXIO; |
| @@ -236,8 +236,7 @@ static int snd_aw2_create(struct snd_card *card, · 235 unmodified lines | ||
| 236 | 236 | pci_set_master(pci); |
| 237 | 237 | |
| 238 | 238 | /* check PCI availability (32bit DMA) */ |
| 239 | − if ((dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) || | |
| 240 | − (dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0)) { | |
| 239 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { | |
| 241 | 240 | dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); |
| 242 | 241 | pci_disable_device(pci); |
| 243 | 242 | return -ENXIO; |
| @@ -2379,8 +2379,7 @@ snd_azf3328_create(struct snd_card *card, · 2378 unmodified lines | ||
| 2379 | 2379 | chip->irq = -1; |
| 2380 | 2380 | |
| 2381 | 2381 | /* check if we can restrict PCI DMA transfers to 24 bits */ |
| 2382 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | |
| 2383 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | |
| 2382 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { | |
| 2384 | 2383 | dev_err(card->dev, |
| 2385 | 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 | 2448 | /* shutdown codecs to reduce power / noise */ |
| 2450 | 2449 | /* have ...ctrl_codec_activity() act properly */ |
| 2451 | − codec->running = 1; | |
| 2450 | + codec->running = true; | |
| 2452 | 2451 | snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); |
| 2453 | 2452 | |
| 2454 | 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 | 327 | current_block = chip->current_line * 16 / chip->lines; |
| 328 | 328 | irq_block = status >> INT_RISCS_SHIFT; |
| 329 | 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 | 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 | 1605 | err = pci_enable_device(pci); |
| 1606 | 1606 | if (err < 0) |
| 1607 | 1607 | return err; |
| 1608 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | |
| 1609 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | |
| 1608 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { | |
| 1610 | 1609 | dev_err(card->dev, "error to set 32bit mask DMA\n"); |
| 1611 | 1610 | pci_disable_device(pci); |
| 1612 | 1611 | return -ENXIO; |
| @@ -813,7 +813,7 @@ static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned · 812 unmodified lines | ||
| 813 | 813 | correctionPerGOF = tmp1 / GOF_PER_SEC; |
| 814 | 814 | tmp1 -= correctionPerGOF * GOF_PER_SEC; |
| 815 | 815 | correctionPerSec = tmp1; |
| 816 | − initialDelay = ((48000 * 24) + rate - 1) / rate; | |
| 816 | + initialDelay = DIV_ROUND_UP(48000 * 24, rate); | |
| 817 | 817 | |
| 818 | 818 | /* |
| 819 | 819 | * Fill in the VariDecimate control block. |
| @@ -269,8 +269,7 @@ static int snd_cs5535audio_create(struct snd_card *card, · 268 unmodified lines | ||
| 269 | 269 | if ((err = pci_enable_device(pci)) < 0) |
| 270 | 270 | return err; |
| 271 | 271 | |
| 272 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0 || | |
| 273 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) { | |
| 272 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { | |
| 274 | 273 | dev_warn(card->dev, "unable to get 32bit dma\n"); |
| 275 | 274 | err = -ENXIO; |
| 276 | 275 | goto pcifail; |
| @@ -158,13 +158,13 @@ int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) · 157 unmodified lines | ||
| 158 | 158 | /* drop the original AD1888 HPF control */ |
| 159 | 159 | memset(&elem, 0, sizeof(elem)); |
| 160 | 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 | 162 | snd_ctl_remove_id(card, &elem); |
| 163 | 163 | |
| 164 | 164 | /* drop the original V_REFOUT control */ |
| 165 | 165 | memset(&elem, 0, sizeof(elem)); |
| 166 | 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 | 168 | snd_ctl_remove_id(card, &elem); |
| 169 | 169 | |
| 170 | 170 | /* add the OLPC-specific controls */ |
| @@ -1901,12 +1901,8 @@ static int hw_card_start(struct hw *hw) · 1900 unmodified lines | ||
| 1901 | 1901 | return err; |
| 1902 | 1902 | |
| 1903 | 1903 | /* Set DMA transfer mask */ |
| 1904 | − if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | |
| 1905 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | |
| 1906 | − } else { | |
| 1907 | − dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 1908 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 1909 | − } | |
| 1904 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) | |
| 1905 | + dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); | |
| 1910 | 1906 | |
| 1911 | 1907 | if (!hw->io_base) { |
| 1912 | 1908 | err = pci_request_regions(pci, "XFi"); |
| @@ -2026,12 +2026,8 @@ static int hw_card_start(struct hw *hw) · 2025 unmodified lines | ||
| 2026 | 2026 | return err; |
| 2027 | 2027 | |
| 2028 | 2028 | /* Set DMA transfer mask */ |
| 2029 | − if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | |
| 2030 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | |
| 2031 | − } else { | |
| 2032 | − dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 2033 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 2034 | − } | |
| 2029 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) | |
| 2030 | + dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); | |
| 2035 | 2031 | |
| 2036 | 2032 | if (!hw->io_base) { |
| 2037 | 2033 | err = pci_request_regions(pci, "XFi"); |
| @@ -433,7 +433,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc, · 432 unmodified lines | ||
| 433 | 433 | pcm->private_data = atc; |
| 434 | 434 | pcm->info_flags = 0; |
| 435 | 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 | 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 | 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 | 213 | if (!mgr->rscs) |
| 214 | 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 | 169 | #endif |
| 170 | 170 | |
| 171 | − strlcpy(card->driver, emu->card_capabilities->driver, | |
| 171 | + strscpy(card->driver, emu->card_capabilities->driver, | |
| 172 | 172 | sizeof(card->driver)); |
| 173 | − strlcpy(card->shortname, emu->card_capabilities->name, | |
| 173 | + strscpy(card->shortname, emu->card_capabilities->name, | |
| 174 | 174 | sizeof(card->shortname)); |
| 175 | 175 | snprintf(card->longname, sizeof(card->longname), |
| 176 | 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 | 1869 | emu->serial); |
| 1870 | 1870 | |
| 1871 | 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 | 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 | 940 | memset(gctl, 0, sizeof(*gctl)); |
| 941 | 941 | id = &ctl->kcontrol->id; |
| 942 | 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 | 944 | gctl->id.index = id->index; |
| 945 | 945 | gctl->id.device = id->device; |
| 946 | 946 | gctl->id.subdevice = id->subdevice; |
| @@ -976,7 +976,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, · 29 unmodified lines | ||
| 976 | 976 | err = snd_emu10k1_verify_controls(emu, icode, in_kernel); |
| 977 | 977 | if (err < 0) |
| 978 | 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 | 980 | /* stop FX processor - this may be dangerous, but it's better to miss |
| 981 | 981 | some samples than generate wrong ones - [jk] */ |
| 982 | 982 | if (emu->audigy) |
| @@ -1015,7 +1015,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, · 32 unmodified lines | ||
| 1015 | 1015 | int err; |
| 1016 | 1016 | |
| 1017 | 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 | 1019 | /* ok, do the main job */ |
| 1020 | 1020 | err = snd_emu10k1_gpr_peek(emu, icode); |
| 1021 | 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 | 375 | struct snd_dma_buffer *dmab) |
| 376 | 376 | { |
| 377 | 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 | 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 | 752 | unsigned int freq, r; |
| 753 | 753 | |
| 754 | 754 | mutex_lock(&ensoniq->src_mutex); |
| 755 | − freq = ((rate << 15) + 1500) / 3000; | |
| 755 | + freq = DIV_ROUND_CLOSEST(rate << 15, 3000); | |
| 756 | 756 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
| 757 | 757 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | |
| 758 | 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 | 773 | unsigned int freq, r; |
| 774 | 774 | |
| 775 | 775 | mutex_lock(&ensoniq->src_mutex); |
| 776 | − freq = ((rate << 15) + 1500) / 3000; | |
| 776 | + freq = DIV_ROUND_CLOSEST(rate << 15, 3000); | |
| 777 | 777 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
| 778 | 778 | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | |
| 779 | 779 | ES_1371_DIS_P2; |
| @@ -1560,8 +1560,7 @@ static int snd_es1938_create(struct snd_card *card, · 1559 unmodified lines | ||
| 1560 | 1560 | if ((err = pci_enable_device(pci)) < 0) |
| 1561 | 1561 | return err; |
| 1562 | 1562 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 1563 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | |
| 1564 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | |
| 1563 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { | |
| 1565 | 1564 | dev_err(card->dev, |
| 1566 | 1565 | "architecture does not support 24bit PCI busmaster DMA\n"); |
| 1567 | 1566 | pci_disable_device(pci); |
| @@ -2668,8 +2668,7 @@ static int snd_es1968_create(struct snd_card *card, · 2667 unmodified lines | ||
| 2668 | 2668 | if ((err = pci_enable_device(pci)) < 0) |
| 2669 | 2669 | return err; |
| 2670 | 2670 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2671 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | |
| 2672 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | |
| 2671 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { | |
| 2673 | 2672 | dev_err(card->dev, |
| 2674 | 2673 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2675 | 2674 | pci_disable_device(pci); |
| @@ -2768,7 +2767,7 @@ static int snd_es1968_create(struct snd_card *card, · 92 unmodified lines | ||
| 2768 | 2767 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
| 2769 | 2768 | dev_info(card->dev, "detected TEA575x radio type %s\n", |
| 2770 | 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 | 2771 | sizeof(chip->tea.card)); |
| 2773 | 2772 | break; |
| 2774 | 2773 | } |
| @@ -1300,7 +1300,7 @@ static int snd_fm801_create(struct snd_card *card, · 1299 unmodified lines | ||
| 1300 | 1300 | chip->tea575x_tuner |= tuner_only; |
| 1301 | 1301 | } |
| 1302 | 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 | 1304 | sizeof(chip->tea.card)); |
| 1305 | 1305 | } |
| 1306 | 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 | 765 | if (!name) |
| 766 | 766 | return 0; |
| 767 | − strlcpy(label, name, maxlen); | |
| 767 | + strscpy(label, name, maxlen); | |
| 768 | 768 | return 1; |
| 769 | 769 | } |
| 770 | 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 | 3999 | sizeof(imux->items[imux->num_items].label), |
| 4000 | 4000 | "%s %d", label, label_idx); |
| 4001 | 4001 | else |
| 4002 | − strlcpy(imux->items[imux->num_items].label, label, | |
| 4002 | + strscpy(imux->items[imux->num_items].label, label, | |
| 4003 | 4003 | sizeof(imux->items[imux->num_items].label)); |
| 4004 | 4004 | imux->items[imux->num_items].index = index; |
| 4005 | 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 | 735 | &pcm); |
| 736 | 736 | if (err < 0) |
| 737 | 737 | return err; |
| 738 | − strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); | |
| 738 | + strscpy(pcm->name, cpcm->name, sizeof(pcm->name)); | |
| 739 | 739 | apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); |
| 740 | 740 | if (apcm == NULL) { |
| 741 | 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 | 260 | codec_info(codec, "HDMI: out of range MNL %d\n", mnl); |
| 261 | 261 | goto out_fail; |
| 262 | 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 | 265 | for (i = 0; i < e->sad_count; i++) { |
| 266 | 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 | 5722 | if (*str) |
| 5723 | 5723 | return; |
| 5724 | − strlcpy(str, chip_name, len); | |
| 5724 | + strscpy(str, chip_name, len); | |
| 5725 | 5725 | |
| 5726 | 5726 | /* drop non-alnum chars after a space */ |
| 5727 | 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 | 1967 | /* allow 64bit DMA address if supported by H/W */ |
| 1968 | 1968 | if (!(gcap & AZX_GCAP_64OK)) |
| 1969 | 1969 | dma_bits = 32; |
| 1970 | − if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) { | |
| 1971 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits)); | |
| 1972 | − } else { | |
| 1973 | − dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 1974 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); | |
| 1975 | − } | |
| 1970 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits))) | |
| 1971 | + dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)); | |
| 1976 | 1972 | |
| 1977 | 1973 | /* read number of streams from GCAP register instead of using |
| 1978 | 1974 | * hardcoded value |
| @@ -2037,7 +2033,7 @@ static int azx_first_init(struct azx *chip) · 58 unmodified lines | ||
| 2037 | 2033 | return -EBUSY; |
| 2038 | 2034 | |
| 2039 | 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 | 2037 | sizeof(card->shortname)); |
| 2042 | 2038 | snprintf(card->longname, sizeof(card->longname), |
| 2043 | 2039 | "%s at 0x%lx irq %i", |
| @@ -2221,8 +2217,6 @@ static const struct snd_pci_quirk power_save_denylist[] = { · 177 unmodified lines | ||
| 2221 | 2217 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2222 | 2218 | SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), |
| 2223 | 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 | 2220 | SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0), |
| 2227 | 2221 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ |
| 2228 | 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 | 2299 | /* HSW/BDW controllers need this power */ |
| 2306 | 2300 | if (CONTROLLER_IN_GPU(pci)) |
| 2307 | − hda->need_i915_power = 1; | |
| 2301 | + hda->need_i915_power = true; | |
| 2308 | 2302 | } |
| 2309 | 2303 | |
| 2310 | 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 | 2475 | /* CometLake-H */ |
| 2482 | 2476 | { PCI_DEVICE(0x8086, 0x06C8), |
| 2483 | 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 | 2480 | /* CometLake-S */ |
| 2485 | 2481 | { PCI_DEVICE(0x8086, 0xa3f0), |
| 2486 | 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 | 530 | !is_jack_detectable(codec, nid); |
| 531 | 531 | |
| 532 | 532 | if (base_name) |
| 533 | − strlcpy(name, base_name, sizeof(name)); | |
| 533 | + strscpy(name, base_name, sizeof(name)); | |
| 534 | 534 | else |
| 535 | 535 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL); |
| 536 | 536 | if (phantom_jack) |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/moduleparam.h> |
| 18 | 18 | #include <linux/mutex.h> |
| 19 | 19 | #include <linux/of_device.h> |
| 20 | +#include <linux/reset.h> | |
| 20 | 21 | #include <linux/slab.h> |
| 21 | 22 | #include <linux/time.h> |
| 22 | 23 | #include <linux/string.h> |
| @@ -70,9 +71,9 @@ · 47 unmodified lines | ||
| 70 | 71 | struct hda_tegra { |
| 71 | 72 | struct azx chip; |
| 72 | 73 | struct device *dev; |
| 73 | − struct clk *hda_clk; | |
| 74 | − struct clk *hda2codec_2x_clk; | |
| 75 | − struct clk *hda2hdmi_clk; | |
| 74 | + struct reset_control *reset; | |
| 75 | + struct clk_bulk_data clocks[3]; | |
| 76 | + unsigned int nclocks; | |
| 76 | 77 | void __iomem *regs; |
| 77 | 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 | 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 | 118 | * power management |
| 148 | 119 | */ |
| @@ -186,7 +157,7 @@ static int __maybe_unused hda_tegra_runtime_suspend(struct device *dev) · 37 unmodified lines | ||
| 186 | 157 | azx_stop_chip(chip); |
| 187 | 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 | 162 | return 0; |
| 192 | 163 | } |
| @@ -198,15 +169,27 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) · 5 unmodified lines | ||
| 198 | 169 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); |
| 199 | 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 | 179 | if (rc != 0) |
| 203 | 180 | return rc; |
| 204 | − if (chip && chip->running) { | |
| 181 | + if (chip->running) { | |
| 205 | 182 | hda_tegra_init(hda); |
| 206 | 183 | azx_init_chip(chip, 1); |
| 207 | 184 | /* disable controller wake up event*/ |
| 208 | 185 | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & |
| 209 | 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 | 195 | return 0; |
| @@ -268,29 +251,6 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) · 55 unmodified lines | ||
| 268 | 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 | 254 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) |
| 295 | 255 | { |
| 296 | 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 | 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 | 469 | if (err < 0) |
| 500 | 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 | 568 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
| 569 | 569 | spec->mute_led_eapd = 0x1b; |
| 570 | − spec->dynamic_eapd = 1; | |
| 570 | + spec->dynamic_eapd = true; | |
| 571 | 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 | 2130 | goto unlock; |
| 2131 | 2131 | } |
| 2132 | 2132 | per_cvt = get_cvt(spec, cvt_idx); |
| 2133 | − snd_BUG_ON(!per_cvt->assigned); | |
| 2134 | 2133 | per_cvt->assigned = 0; |
| 2135 | 2134 | hinfo->nid = 0; |
| 2136 | 2135 | |
| @@ -1905,6 +1905,7 @@ enum { · 1904 unmodified lines | ||
| 1905 | 1905 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, |
| 1906 | 1906 | ALC889_FIXUP_VAIO_TT, |
| 1907 | 1907 | ALC888_FIXUP_EEE1601, |
| 1908 | + ALC886_FIXUP_EAPD, | |
| 1908 | 1909 | ALC882_FIXUP_EAPD, |
| 1909 | 1910 | ALC883_FIXUP_EAPD, |
| 1910 | 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 | 2251 | [ALC882_FIXUP_EAPD] = { |
| 2242 | 2252 | .type = HDA_FIXUP_VERBS, |
| 2243 | 2253 | .v.verbs = (const struct hda_verb[]) { |
| @@ -2510,6 +2520,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { · 266 unmodified lines | ||
| 2510 | 2520 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), |
| 2511 | 2521 | |
| 2512 | 2522 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
| 2523 | + SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD), | |
| 2513 | 2524 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
| 2514 | 2525 | SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), |
| 2515 | 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 | 4316 | static void alc_update_coef_led(struct hda_codec *codec, |
| 4284 | 4317 | struct alc_coef_led *led, |
| 4285 | 4318 | bool polarity, bool on) |
| @@ -6266,6 +6299,7 @@ enum { · 1980 unmodified lines | ||
| 6266 | 6299 | ALC280_FIXUP_HP_DOCK_PINS, |
| 6267 | 6300 | ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, |
| 6268 | 6301 | ALC280_FIXUP_HP_9480M, |
| 6302 | + ALC245_FIXUP_HP_X360_AMP, | |
| 6269 | 6303 | ALC288_FIXUP_DELL_HEADSET_MODE, |
| 6270 | 6304 | ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, |
| 6271 | 6305 | ALC288_FIXUP_DELL_XPS_13, |
| @@ -6971,6 +7005,10 @@ static const struct hda_fixup alc269_fixups[] = { · 699 unmodified lines | ||
| 6971 | 7005 | .type = HDA_FIXUP_FUNC, |
| 6972 | 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 | 7012 | [ALC288_FIXUP_DELL_HEADSET_MODE] = { |
| 6975 | 7013 | .type = HDA_FIXUP_FUNC, |
| 6976 | 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 | 8023 | SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 7986 | 8024 | SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), |
| 7987 | 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 | 8027 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
| 7989 | 8028 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
| 7990 | 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 | 8396 | {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"}, |
| 8358 | 8397 | {.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"}, |
| 8359 | 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 | 8402 | #define ALC225_STANDARD_PINS \ |
| @@ -2486,8 +2486,7 @@ static int snd_ice1712_create(struct snd_card *card, · 2485 unmodified lines | ||
| 2486 | 2486 | if (err < 0) |
| 2487 | 2487 | return err; |
| 2488 | 2488 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2489 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | |
| 2490 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | |
| 2489 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { | |
| 2491 | 2490 | dev_err(card->dev, |
| 2492 | 2491 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2493 | 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 | 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 | 417 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 418 | 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 | 189 | /* notify about master speaker mute change */ |
| 190 | 190 | memset(&elem_id, 0, sizeof(elem_id)); |
| 191 | 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 | 193 | sizeof(elem_id.name)); |
| 194 | 194 | kctl = snd_ctl_find_id(ice->card, &elem_id); |
| 195 | 195 | snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); |
| 196 | 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 | 198 | sizeof(elem_id.name)); |
| 199 | 199 | kctl = snd_ctl_find_id(ice->card, &elem_id); |
| 200 | 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 | 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 | 775 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 776 | 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 | 38 | unsigned int index_offset; |
| 39 | 39 | |
| 40 | 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 | 42 | elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 43 | 43 | kctl = snd_ctl_find_id(card, &elem_id); |
| 44 | 44 | if (!kctl) |
| @@ -1129,13 +1129,14 @@ static int snd_intel8x0m_create(struct snd_card *card, · 1128 unmodified lines | ||
| 1129 | 1129 | chip->bmaddr = pci_iomap(pci, 3, 0); |
| 1130 | 1130 | else |
| 1131 | 1131 | chip->bmaddr = pci_iomap(pci, 1, 0); |
| 1132 | + | |
| 1133 | +port_inited: | |
| 1132 | 1134 | if (!chip->bmaddr) { |
| 1133 | 1135 | dev_err(card->dev, "Controller space ioremap problem\n"); |
| 1134 | 1136 | snd_intel8x0m_free(chip); |
| 1135 | 1137 | return -EIO; |
| 1136 | 1138 | } |
| 1137 | 1139 | |
| 1138 | − port_inited: | |
| 1139 | 1140 | /* initialize offsets */ |
| 1140 | 1141 | chip->bdbars_count = 2; |
| 1141 | 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 | 671 | strcpy(card->driver, "Lola"); |
| 672 | − strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); | |
| 672 | + strscpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); | |
| 673 | 673 | snprintf(card->longname, sizeof(card->longname), |
| 674 | 674 | "%s at 0x%lx irq %i", |
| 675 | 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 | 137 | nitems = chip->clock.items; |
| 138 | − nb_verbs = (nitems + 3) / 4; | |
| 138 | + nb_verbs = DIV_ROUND_UP(nitems, 4); | |
| 139 | 139 | idx = 0; |
| 140 | 140 | idx_list = 0; |
| 141 | 141 | for (i = 0; i < nb_verbs; i++) { |
| @@ -601,7 +601,7 @@ int lola_create_pcm(struct lola *chip) · 600 unmodified lines | ||
| 601 | 601 | &pcm); |
| 602 | 602 | if (err < 0) |
| 603 | 603 | return err; |
| 604 | − strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name)); | |
| 604 | + strscpy(pcm->name, "Digigram Lola", sizeof(pcm->name)); | |
| 605 | 605 | pcm->private_data = chip; |
| 606 | 606 | for (i = 0; i < 2; i++) { |
| 607 | 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 | 1245 | snd_pcm_format_width(runtime->format) == 16 ? 0 : 1); |
| 1246 | 1246 | |
| 1247 | 1247 | /* set up dac/adc rate */ |
| 1248 | − freq = ((runtime->rate << 15) + 24000 ) / 48000; | |
| 1248 | + freq = DIV_ROUND_CLOSEST(runtime->rate << 15, 48000); | |
| 1249 | 1249 | if (freq) |
| 1250 | 1250 | freq--; |
| 1251 | 1251 | |
| @@ -2532,8 +2532,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, · 1280 unmodified lines | ||
| 2532 | 2532 | return -EIO; |
| 2533 | 2533 | |
| 2534 | 2534 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
| 2535 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 || | |
| 2536 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) { | |
| 2535 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) { | |
| 2537 | 2536 | dev_err(card->dev, |
| 2538 | 2537 | "architecture does not support 28bit PCI busmaster DMA\n"); |
| 2539 | 2538 | pci_disable_device(pci); |
| @@ -469,6 +469,7 @@ struct hdsp { · 468 unmodified lines | ||
| 469 | 469 | unsigned char qs_out_channels; |
| 470 | 470 | unsigned char ds_out_channels; |
| 471 | 471 | unsigned char ss_out_channels; |
| 472 | + u32 io_loopback; /* output loopback channel states*/ | |
| 472 | 473 | |
| 473 | 474 | struct snd_dma_buffer capture_dma_buf; |
| 474 | 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 | 3254 | HDSP_AnalogExtensionBoard); |
| 3254 | 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 | 3311 | static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) |
| 3257 | 3312 | { |
| 3258 | 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 | 3366 | /* AEB control for H96xx card */ |
| 3301 | 3367 | if (hdsp->io_type == H9632 || hdsp->io_type == H9652) { |
| 3302 | 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 | 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 | 5027 | switch (hdsp->io_type) { |
| 4962 | 5028 | case Digiface: |
| @@ -4983,6 +5049,12 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp) · 20 unmodified lines | ||
| 4983 | 5049 | hdsp->ss_out_channels = H9632_SS_CHANNELS+aebo_channels; |
| 4984 | 5050 | hdsp->ds_out_channels = H9632_DS_CHANNELS+aebo_channels; |
| 4985 | 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 | 5058 | break; |
| 4987 | 5059 | |
| 4988 | 5060 | case Multiface: |
| @@ -6329,7 +6329,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, · 6328 unmodified lines | ||
| 6329 | 6329 | memset(&hdspm_version, 0, sizeof(hdspm_version)); |
| 6330 | 6330 | |
| 6331 | 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 | 6333 | sizeof(hdspm_version.cardname)); |
| 6334 | 6334 | hdspm_version.serial = hdspm->serial; |
| 6335 | 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 | 363 | else if (rate == 48000) |
| 364 | 364 | delta = 0x1000; |
| 365 | 365 | else |
| 366 | − delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; | |
| 366 | + delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff; | |
| 367 | 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 | 570 | unsigned int div; |
| 571 | 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 | 574 | if (div > 65535) |
| 575 | 575 | div = 65535; |
| 576 | 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 | 1230 | if ((err = pci_enable_device(pci)) < 0) |
| 1231 | 1231 | return err; |
| 1232 | 1232 | /* check, if we can restrict PCI DMA transfers to 24 bits */ |
| 1233 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(24)) < 0 || | |
| 1234 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(24)) < 0) { | |
| 1233 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) { | |
| 1235 | 1234 | dev_err(card->dev, |
| 1236 | 1235 | "architecture does not support 24bit PCI busmaster DMA\n"); |
| 1237 | 1236 | pci_disable_device(pci); |
| @@ -678,7 +678,7 @@ static unsigned int snd_trident_convert_rate(unsigned int rate) · 677 unmodified lines | ||
| 678 | 678 | else if (rate == 48000) |
| 679 | 679 | delta = 0x1000; |
| 680 | 680 | else |
| 681 | − delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff; | |
| 681 | + delta = DIV_ROUND_CLOSEST(rate << 12, 48000) & 0x0000ffff; | |
| 682 | 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 | 1034 | ESO_bytes++; |
| 1035 | 1035 | |
| 1036 | 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 | 1038 | outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R)); |
| 1039 | 1039 | |
| 1040 | 1040 | // Set channel interrupt blk length |
| @@ -3497,8 +3497,7 @@ int snd_trident_create(struct snd_card *card, · 2456 unmodified lines | ||
| 3497 | 3497 | if ((err = pci_enable_device(pci)) < 0) |
| 3498 | 3498 | return err; |
| 3499 | 3499 | /* check, if we can restrict PCI DMA transfers to 30 bits */ |
| 3500 | − if (dma_set_mask(&pci->dev, DMA_BIT_MASK(30)) < 0 || | |
| 3501 | − dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(30)) < 0) { | |
| 3500 | + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(30))) { | |
| 3502 | 3501 | dev_err(card->dev, |
| 3503 | 3502 | "architecture does not support 30bit PCI busmaster DMA\n"); |
| 3504 | 3503 | pci_disable_device(pci); |
| @@ -49,7 +49,7 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) · 48 unmodified lines | ||
| 49 | 49 | return -EINVAL; /* ignored */ |
| 50 | 50 | |
| 51 | 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 | 53 | info.addr = keywest_ctx->addr; |
| 54 | 54 | client = i2c_new_client_device(adapter, &info); |
| 55 | 55 | if (IS_ERR(client)) |
| @@ -37,6 +37,23 @@ config SND_SOC_COMPRESS · 36 unmodified lines | ||
| 37 | 37 | config SND_SOC_TOPOLOGY |
| 38 | 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 | 57 | config SND_SOC_ACPI |
| 41 | 58 | tristate |
| 42 | 59 | |
| @@ -62,7 +79,6 @@ source "sound/soc/qcom/Kconfig" · 19 unmodified lines | ||
| 62 | 79 | source "sound/soc/rockchip/Kconfig" |
| 63 | 80 | source "sound/soc/samsung/Kconfig" |
| 64 | 81 | source "sound/soc/sh/Kconfig" |
| 65 | −source "sound/soc/sirf/Kconfig" | |
| 66 | 82 | source "sound/soc/sof/Kconfig" |
| 67 | 83 | source "sound/soc/spear/Kconfig" |
| 68 | 84 | source "sound/soc/sprd/Kconfig" |
| @@ -71,12 +87,10 @@ source "sound/soc/stm/Kconfig" · 2 unmodified lines | ||
| 71 | 87 | source "sound/soc/sunxi/Kconfig" |
| 72 | 88 | source "sound/soc/tegra/Kconfig" |
| 73 | 89 | source "sound/soc/ti/Kconfig" |
| 74 | −source "sound/soc/txx9/Kconfig" | |
| 75 | 90 | source "sound/soc/uniphier/Kconfig" |
| 76 | 91 | source "sound/soc/ux500/Kconfig" |
| 77 | 92 | source "sound/soc/xilinx/Kconfig" |
| 78 | 93 | source "sound/soc/xtensa/Kconfig" |
| 79 | −source "sound/soc/zte/Kconfig" | |
| 80 | 94 | |
| 81 | 95 | # Supported codecs |
| 82 | 96 | source "sound/soc/codecs/Kconfig" |
| @@ -7,6 +7,11 @@ ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) · 6 unmodified lines | ||
| 7 | 7 | snd-soc-core-objs += soc-topology.o |
| 8 | 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 | 15 | ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) |
| 11 | 16 | snd-soc-core-objs += soc-generic-dmaengine-pcm.o |
| 12 | 17 | endif |
| @@ -45,7 +50,6 @@ obj-$(CONFIG_SND_SOC) += qcom/ · 32 unmodified lines | ||
| 45 | 50 | obj-$(CONFIG_SND_SOC) += rockchip/ |
| 46 | 51 | obj-$(CONFIG_SND_SOC) += samsung/ |
| 47 | 52 | obj-$(CONFIG_SND_SOC) += sh/ |
| 48 | −obj-$(CONFIG_SND_SOC) += sirf/ | |
| 49 | 53 | obj-$(CONFIG_SND_SOC) += sof/ |
| 50 | 54 | obj-$(CONFIG_SND_SOC) += spear/ |
| 51 | 55 | obj-$(CONFIG_SND_SOC) += sprd/ |
| @@ -54,9 +58,7 @@ obj-$(CONFIG_SND_SOC) += stm/ · 2 unmodified lines | ||
| 54 | 58 | obj-$(CONFIG_SND_SOC) += sunxi/ |
| 55 | 59 | obj-$(CONFIG_SND_SOC) += tegra/ |
| 56 | 60 | obj-$(CONFIG_SND_SOC) += ti/ |
| 57 | −obj-$(CONFIG_SND_SOC) += txx9/ | |
| 58 | 61 | obj-$(CONFIG_SND_SOC) += uniphier/ |
| 59 | 62 | obj-$(CONFIG_SND_SOC) += ux500/ |
| 60 | 63 | obj-$(CONFIG_SND_SOC) += xilinx/ |
| 61 | 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 | 156 | static struct snd_soc_dai_driver axi_i2s_dai = { |
| 157 | 157 | .probe = axi_i2s_dai_probe, |
| 158 | 158 | .ops = &axi_i2s_dai_ops, |
| 159 | − .symmetric_rates = 1, | |
| 159 | + .symmetric_rate = 1, | |
| 160 | 160 | }; |
| 161 | 161 | |
| 162 | 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 | 140 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 141 | 141 | if (strcmp(codec_dai->name, "rt1015-aif")) |
| 142 | 142 | continue; |
| 143 | − ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); | |
| 144 | − if (ret < 0) | |
| 145 | − return ret; | |
| 143 | + | |
| 146 | 144 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 147 | 145 | 64 * srate, 256 * srate); |
| 148 | 146 | if (ret < 0) |
| @@ -541,7 +541,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = { · 540 unmodified lines | ||
| 541 | 541 | .formats = ATMEL_I2S_FORMATS, |
| 542 | 542 | }, |
| 543 | 543 | .ops = &atmel_i2s_dai_ops, |
| 544 | − .symmetric_rates = 1, | |
| 544 | + .symmetric_rate = 1, | |
| 545 | 545 | }; |
| 546 | 546 | |
| 547 | 547 | static const struct snd_soc_component_driver atmel_i2s_component = { |
| @@ -34,86 +34,21 @@ · 33 unmodified lines | ||
| 34 | 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 | 37 | static int atmel_pcm_new(struct snd_soc_component *component, |
| 69 | 38 | struct snd_soc_pcm_runtime *rtd) |
| 70 | 39 | { |
| 71 | 40 | struct snd_card *card = rtd->card->snd_card; |
| 72 | − struct snd_pcm *pcm = rtd->pcm; | |
| 73 | 41 | int ret; |
| 74 | 42 | |
| 75 | 43 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); |
| 76 | 44 | if (ret) |
| 77 | 45 | return ret; |
| 78 | 46 | |
| 79 | − if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | |
| 80 | − pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); | |
| 81 | − ret = atmel_pcm_preallocate_dma_buffer(pcm, | |
| 82 | − SNDRV_PCM_STREAM_PLAYBACK); | |
| 83 | − if (ret) | |
| 84 | − goto out; | |
| 85 | − } | |
| 47 | + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, | |
| 48 | + card->dev, ATMEL_SSC_DMABUF_SIZE, | |
| 49 | + ATMEL_SSC_DMABUF_SIZE); | |
| 86 | 50 | |
| 87 | − if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | |
| 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 | − } | |
| 51 | + return 0; | |
| 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 | 145 | /* this may get called several times by oss emulation |
| 211 | 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 | 148 | prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); |
| 217 | 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 | 316 | .prepare = atmel_pcm_prepare, |
| 385 | 317 | .trigger = atmel_pcm_trigger, |
| 386 | 318 | .pointer = atmel_pcm_pointer, |
| 387 | − .mmap = atmel_pcm_mmap, | |
| 388 | 319 | .pcm_construct = atmel_pcm_new, |
| 389 | − .pcm_destruct = atmel_pcm_free, | |
| 390 | 320 | }; |
| 391 | 321 | |
| 392 | 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 | 859 | .formats = MCHP_I2SMCC_FORMATS, |
| 860 | 860 | }, |
| 861 | 861 | .ops = &mchp_i2s_mcc_dai_ops, |
| 862 | − .symmetric_rates = 1, | |
| 863 | − .symmetric_samplebits = 1, | |
| 862 | + .symmetric_rate = 1, | |
| 863 | + .symmetric_sample_bits = 1, | |
| 864 | 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 | 212 | static struct snd_soc_dai_driver au1xi2s_dai_driver = { |
| 213 | − .symmetric_rates = 1, | |
| 213 | + .symmetric_rate = 1, | |
| 214 | 214 | .playback = { |
| 215 | 215 | .rates = AU1XI2SC_RATES, |
| 216 | 216 | .formats = AU1XI2SC_FMTS, |
| @@ -783,8 +783,8 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = { · 782 unmodified lines | ||
| 783 | 783 | | SNDRV_PCM_FMTBIT_S32_LE |
| 784 | 784 | }, |
| 785 | 785 | .ops = &bcm2835_i2s_dai_ops, |
| 786 | − .symmetric_rates = 1, | |
| 787 | − .symmetric_samplebits = 1, | |
| 786 | + .symmetric_rate = 1, | |
| 787 | + .symmetric_sample_bits = 1, | |
| 788 | 788 | }; |
| 789 | 789 | |
| 790 | 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 | 212 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 213 | 213 | }, |
| 214 | 214 | .ops = &bcm63xx_i2s_dai_ops, |
| 215 | − .symmetric_rates = 1, | |
| 215 | + .symmetric_rate = 1, | |
| 216 | 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 | 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 | 639 | static int cygnus_pcm_prepare(struct snd_soc_component *component, |
| 670 | 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 | 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 | 703 | static int cygnus_dma_new(struct snd_soc_component *component, |
| 788 | 704 | struct snd_soc_pcm_runtime *rtd) |
| 789 | 705 | { |
| 706 | + size_t size = cygnus_pcm_hw.buffer_bytes_max; | |
| 790 | 707 | struct snd_card *card = rtd->card->snd_card; |
| 791 | − struct snd_pcm *pcm = rtd->pcm; | |
| 792 | − int ret; | |
| 793 | 708 | |
| 794 | 709 | if (!card->dev->dma_mask) |
| 795 | 710 | card->dev->dma_mask = &cygnus_dma_dmamask; |
| 796 | 711 | if (!card->dev->coherent_dma_mask) |
| 797 | 712 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
| 798 | 713 | |
| 799 | − if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | |
| 800 | − ret = cygnus_pcm_preallocate_dma_buffer(pcm, | |
| 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 | − } | |
| 714 | + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, | |
| 715 | + card->dev, size, size); | |
| 814 | 716 | |
| 815 | 717 | return 0; |
| 816 | 718 | } |
| @@ -818,13 +720,10 @@ static int cygnus_dma_new(struct snd_soc_component *component, · 1 unmodified line | ||
| 818 | 720 | static struct snd_soc_component_driver cygnus_soc_platform = { |
| 819 | 721 | .open = cygnus_pcm_open, |
| 820 | 722 | .close = cygnus_pcm_close, |
| 821 | − .hw_params = cygnus_pcm_hw_params, | |
| 822 | − .hw_free = cygnus_pcm_hw_free, | |
| 823 | 723 | .prepare = cygnus_pcm_prepare, |
| 824 | 724 | .trigger = cygnus_pcm_trigger, |
| 825 | 725 | .pointer = cygnus_pcm_pointer, |
| 826 | 726 | .pcm_construct = cygnus_dma_new, |
| 827 | − .pcm_destruct = cygnus_dma_free_dma_buffers, | |
| 828 | 727 | }; |
| 829 | 728 | |
| 830 | 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 | 404 | #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) |
| 405 | 405 | |
| 406 | 406 | static struct snd_soc_dai_driver ep93xx_i2s_dai = { |
| 407 | − .symmetric_rates= 1, | |
| 407 | + .symmetric_rate = 1, | |
| 408 | 408 | .probe = ep93xx_i2s_dai_probe, |
| 409 | 409 | .playback = { |
| 410 | 410 | .channels_min = 2, |
| @@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS · 103 unmodified lines | ||
| 104 | 104 | imply SND_SOC_ISABELLE |
| 105 | 105 | imply SND_SOC_JZ4740_CODEC |
| 106 | 106 | imply SND_SOC_JZ4725B_CODEC |
| 107 | + imply SND_SOC_JZ4760_CODEC | |
| 107 | 108 | imply SND_SOC_JZ4770_CODEC |
| 108 | 109 | imply SND_SOC_LM4857 |
| 109 | 110 | imply SND_SOC_LM49453 |
| @@ -227,6 +228,8 @@ config SND_SOC_ALL_CODECS · 117 unmodified lines | ||
| 227 | 228 | imply SND_SOC_UDA1380 |
| 228 | 229 | imply SND_SOC_WCD9335 |
| 229 | 230 | imply SND_SOC_WCD934X |
| 231 | + imply SND_SOC_LPASS_RX_MACRO | |
| 232 | + imply SND_SOC_LPASS_TX_MACRO | |
| 230 | 233 | imply SND_SOC_WL1273 |
| 231 | 234 | imply SND_SOC_WM0010 |
| 232 | 235 | imply SND_SOC_WM1250_EV1 |
| @@ -712,7 +715,7 @@ config SND_SOC_CX2072X · 479 unmodified lines | ||
| 712 | 715 | Enable support for Conexant CX20721 and CX20723 codec chips. |
| 713 | 716 | |
| 714 | 717 | config SND_SOC_JZ4740_CODEC |
| 715 | − depends on MIPS || COMPILE_TEST | |
| 718 | + depends on MACH_INGENIC || COMPILE_TEST | |
| 716 | 719 | depends on OF |
| 717 | 720 | select REGMAP_MMIO |
| 718 | 721 | tristate "Ingenic JZ4740 internal CODEC" |
| @@ -724,7 +727,7 @@ config SND_SOC_JZ4740_CODEC · 5 unmodified lines | ||
| 724 | 727 | will be called snd-soc-jz4740-codec. |
| 725 | 728 | |
| 726 | 729 | config SND_SOC_JZ4725B_CODEC |
| 727 | − depends on MIPS || COMPILE_TEST | |
| 730 | + depends on MACH_INGENIC || COMPILE_TEST | |
| 728 | 731 | depends on OF |
| 729 | 732 | select REGMAP |
| 730 | 733 | tristate "Ingenic JZ4725B internal CODEC" |
| @@ -735,8 +738,20 @@ config SND_SOC_JZ4725B_CODEC · 4 unmodified lines | ||
| 735 | 738 | This driver can also be built as a module. If so, the module |
| 736 | 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 | 753 | config SND_SOC_JZ4770_CODEC |
| 739 | − depends on MIPS || COMPILE_TEST | |
| 754 | + depends on MACH_INGENIC || COMPILE_TEST | |
| 740 | 755 | depends on OF |
| 741 | 756 | select REGMAP |
| 742 | 757 | tristate "Ingenic JZ4770 internal CODEC" |
| @@ -1162,7 +1177,7 @@ config SND_SOC_RT5651 · 419 unmodified lines | ||
| 1162 | 1177 | depends on I2C |
| 1163 | 1178 | |
| 1164 | 1179 | config SND_SOC_RT5659 |
| 1165 | − tristate | |
| 1180 | + tristate "Realtek RT5658/RT5659 Codec" | |
| 1166 | 1181 | depends on I2C |
| 1167 | 1182 | |
| 1168 | 1183 | config SND_SOC_RT5660 |
| @@ -1820,4 +1835,12 @@ config SND_SOC_LPASS_VA_MACRO · 651 unmodified lines | ||
| 1820 | 1835 | depends on COMMON_CLK |
| 1821 | 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 | 1846 | endmenu |
| @@ -101,11 +101,14 @@ snd-soc-inno-rk3036-objs := inno_rk3036.o · 100 unmodified lines | ||
| 101 | 101 | snd-soc-isabelle-objs := isabelle.o |
| 102 | 102 | snd-soc-jz4740-codec-objs := jz4740.o |
| 103 | 103 | snd-soc-jz4725b-codec-objs := jz4725b.o |
| 104 | +snd-soc-jz4760-codec-objs := jz4760.o | |
| 104 | 105 | snd-soc-jz4770-codec-objs := jz4770.o |
| 105 | 106 | snd-soc-l3-objs := l3.o |
| 106 | 107 | snd-soc-lm4857-objs := lm4857.o |
| 107 | 108 | snd-soc-lm49453-objs := lm49453.o |
| 108 | 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 | 112 | snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o |
| 110 | 113 | snd-soc-lpass-va-macro-objs := lpass-va-macro.o |
| 111 | 114 | snd-soc-madera-objs := madera.o |
| @@ -201,7 +204,6 @@ snd-soc-sigmadsp-objs := sigmadsp.o · 89 unmodified lines | ||
| 201 | 204 | snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o |
| 202 | 205 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o |
| 203 | 206 | snd-soc-si476x-objs := si476x.o |
| 204 | −snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o | |
| 205 | 207 | snd-soc-spdif-tx-objs := spdif_transmitter.o |
| 206 | 208 | snd-soc-spdif-rx-objs := spdif_receiver.o |
| 207 | 209 | snd-soc-ssm2305-objs := ssm2305.o |
| @@ -302,7 +304,6 @@ snd-soc-wm9713-objs := wm9713.o · 94 unmodified lines | ||
| 302 | 304 | snd-soc-wm-hubs-objs := wm_hubs.o |
| 303 | 305 | snd-soc-wsa881x-objs := wsa881x.o |
| 304 | 306 | snd-soc-zl38060-objs := zl38060.o |
| 305 | −snd-soc-zx-aud96p22-objs := zx_aud96p22.o | |
| 306 | 307 | # Amp |
| 307 | 308 | snd-soc-max9877-objs := max9877.o |
| 308 | 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 | 419 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o |
| 419 | 420 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o |
| 420 | 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 | 423 | obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o |
| 422 | 424 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o |
| 423 | 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 | 518 | obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o |
| 517 | 519 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o |
| 518 | 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 | 521 | obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o |
| 521 | 522 | obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o |
| 522 | 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 | 619 | obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o |
| 619 | 620 | obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o |
| 620 | 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 | 623 | # Amp |
| 624 | 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 | 627 | obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o |
| 628 | 628 | obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o |
| 629 | 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 | 633 | # Mux |
| 632 | 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 | 2384 | .formats = AB8500_SUPPORTED_FMT, |
| 2385 | 2385 | }, |
| 2386 | 2386 | .ops = &ab8500_codec_ops, |
| 2387 | − .symmetric_rates = 1 | |
| 2387 | + .symmetric_rate = 1 | |
| 2388 | 2388 | }, |
| 2389 | 2389 | { |
| 2390 | 2390 | .name = "ab8500-codec-dai.1", |
| @@ -2397,7 +2397,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { · 6 unmodified lines | ||
| 2397 | 2397 | .formats = AB8500_SUPPORTED_FMT, |
| 2398 | 2398 | }, |
| 2399 | 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 | 890 | .sig_bits = 24, |
| 891 | 891 | }, |
| 892 | 892 | .ops = &adau1372_dai_ops, |
| 893 | − .symmetric_rates = 1, | |
| 893 | + .symmetric_rate = 1, | |
| 894 | 894 | }; |
| 895 | 895 | |
| 896 | 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 | 1205 | .formats = ADAU1373_FORMATS, |
| 1206 | 1206 | }, |
| 1207 | 1207 | .ops = &adau1373_dai_ops, |
| 1208 | − .symmetric_rates = 1, | |
| 1208 | + .symmetric_rate = 1, | |
| 1209 | 1209 | }, |
| 1210 | 1210 | { |
| 1211 | 1211 | .id = 1, |
| @@ -1225,7 +1225,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { · 13 unmodified lines | ||
| 1225 | 1225 | .formats = ADAU1373_FORMATS, |
| 1226 | 1226 | }, |
| 1227 | 1227 | .ops = &adau1373_dai_ops, |
| 1228 | − .symmetric_rates = 1, | |
| 1228 | + .symmetric_rate = 1, | |
| 1229 | 1229 | }, |
| 1230 | 1230 | { |
| 1231 | 1231 | .id = 2, |
| @@ -1245,7 +1245,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = { · 13 unmodified lines | ||
| 1245 | 1245 | .formats = ADAU1373_FORMATS, |
| 1246 | 1246 | }, |
| 1247 | 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 | 653 | .formats = ADAU1701_FORMATS, |
| 654 | 654 | }, |
| 655 | 655 | .ops = &adau1701_dai_ops, |
| 656 | − .symmetric_rates = 1, | |
| 656 | + .symmetric_rate = 1, | |
| 657 | 657 | }; |
| 658 | 658 | |
| 659 | 659 | #ifdef CONFIG_OF |
| @@ -1095,8 +1095,7 @@ void adau17x1_remove(struct device *dev) · 1094 unmodified lines | ||
| 1095 | 1095 | { |
| 1096 | 1096 | struct adau *adau = dev_get_drvdata(dev); |
| 1097 | 1097 | |
| 1098 | − if (adau->mclk) | |
| 1099 | − clk_disable_unprepare(adau->mclk); | |
| 1098 | + clk_disable_unprepare(adau->mclk); | |
| 1100 | 1099 | } |
| 1101 | 1100 | EXPORT_SYMBOL_GPL(adau17x1_remove); |
| 1102 | 1101 | |
| @@ -56,7 +56,7 @@ static struct snd_soc_dai_driver ak4554_dai = { · 55 unmodified lines | ||
| 56 | 56 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 57 | 57 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 58 | 58 | }, |
| 59 | − .symmetric_rates = 1, | |
| 59 | + .symmetric_rate = 1, | |
| 60 | 60 | }; |
| 61 | 61 | |
| 62 | 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 | 575 | .formats = AK4613_PCM_FMTBIT, |
| 576 | 576 | }, |
| 577 | 577 | .ops = &ak4613_dai_ops, |
| 578 | − .symmetric_rates = 1, | |
| 578 | + .symmetric_rate = 1, | |
| 579 | 579 | }; |
| 580 | 580 | |
| 581 | 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 | 499 | .formats = AK4641_FORMATS, |
| 500 | 500 | }, |
| 501 | 501 | .ops = &ak4641_i2s_dai_ops, |
| 502 | − .symmetric_rates = 1, | |
| 502 | + .symmetric_rate = 1, | |
| 503 | 503 | }, |
| 504 | 504 | { |
| 505 | 505 | .name = "ak4641-voice", |
| @@ -519,7 +519,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { · 13 unmodified lines | ||
| 519 | 519 | .formats = AK4641_FORMATS, |
| 520 | 520 | }, |
| 521 | 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 | 516 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 517 | 517 | .formats = SNDRV_PCM_FMTBIT_S16_LE }, |
| 518 | 518 | .ops = &ak4642_dai_ops, |
| 519 | − .symmetric_rates = 1, | |
| 519 | + .symmetric_rate = 1, | |
| 520 | 520 | }; |
| 521 | 521 | |
| 522 | 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 | 1032 | .formats = ALC5632_FORMATS,}, |
| 1033 | 1033 | |
| 1034 | 1034 | .ops = &alc5632_dai_ops, |
| 1035 | − .symmetric_rates = 1, | |
| 1035 | + .symmetric_rate = 1, | |
| 1036 | 1036 | }; |
| 1037 | 1037 | |
| 1038 | 1038 | #ifdef CONFIG_PM |
| @@ -16,6 +16,14 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <sound/soc.h> |
| 17 | 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 | 27 | /* Register 513 CPCAP_REG_CC --- CODEC */ |
| 20 | 28 | #define CPCAP_BIT_CDC_CLK2 15 |
| 21 | 29 | #define CPCAP_BIT_CDC_CLK1 14 |
| @@ -221,6 +229,7 @@ struct cpcap_reg_info { · 199 unmodified lines | ||
| 221 | 229 | }; |
| 222 | 230 | |
| 223 | 231 | static const struct cpcap_reg_info cpcap_default_regs[] = { |
| 232 | + { CPCAP_REG_VAUDIOC, 0x003F, 0x0000 }, | |
| 224 | 233 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, |
| 225 | 234 | { CPCAP_REG_CC, 0xFFFF, 0x0000 }, |
| 226 | 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 | 1274 | if (direction == SNDRV_PCM_STREAM_CAPTURE) { |
| 1266 | 1275 | mask = 0x0000; |
| 1267 | − mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0; | |
| 1268 | − mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1; | |
| 1269 | − mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2; | |
| 1270 | − mask |= CPCAP_BIT_MIC2_TIMESLOT0; | |
| 1271 | − mask |= CPCAP_BIT_MIC2_TIMESLOT1; | |
| 1272 | − mask |= CPCAP_BIT_MIC2_TIMESLOT2; | |
| 1276 | + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); | |
| 1277 | + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1); | |
| 1278 | + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2); | |
| 1279 | + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0); | |
| 1280 | + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1); | |
| 1281 | + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2); | |
| 1273 | 1282 | val = 0x0000; |
| 1274 | 1283 | if (channels >= 2) |
| 1275 | 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 | 1380 | return 0; |
| 1372 | 1381 | } |
| 1373 | 1382 | |
| 1374 | −static int cpcap_voice_set_mute(struct snd_soc_dai *dai, | |
| 1375 | − int mute, int direction) | |
| 1383 | + | |
| 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 | 1499 | struct snd_soc_component *component = dai->component; |
| 1378 | 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 | 1515 | .hw_params = cpcap_voice_hw_params, |
| 1394 | 1516 | .set_sysclk = cpcap_voice_set_dai_sysclk, |
| 1395 | 1517 | .set_fmt = cpcap_voice_set_dai_fmt, |
| 1518 | + .set_tdm_slot = cpcap_voice_set_tdm_slot, | |
| 1396 | 1519 | .mute_stream = cpcap_voice_set_mute, |
| 1397 | 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 | 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 | 1026 | platform_set_drvdata(pdev, priv); |
| 1015 | 1027 | |
| 1016 | 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 | 194 | .formats = CS35L32_FORMATS, |
| 195 | 195 | }, |
| 196 | 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 | 691 | .formats = CS35L33_FORMATS, |
| 692 | 692 | }, |
| 693 | 693 | .ops = &cs35l33_ops, |
| 694 | − .symmetric_rates = 1, | |
| 694 | + .symmetric_rate = 1, | |
| 695 | 695 | }; |
| 696 | 696 | |
| 697 | 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 | 666 | .formats = CS35L34_FORMATS, |
| 667 | 667 | }, |
| 668 | 668 | .ops = &cs35l34_ops, |
| 669 | − .symmetric_rates = 1, | |
| 669 | + .symmetric_rate = 1, | |
| 670 | 670 | }; |
| 671 | 671 | |
| 672 | 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 | 692 | .formats = CS35L35_FORMATS, |
| 693 | 693 | }, |
| 694 | 694 | .ops = &cs35l35_ops, |
| 695 | − .symmetric_rates = 1, | |
| 695 | + .symmetric_rate = 1, | |
| 696 | 696 | }, |
| 697 | 697 | { |
| 698 | 698 | .name = "cs35l35-pdm", |
| @@ -995,7 +995,7 @@ static struct snd_soc_dai_driver cs35l36_dai[] = { · 994 unmodified lines | ||
| 995 | 995 | .formats = CS35L36_TX_FORMATS, |
| 996 | 996 | }, |
| 997 | 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 | 585 | .formats = CS4234_FORMATS, |
| 586 | 586 | }, |
| 587 | 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 | 481 | .formats = CS4271_PCM_FORMATS, |
| 482 | 482 | }, |
| 483 | 483 | .ops = &cs4271_dai_ops, |
| 484 | − .symmetric_rates = 1, | |
| 484 | + .symmetric_rate = 1, | |
| 485 | 485 | }; |
| 486 | 486 | |
| 487 | 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 | 1250 | dev_err(&i2c_client->dev, |
| 1251 | 1251 | "CS42L56 Device ID (%X). Expected %X\n", |
| 1252 | 1252 | devid, CS42L56_DEVID); |
| 1253 | + ret = -EINVAL; | |
| 1253 | 1254 | goto err_enable; |
| 1254 | 1255 | } |
| 1255 | 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 | 1308 | ret = devm_snd_soc_register_component(&i2c_client->dev, |
| 1308 | 1309 | &soc_component_dev_cs42l56, &cs42l56_dai, 1); |
| 1309 | 1310 | if (ret < 0) |
| 1310 | − return ret; | |
| 1311 | + goto err_enable; | |
| 1311 | 1312 | |
| 1312 | 1313 | return 0; |
| 1313 | 1314 | |
| @@ -1181,7 +1181,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 1180 unmodified lines | ||
| 1181 | 1181 | .formats = CS42L73_FORMATS, |
| 1182 | 1182 | }, |
| 1183 | 1183 | .ops = &cs42l73_ops, |
| 1184 | − .symmetric_rates = 1, | |
| 1184 | + .symmetric_rate = 1, | |
| 1185 | 1185 | }, |
| 1186 | 1186 | { |
| 1187 | 1187 | .name = "cs42l73-asp", |
| @@ -1201,7 +1201,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 13 unmodified lines | ||
| 1201 | 1201 | .formats = CS42L73_FORMATS, |
| 1202 | 1202 | }, |
| 1203 | 1203 | .ops = &cs42l73_ops, |
| 1204 | − .symmetric_rates = 1, | |
| 1204 | + .symmetric_rate = 1, | |
| 1205 | 1205 | }, |
| 1206 | 1206 | { |
| 1207 | 1207 | .name = "cs42l73-vsp", |
| @@ -1221,7 +1221,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = { · 13 unmodified lines | ||
| 1221 | 1221 | .formats = CS42L73_FORMATS, |
| 1222 | 1222 | }, |
| 1223 | 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 | 1581 | .formats = CS43130_PCM_FORMATS, |
| 1582 | 1582 | }, |
| 1583 | 1583 | .ops = &cs43130_pcm_ops, |
| 1584 | − .symmetric_rates = 1, | |
| 1584 | + .symmetric_rate = 1, | |
| 1585 | 1585 | }, |
| 1586 | 1586 | { |
| 1587 | 1587 | .name = "cs43130-asp-dop", |
| @@ -1594,7 +1594,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { · 6 unmodified lines | ||
| 1594 | 1594 | .formats = CS43130_DOP_FORMATS, |
| 1595 | 1595 | }, |
| 1596 | 1596 | .ops = &cs43130_dop_ops, |
| 1597 | − .symmetric_rates = 1, | |
| 1597 | + .symmetric_rate = 1, | |
| 1598 | 1598 | }, |
| 1599 | 1599 | { |
| 1600 | 1600 | .name = "cs43130-xsp-dop", |
| @@ -1607,7 +1607,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = { · 6 unmodified lines | ||
| 1607 | 1607 | .formats = CS43130_DOP_FORMATS, |
| 1608 | 1608 | }, |
| 1609 | 1609 | .ops = &cs43130_dop_ops, |
| 1610 | − .symmetric_rates = 1, | |
| 1610 | + .symmetric_rate = 1, | |
| 1611 | 1611 | }, |
| 1612 | 1612 | { |
| 1613 | 1613 | .name = "cs43130-xsp-dsd", |
| @@ -189,7 +189,7 @@ static struct snd_soc_dai_driver cs4341_dai = { · 188 unmodified lines | ||
| 189 | 189 | SNDRV_PCM_FMTBIT_S24_LE, |
| 190 | 190 | }, |
| 191 | 191 | .ops = &cs4341_dai_ops, |
| 192 | − .symmetric_rates = 1, | |
| 192 | + .symmetric_rate = 1, | |
| 193 | 193 | }; |
| 194 | 194 | |
| 195 | 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 | 250 | .formats = CS4349_PCM_FORMATS, |
| 251 | 251 | }, |
| 252 | 252 | .ops = &cs4349_dai_ops, |
| 253 | − .symmetric_rates = 1, | |
| 253 | + .symmetric_rate = 1, | |
| 254 | 254 | }; |
| 255 | 255 | |
| 256 | 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 | 1160 | .formats = MADERA_FORMATS, |
| 1161 | 1161 | }, |
| 1162 | 1162 | .ops = &madera_dai_ops, |
| 1163 | − .symmetric_rates = 1, | |
| 1164 | − .symmetric_samplebits = 1, | |
| 1163 | + .symmetric_rate = 1, | |
| 1164 | + .symmetric_sample_bits = 1, | |
| 1165 | 1165 | }, |
| 1166 | 1166 | { |
| 1167 | 1167 | .name = "cs47l15-aif2", |
| @@ -1182,8 +1182,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { · 14 unmodified lines | ||
| 1182 | 1182 | .formats = MADERA_FORMATS, |
| 1183 | 1183 | }, |
| 1184 | 1184 | .ops = &madera_dai_ops, |
| 1185 | − .symmetric_rates = 1, | |
| 1186 | − .symmetric_samplebits = 1, | |
| 1185 | + .symmetric_rate = 1, | |
| 1186 | + .symmetric_sample_bits = 1, | |
| 1187 | 1187 | }, |
| 1188 | 1188 | { |
| 1189 | 1189 | .name = "cs47l15-aif3", |
| @@ -1204,8 +1204,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = { · 14 unmodified lines | ||
| 1204 | 1204 | .formats = MADERA_FORMATS, |
| 1205 | 1205 | }, |
| 1206 | 1206 | .ops = &madera_dai_ops, |
| 1207 | − .symmetric_rates = 1, | |
| 1208 | − .symmetric_samplebits = 1, | |
| 1207 | + .symmetric_rate = 1, | |
| 1208 | + .symmetric_sample_bits = 1, | |
| 1209 | 1209 | }, |
| 1210 | 1210 | { |
| 1211 | 1211 | .name = "cs47l15-cpu-trace", |
| @@ -977,8 +977,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 976 unmodified lines | ||
| 977 | 977 | .formats = CS47L24_FORMATS, |
| 978 | 978 | }, |
| 979 | 979 | .ops = &arizona_dai_ops, |
| 980 | − .symmetric_rates = 1, | |
| 981 | − .symmetric_samplebits = 1, | |
| 980 | + .symmetric_rate = 1, | |
| 981 | + .symmetric_sample_bits = 1, | |
| 982 | 982 | }, |
| 983 | 983 | { |
| 984 | 984 | .name = "cs47l24-aif2", |
| @@ -999,8 +999,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 14 unmodified lines | ||
| 999 | 999 | .formats = CS47L24_FORMATS, |
| 1000 | 1000 | }, |
| 1001 | 1001 | .ops = &arizona_dai_ops, |
| 1002 | − .symmetric_rates = 1, | |
| 1003 | − .symmetric_samplebits = 1, | |
| 1002 | + .symmetric_rate = 1, | |
| 1003 | + .symmetric_sample_bits = 1, | |
| 1004 | 1004 | }, |
| 1005 | 1005 | { |
| 1006 | 1006 | .name = "cs47l24-aif3", |
| @@ -1021,8 +1021,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 14 unmodified lines | ||
| 1021 | 1021 | .formats = CS47L24_FORMATS, |
| 1022 | 1022 | }, |
| 1023 | 1023 | .ops = &arizona_dai_ops, |
| 1024 | − .symmetric_rates = 1, | |
| 1025 | − .symmetric_samplebits = 1, | |
| 1024 | + .symmetric_rate = 1, | |
| 1025 | + .symmetric_sample_bits = 1, | |
| 1026 | 1026 | }, |
| 1027 | 1027 | { |
| 1028 | 1028 | .name = "cs47l24-cpu-voicectrl", |
| @@ -1368,8 +1368,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 1367 unmodified lines | ||
| 1368 | 1368 | .formats = MADERA_FORMATS, |
| 1369 | 1369 | }, |
| 1370 | 1370 | .ops = &madera_dai_ops, |
| 1371 | − .symmetric_rates = 1, | |
| 1372 | − .symmetric_samplebits = 1, | |
| 1371 | + .symmetric_rate = 1, | |
| 1372 | + .symmetric_sample_bits = 1, | |
| 1373 | 1373 | }, |
| 1374 | 1374 | { |
| 1375 | 1375 | .name = "cs47l35-aif2", |
| @@ -1390,8 +1390,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 14 unmodified lines | ||
| 1390 | 1390 | .formats = MADERA_FORMATS, |
| 1391 | 1391 | }, |
| 1392 | 1392 | .ops = &madera_dai_ops, |
| 1393 | − .symmetric_rates = 1, | |
| 1394 | − .symmetric_samplebits = 1, | |
| 1393 | + .symmetric_rate = 1, | |
| 1394 | + .symmetric_sample_bits = 1, | |
| 1395 | 1395 | }, |
| 1396 | 1396 | { |
| 1397 | 1397 | .name = "cs47l35-aif3", |
| @@ -1412,8 +1412,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = { · 14 unmodified lines | ||
| 1412 | 1412 | .formats = MADERA_FORMATS, |
| 1413 | 1413 | }, |
| 1414 | 1414 | .ops = &madera_dai_ops, |
| 1415 | − .symmetric_rates = 1, | |
| 1416 | − .symmetric_samplebits = 1, | |
| 1415 | + .symmetric_rate = 1, | |
| 1416 | + .symmetric_sample_bits = 1, | |
| 1417 | 1417 | }, |
| 1418 | 1418 | { |
| 1419 | 1419 | .name = "cs47l35-slim1", |
| @@ -2269,8 +2269,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 2268 unmodified lines | ||
| 2269 | 2269 | .formats = MADERA_FORMATS, |
| 2270 | 2270 | }, |
| 2271 | 2271 | .ops = &madera_dai_ops, |
| 2272 | − .symmetric_rates = 1, | |
| 2273 | − .symmetric_samplebits = 1, | |
| 2272 | + .symmetric_rate = 1, | |
| 2273 | + .symmetric_sample_bits = 1, | |
| 2274 | 2274 | }, |
| 2275 | 2275 | { |
| 2276 | 2276 | .name = "cs47l85-aif2", |
| @@ -2291,8 +2291,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | ||
| 2291 | 2291 | .formats = MADERA_FORMATS, |
| 2292 | 2292 | }, |
| 2293 | 2293 | .ops = &madera_dai_ops, |
| 2294 | − .symmetric_rates = 1, | |
| 2295 | − .symmetric_samplebits = 1, | |
| 2294 | + .symmetric_rate = 1, | |
| 2295 | + .symmetric_sample_bits = 1, | |
| 2296 | 2296 | }, |
| 2297 | 2297 | { |
| 2298 | 2298 | .name = "cs47l85-aif3", |
| @@ -2313,8 +2313,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | ||
| 2313 | 2313 | .formats = MADERA_FORMATS, |
| 2314 | 2314 | }, |
| 2315 | 2315 | .ops = &madera_dai_ops, |
| 2316 | − .symmetric_rates = 1, | |
| 2317 | − .symmetric_samplebits = 1, | |
| 2316 | + .symmetric_rate = 1, | |
| 2317 | + .symmetric_sample_bits = 1, | |
| 2318 | 2318 | }, |
| 2319 | 2319 | { |
| 2320 | 2320 | .name = "cs47l85-aif4", |
| @@ -2335,8 +2335,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = { · 14 unmodified lines | ||
| 2335 | 2335 | .formats = MADERA_FORMATS, |
| 2336 | 2336 | }, |
| 2337 | 2337 | .ops = &madera_dai_ops, |
| 2338 | − .symmetric_rates = 1, | |
| 2339 | − .symmetric_samplebits = 1, | |
| 2338 | + .symmetric_rate = 1, | |
| 2339 | + .symmetric_sample_bits = 1, | |
| 2340 | 2340 | }, |
| 2341 | 2341 | { |
| 2342 | 2342 | .name = "cs47l85-slim1", |
| @@ -2188,8 +2188,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 2187 unmodified lines | ||
| 2188 | 2188 | .formats = MADERA_FORMATS, |
| 2189 | 2189 | }, |
| 2190 | 2190 | .ops = &madera_dai_ops, |
| 2191 | − .symmetric_rates = 1, | |
| 2192 | − .symmetric_samplebits = 1, | |
| 2191 | + .symmetric_rate = 1, | |
| 2192 | + .symmetric_sample_bits = 1, | |
| 2193 | 2193 | }, |
| 2194 | 2194 | { |
| 2195 | 2195 | .name = "cs47l90-aif2", |
| @@ -2210,8 +2210,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | ||
| 2210 | 2210 | .formats = MADERA_FORMATS, |
| 2211 | 2211 | }, |
| 2212 | 2212 | .ops = &madera_dai_ops, |
| 2213 | − .symmetric_rates = 1, | |
| 2214 | − .symmetric_samplebits = 1, | |
| 2213 | + .symmetric_rate = 1, | |
| 2214 | + .symmetric_sample_bits = 1, | |
| 2215 | 2215 | }, |
| 2216 | 2216 | { |
| 2217 | 2217 | .name = "cs47l90-aif3", |
| @@ -2232,8 +2232,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | ||
| 2232 | 2232 | .formats = MADERA_FORMATS, |
| 2233 | 2233 | }, |
| 2234 | 2234 | .ops = &madera_dai_ops, |
| 2235 | − .symmetric_rates = 1, | |
| 2236 | − .symmetric_samplebits = 1, | |
| 2235 | + .symmetric_rate = 1, | |
| 2236 | + .symmetric_sample_bits = 1, | |
| 2237 | 2237 | }, |
| 2238 | 2238 | { |
| 2239 | 2239 | .name = "cs47l90-aif4", |
| @@ -2254,8 +2254,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = { · 14 unmodified lines | ||
| 2254 | 2254 | .formats = MADERA_FORMATS, |
| 2255 | 2255 | }, |
| 2256 | 2256 | .ops = &madera_dai_ops, |
| 2257 | − .symmetric_rates = 1, | |
| 2258 | − .symmetric_samplebits = 1, | |
| 2257 | + .symmetric_rate = 1, | |
| 2258 | + .symmetric_sample_bits = 1, | |
| 2259 | 2259 | }, |
| 2260 | 2260 | { |
| 2261 | 2261 | .name = "cs47l90-slim1", |
| @@ -1704,8 +1704,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 1703 unmodified lines | ||
| 1704 | 1704 | .formats = MADERA_FORMATS, |
| 1705 | 1705 | }, |
| 1706 | 1706 | .ops = &madera_dai_ops, |
| 1707 | − .symmetric_rates = 1, | |
| 1708 | − .symmetric_samplebits = 1, | |
| 1707 | + .symmetric_rate = 1, | |
| 1708 | + .symmetric_sample_bits = 1, | |
| 1709 | 1709 | }, |
| 1710 | 1710 | { |
| 1711 | 1711 | .name = "cs47l92-aif2", |
| @@ -1726,8 +1726,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 14 unmodified lines | ||
| 1726 | 1726 | .formats = MADERA_FORMATS, |
| 1727 | 1727 | }, |
| 1728 | 1728 | .ops = &madera_dai_ops, |
| 1729 | − .symmetric_rates = 1, | |
| 1730 | − .symmetric_samplebits = 1, | |
| 1729 | + .symmetric_rate = 1, | |
| 1730 | + .symmetric_sample_bits = 1, | |
| 1731 | 1731 | }, |
| 1732 | 1732 | { |
| 1733 | 1733 | .name = "cs47l92-aif3", |
| @@ -1748,8 +1748,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = { · 14 unmodified lines | ||
| 1748 | 1748 | .formats = MADERA_FORMATS, |
| 1749 | 1749 | }, |
| 1750 | 1750 | .ops = &madera_dai_ops, |
| 1751 | − .symmetric_rates = 1, | |
| 1752 | − .symmetric_samplebits = 1, | |
| 1751 | + .symmetric_rate = 1, | |
| 1752 | + .symmetric_sample_bits = 1, | |
| 1753 | 1753 | }, |
| 1754 | 1754 | { |
| 1755 | 1755 | .name = "cs47l92-slim1", |
| @@ -869,7 +869,7 @@ static struct snd_soc_dai_driver cs53l30_dai = { · 868 unmodified lines | ||
| 869 | 869 | .formats = CS53L30_FORMATS, |
| 870 | 870 | }, |
| 871 | 871 | .ops = &cs53l30_ops, |
| 872 | − .symmetric_rates = 1, | |
| 872 | + .symmetric_rate = 1, | |
| 873 | 873 | }; |
| 874 | 874 | |
| 875 | 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 | 1572 | .formats = CX2072X_FORMATS, |
| 1573 | 1573 | }, |
| 1574 | 1574 | .ops = &cx2072x_dai_ops, |
| 1575 | − .symmetric_rates = 1, | |
| 1575 | + .symmetric_rate = 1, | |
| 1576 | 1576 | }, |
| 1577 | 1577 | { /* plabayck only, return echo reference to Conexant DSP chip */ |
| 1578 | 1578 | .name = "cx2072x-dsp", |
| @@ -1059,7 +1059,7 @@ static struct snd_soc_dai_driver da7210_dai = { · 1058 unmodified lines | ||
| 1059 | 1059 | .formats = DA7210_FORMATS, |
| 1060 | 1060 | }, |
| 1061 | 1061 | .ops = &da7210_dai_ops, |
| 1062 | − .symmetric_rates = 1, | |
| 1062 | + .symmetric_rate = 1, | |
| 1063 | 1063 | }; |
| 1064 | 1064 | |
| 1065 | 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 | 1551 | .formats = DA7213_FORMATS, |
| 1552 | 1552 | }, |
| 1553 | 1553 | .ops = &da7213_dai_ops, |
| 1554 | − .symmetric_rates = 1, | |
| 1554 | + .symmetric_rate = 1, | |
| 1555 | 1555 | }; |
| 1556 | 1556 | |
| 1557 | 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 | 2194 | .formats = DA7218_FORMATS, |
| 2195 | 2195 | }, |
| 2196 | 2196 | .ops = &da7218_dai_ops, |
| 2197 | − .symmetric_rates = 1, | |
| 2197 | + .symmetric_rate = 1, | |
| 2198 | 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 | 2278 | * DT |
| 2279 | 2279 | */ |
| 2280 | 2280 | |
| 2281 | −#ifdef CONFIG_OF | |
| 2282 | 2281 | static const struct of_device_id da7218_of_match[] = { |
| 2283 | 2282 | { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID }, |
| 2284 | 2283 | { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID }, |
| 2285 | 2284 | { } |
| 2286 | 2285 | }; |
| 2287 | 2286 | MODULE_DEVICE_TABLE(of, da7218_of_match); |
| 2288 | −#endif | |
| 2289 | 2287 | |
| 2290 | 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 | 3309 | static struct i2c_driver da7218_i2c_driver = { |
| 3312 | 3310 | .driver = { |
| 3313 | 3311 | .name = "da7218", |
| 3314 | − .of_match_table = of_match_ptr(da7218_of_match), | |
| 3312 | + .of_match_table = da7218_of_match, | |
| 3315 | 3313 | }, |
| 3316 | 3314 | .probe = da7218_i2c_probe, |
| 3317 | 3315 | .id_table = da7218_i2c_id, |
| @@ -1692,9 +1692,9 @@ static struct snd_soc_dai_driver da7219_dai = { · 1691 unmodified lines | ||
| 1692 | 1692 | .formats = DA7219_FORMATS, |
| 1693 | 1693 | }, |
| 1694 | 1694 | .ops = &da7219_dai_ops, |
| 1695 | − .symmetric_rates = 1, | |
| 1695 | + .symmetric_rate = 1, | |
| 1696 | 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 | 1347 | .formats = DA9055_FORMATS, |
| 1348 | 1348 | }, |
| 1349 | 1349 | .ops = &da9055_dai_ops, |
| 1350 | − .symmetric_rates = 1, | |
| 1350 | + .symmetric_rate = 1, | |
| 1351 | 1351 | }; |
| 1352 | 1352 | |
| 1353 | 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 | 543 | .formats = ES8316_FORMATS, |
| 544 | 544 | }, |
| 545 | 545 | .ops = &es8316_ops, |
| 546 | − .symmetric_rates = 1, | |
| 546 | + .symmetric_rate = 1, | |
| 547 | 547 | }; |
| 548 | 548 | |
| 549 | 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 | 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 | 687 | disable_irq(es8316->irq); |
| 685 | 688 | |
| 686 | 689 | mutex_lock(&es8316->lock); |
| @@ -715,7 +715,7 @@ static struct snd_soc_dai_driver es8328_dai = { · 714 unmodified lines | ||
| 715 | 715 | .formats = ES8328_FORMATS, |
| 716 | 716 | }, |
| 717 | 717 | .ops = &es8328_dai_ops, |
| 718 | − .symmetric_rates = 1, | |
| 718 | + .symmetric_rate = 1, | |
| 719 | 719 | }; |
| 720 | 720 | |
| 721 | 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 | 810 | es8328 = snd_soc_component_get_drvdata(component); |
| 811 | 811 | |
| 812 | − if (es8328->clk) | |
| 813 | − clk_disable_unprepare(es8328->clk); | |
| 812 | + clk_disable_unprepare(es8328->clk); | |
| 814 | 813 | |
| 815 | 814 | regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), |
| 816 | 815 | es8328->supplies); |
| @@ -489,6 +489,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, · 488 unmodified lines | ||
| 489 | 489 | hp.sample_rate = params_rate(params); |
| 490 | 490 | hp.channels = params_channels(params); |
| 491 | 491 | |
| 492 | + cf->bit_fmt = params_format(params); | |
| 492 | 493 | return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, |
| 493 | 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 | 618 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ |
| 618 | 619 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ |
| 619 | 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 | 624 | static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 623 | 625 | struct snd_soc_dai *dai) |
| @@ -325,7 +325,7 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = { · 324 unmodified lines | ||
| 325 | 325 | .formats = RK3036_CODEC_FMTS, |
| 326 | 326 | }, |
| 327 | 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 | 214 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, |
| 215 | 215 | }, |
| 216 | 216 | .ops = &jz4740_codec_dai_ops, |
| 217 | − .symmetric_rates = 1, | |
| 217 | + .symmetric_rate = 1, | |
| 218 | 218 | }; |
| 219 | 219 | |
| 220 | 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 | 1343 | .formats = LM49453_FORMATS, |
| 1344 | 1344 | }, |
| 1345 | 1345 | .ops = &lm49453_headset_dai_ops, |
| 1346 | − .symmetric_rates = 1, | |
| 1346 | + .symmetric_rate = 1, | |
| 1347 | 1347 | }, |
| 1348 | 1348 | { |
| 1349 | 1349 | .name = "LM49453 Speaker", |
| @@ -166,8 +166,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 165 unmodified lines | ||
| 166 | 166 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 167 | 167 | }, |
| 168 | 168 | .ops = &lochnagar_sc_line_ops, |
| 169 | − .symmetric_rates = true, | |
| 170 | − .symmetric_samplebits = true, | |
| 169 | + .symmetric_rate = true, | |
| 170 | + .symmetric_sample_bits = true, | |
| 171 | 171 | }, |
| 172 | 172 | { |
| 173 | 173 | .name = "lochnagar-usb1", |
| @@ -186,8 +186,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 12 unmodified lines | ||
| 186 | 186 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 187 | 187 | }, |
| 188 | 188 | .ops = &lochnagar_sc_usb_ops, |
| 189 | − .symmetric_rates = true, | |
| 190 | − .symmetric_samplebits = true, | |
| 189 | + .symmetric_rate = true, | |
| 190 | + .symmetric_sample_bits = true, | |
| 191 | 191 | }, |
| 192 | 192 | { |
| 193 | 193 | .name = "lochnagar-usb2", |
| @@ -206,8 +206,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = { · 12 unmodified lines | ||
| 206 | 206 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
| 207 | 207 | }, |
| 208 | 208 | .ops = &lochnagar_sc_usb_ops, |
| 209 | − .symmetric_rates = true, | |
| 210 | − .symmetric_samplebits = true, | |
| 209 | + .symmetric_rate = 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 | 40 | #define CDC_WSA_TOP_I2S_CLK (0x00A4) |
| 41 | 41 | #define CDC_WSA_TOP_I2S_RESET (0x00A8) |
| 42 | 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) | |
| 44 | −#define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) | |
| 43 | +#define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(2, 0) | |
| 44 | +#define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(5, 3) | |
| 45 | 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 | 48 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108) |
| 47 | 49 | #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C) |
| 48 | 50 | #define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110) |
| @@ -229,8 +231,6 @@ · 180 unmodified lines | ||
| 229 | 231 | #define NUM_INTERPOLATORS 2 |
| 230 | 232 | #define WSA_NUM_CLKS_MAX 5 |
| 231 | 233 | #define WSA_MACRO_MCLK_FREQ 19200000 |
| 232 | −#define WSA_MACRO_MUX_INP_SHFT 0x3 | |
| 233 | −#define WSA_MACRO_MUX_INP_MASK1 0x07 | |
| 234 | 234 | #define WSA_MACRO_MUX_INP_MASK2 0x38 |
| 235 | 235 | #define WSA_MACRO_MUX_CFG_OFFSET 0x8 |
| 236 | 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 | 843 | u32 j, port; |
| 844 | 844 | u16 int_mux_cfg0, int_mux_cfg1; |
| 845 | 845 | u16 int_fs_reg; |
| 846 | − u8 int_mux_cfg0_val, int_mux_cfg1_val; | |
| 847 | 846 | u8 inp0_sel, inp1_sel, inp2_sel; |
| 848 | 847 | struct snd_soc_component *component = dai->component; |
| 849 | 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 | 865 | for (j = 0; j < NUM_INTERPOLATORS; j++) { |
| 867 | 866 | int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; |
| 868 | − int_mux_cfg0_val = snd_soc_component_read(component, | |
| 869 | − int_mux_cfg0); | |
| 870 | − int_mux_cfg1_val = snd_soc_component_read(component, | |
| 871 | − int_mux_cfg1); | |
| 872 | − inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1; | |
| 873 | − inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) & | |
| 874 | − WSA_MACRO_MUX_INP_MASK1; | |
| 875 | − inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) & | |
| 876 | − WSA_MACRO_MUX_INP_MASK1; | |
| 867 | + inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, | |
| 868 | + CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); | |
| 869 | + inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, | |
| 870 | + CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); | |
| 871 | + inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, | |
| 872 | + CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); | |
| 873 | + | |
| 877 | 874 | if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || |
| 878 | 875 | (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || |
| 879 | 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 | 910 | int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; |
| 914 | 911 | for (j = 0; j < NUM_INTERPOLATORS; j++) { |
| 915 | − int_mux_cfg1_val = snd_soc_component_read(component, | |
| 916 | − int_mux_cfg1) & | |
| 917 | − WSA_MACRO_MUX_INP_MASK1; | |
| 912 | + int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, | |
| 913 | + CDC_WSA_RX_INTX_2_SEL_MASK); | |
| 914 | + | |
| 918 | 915 | if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { |
| 919 | 916 | int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + |
| 920 | 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 | 1407 | int interp_idx) |
| 1411 | 1408 | { |
| 1412 | 1409 | u16 int_mux_cfg0, int_mux_cfg1; |
| 1413 | − u8 int_mux_cfg0_val, int_mux_cfg1_val; | |
| 1414 | 1410 | u8 int_n_inp0, int_n_inp1, int_n_inp2; |
| 1415 | 1411 | |
| 1416 | 1412 | int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; |
| 1417 | 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 | 1417 | if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || |
| 1423 | 1418 | int_n_inp0 == INTn_1_INP_SEL_DEC1) |
| 1424 | 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 | 1423 | if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || |
| 1428 | 1424 | int_n_inp1 == INTn_1_INP_SEL_DEC1) |
| 1429 | 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 | 1429 | if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || |
| 1433 | 1430 | int_n_inp2 == INTn_1_INP_SEL_DEC1) |
| 1434 | 1431 | return true; |
| @@ -262,6 +262,8 @@ static __maybe_unused int max98373_suspend(struct device *dev) · 261 unmodified lines | ||
| 262 | 262 | return 0; |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | +#define MAX98373_PROBE_TIMEOUT 5000 | |
| 266 | + | |
| 265 | 267 | static __maybe_unused int max98373_resume(struct device *dev) |
| 266 | 268 | { |
| 267 | 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 | 277 | goto regmap_sync; |
| 276 | 278 | |
| 277 | 279 | time = wait_for_completion_timeout(&slave->initialization_complete, |
| 278 | − msecs_to_jiffies(2000)); | |
| 280 | + msecs_to_jiffies(MAX98373_PROBE_TIMEOUT)); | |
| 279 | 281 | if (!time) { |
| 280 | 282 | dev_err(dev, "Initialization not complete, timed out\n"); |
| 281 | 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 | 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 | 489 | SNDRV_PCM_FMTBIT_S32_LE, |
| 490 | 490 | }, |
| 491 | 491 | .ops = &max9860_dai_ops, |
| 492 | − .symmetric_rates = 1, | |
| 492 | + .symmetric_rate = 1, | |
| 493 | 493 | }; |
| 494 | 494 | |
| 495 | 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 | 520 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 521 | 521 | }, |
| 522 | 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 | 712 | .formats = MC13783_FORMATS, |
| 713 | 713 | }, |
| 714 | 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 | 513 | .rates = ML26124_RATES, |
| 514 | 514 | .formats = ML26124_FORMATS,}, |
| 515 | 515 | .ops = &ml26124_dai_ops, |
| 516 | − .symmetric_rates = 1, | |
| 516 | + .symmetric_rate = 1, | |
| 517 | 517 | }; |
| 518 | 518 | |
| 519 | 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 | 2754 | ret = of_property_read_u32(np, "mediatek,dmic-mode", |
| 2755 | 2755 | &priv->dmic_one_wire_mode); |
| 2756 | 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 | 2759 | __func__); |
| 2759 | 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 | 2763 | ret = of_property_read_u32(np, "mediatek,mic-type-0", |
| 2763 | 2764 | &priv->mux_select[MUX_MIC_TYPE_0]); |
| 2764 | 2765 | if (ret) { |
| 2765 | − dev_warn(priv->dev, "%s() failed to read mic-type-0\n", | |
| 2766 | − __func__); | |
| 2766 | + dev_info(priv->dev, | |
| 2767 | + "%s() failed to read mic-type-0, use default (%d)\n", | |
| 2768 | + __func__, MIC_TYPE_MUX_IDLE); | |
| 2767 | 2769 | priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE; |
| 2768 | 2770 | } |
| 2769 | 2771 | |
| 2770 | 2772 | ret = of_property_read_u32(np, "mediatek,mic-type-1", |
| 2771 | 2773 | &priv->mux_select[MUX_MIC_TYPE_1]); |
| 2772 | 2774 | if (ret) { |
| 2773 | − dev_warn(priv->dev, "%s() failed to read mic-type-1\n", | |
| 2774 | − __func__); | |
| 2775 | + dev_info(priv->dev, | |
| 2776 | + "%s() failed to read mic-type-1, use default (%d)\n", | |
| 2777 | + __func__, MIC_TYPE_MUX_IDLE); | |
| 2775 | 2778 | priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE; |
| 2776 | 2779 | } |
| 2777 | 2780 | |
| 2778 | 2781 | ret = of_property_read_u32(np, "mediatek,mic-type-2", |
| 2779 | 2782 | &priv->mux_select[MUX_MIC_TYPE_2]); |
| 2780 | 2783 | if (ret) { |
| 2781 | − dev_warn(priv->dev, "%s() failed to read mic-type-2\n", | |
| 2782 | − __func__); | |
| 2784 | + dev_info(priv->dev, | |
| 2785 | + "%s() failed to read mic-type-2, use default (%d)\n", | |
| 2786 | + __func__, MIC_TYPE_MUX_IDLE); | |
| 2783 | 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 | 404 | .formats = STUB_FORMATS, |
| 405 | 405 | }, |
| 406 | 406 | /* dai properties */ |
| 407 | − .symmetric_rates = 1, | |
| 407 | + .symmetric_rate = 1, | |
| 408 | 408 | .symmetric_channels = 1, |
| 409 | − .symmetric_samplebits = 1, | |
| 409 | + .symmetric_sample_bits = 1, | |
| 410 | 410 | /* dai operations */ |
| 411 | 411 | .ops = &mt6660_component_aif_ops, |
| 412 | 412 | }; |
| @@ -837,7 +837,7 @@ static struct snd_soc_dai_driver nau8810_dai = { · 836 unmodified lines | ||
| 837 | 837 | .formats = NAU8810_FORMATS, |
| 838 | 838 | }, |
| 839 | 839 | .ops = &nau8810_ops, |
| 840 | − .symmetric_rates = 1, | |
| 840 | + .symmetric_rate = 1, | |
| 841 | 841 | }; |
| 842 | 842 | |
| 843 | 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 | 991 | .formats = NAU8822_FORMATS, |
| 992 | 992 | }, |
| 993 | 993 | .ops = &nau8822_dai_ops, |
| 994 | − .symmetric_rates = 1, | |
| 994 | + .symmetric_rate = 1, | |
| 995 | 995 | }; |
| 996 | 996 | |
| 997 | 997 | static int nau8822_suspend(struct snd_soc_component *component) |
| @@ -24,10 +24,10 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <sound/initval.h> |
| 25 | 25 | #include <sound/pcm.h> |
| 26 | 26 | #include <sound/pcm_params.h> |
| 27 | +#include <sound/rt1015.h> | |
| 27 | 28 | #include <sound/soc-dapm.h> |
| 28 | 29 | #include <sound/soc.h> |
| 29 | 30 | #include <sound/tlv.h> |
| 30 | −#include <sound/rt1015.h> | |
| 31 | 31 | |
| 32 | 32 | #include "rl6231.h" |
| 33 | 33 | #include "rt1015.h" |
| @@ -444,10 +444,9 @@ static int rt1015_boost_mode_put(struct snd_kcontrol *kcontrol, · 410 unmodified lines | ||
| 444 | 444 | snd_soc_kcontrol_component(kcontrol); |
| 445 | 445 | struct rt1015_priv *rt1015 = |
| 446 | 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 | − | |
| 450 | − switch (rt1015->boost_mode) { | |
| 449 | + switch (boost_mode) { | |
| 451 | 450 | case BYPASS: |
| 452 | 451 | snd_soc_component_update_bits(component, |
| 453 | 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 | 470 | break; |
| 472 | 471 | default: |
| 473 | 472 | dev_err(component->dev, "Unknown boost control.\n"); |
| 473 | + return -EINVAL; | |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | + rt1015->boost_mode = boost_mode; | |
| 477 | + | |
| 476 | 478 | return 0; |
| 477 | 479 | } |
| 478 | 480 | |
| @@ -497,40 +499,20 @@ static void rt1015_calibrate(struct rt1015_priv *rt1015) · 18 unmodified lines | ||
| 497 | 499 | snd_soc_dapm_mutex_lock(&component->dapm); |
| 498 | 500 | regcache_cache_bypass(regmap, true); |
| 499 | 501 | |
| 500 | − regmap_write(regmap, RT1015_PWR9, 0xAA60); | |
| 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); | |
| 502 | + regmap_write(regmap, RT1015_CLK_DET, 0x0000); | |
| 520 | 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 | 510 | regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2028); |
| 522 | 511 | regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140); |
| 523 | − regmap_write(regmap, RT1015_PWR5, 0x0175); | |
| 524 | − regmap_write(regmap, RT1015_CLSD_INTERNAL1, 0x1721); | |
| 525 | − regmap_write(regmap, RT1015_CLASSD_SEQ, 0x570E); | |
| 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); | |
| 512 | + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000D); | |
| 513 | + msleep(300); | |
| 514 | + regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x0008); | |
| 532 | 515 | regmap_write(regmap, RT1015_SYS_RST1, 0x05F5); |
| 533 | − regmap_write(regmap, RT1015_SYS_RST2, 0x0b9a); | |
| 534 | 516 | |
| 535 | 517 | regcache_cache_bypass(regmap, false); |
| 536 | 518 | regcache_mark_dirty(regmap); |
| @@ -546,17 +528,19 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, · 9 unmodified lines | ||
| 546 | 528 | struct rt1015_priv *rt1015 = |
| 547 | 529 | snd_soc_component_get_drvdata(component); |
| 548 | 530 | |
| 549 | − if (!rt1015->dac_is_used) { | |
| 550 | − rt1015->bypass_boost = ucontrol->value.integer.value[0]; | |
| 551 | − if (rt1015->bypass_boost == RT1015_Bypass_Boost && | |
| 531 | + if (rt1015->dac_is_used) { | |
| 532 | + dev_err(component->dev, "DAC is being used!\n"); | |
| 533 | + return -EBUSY; | |
| 534 | + } | |
| 535 | + | |
| 536 | + rt1015->bypass_boost = ucontrol->value.integer.value[0]; | |
| 537 | + if (rt1015->bypass_boost == RT1015_Bypass_Boost && | |
| 552 | 538 | !rt1015->cali_done) { |
| 553 | − rt1015_calibrate(rt1015); | |
| 554 | − rt1015->cali_done = 1; | |
| 539 | + rt1015_calibrate(rt1015); | |
| 540 | + rt1015->cali_done = 1; | |
| 555 | 541 | |
| 556 | − regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); | |
| 557 | − } | |
| 558 | − } else | |
| 559 | − dev_err(component->dev, "DAC is being used!\n"); | |
| 542 | + regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010); | |
| 543 | + } | |
| 560 | 544 | |
| 561 | 545 | return 0; |
| 562 | 546 | } |
| @@ -566,15 +550,14 @@ static void rt1015_flush_work(struct work_struct *work) · 3 unmodified lines | ||
| 566 | 550 | struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, |
| 567 | 551 | flush_work.work); |
| 568 | 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 | 556 | usleep_range(1000, 1500); |
| 573 | 557 | dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i); |
| 574 | 558 | regmap_read(rt1015->regmap, RT1015_CLK_DET, &val); |
| 575 | 559 | if (val & 0x800) |
| 576 | 560 | break; |
| 577 | − i++; | |
| 578 | 561 | } |
| 579 | 562 | |
| 580 | 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 | 705 | struct snd_soc_component *component = dai->component; |
| 723 | 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 | 708 | unsigned int val_len = 0; |
| 726 | 709 | |
| 727 | − rt1015->lrck = params_rate(params); | |
| 728 | − pre_div = rl6231_get_clk_info(rt1015->sysclk, rt1015->lrck); | |
| 710 | + lrck = params_rate(params); | |
| 711 | + pre_div = rl6231_get_clk_info(rt1015->sysclk, lrck); | |
| 729 | 712 | if (pre_div < 0) { |
| 730 | 713 | dev_err(component->dev, "Unsupported clock rate\n"); |
| 731 | 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 | 724 | bclk_ms = frame_size > 32; |
| 742 | − rt1015->bclk = rt1015->lrck * (32 << bclk_ms); | |
| 743 | 725 | |
| 744 | 726 | dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", |
| 745 | 727 | bclk_ms, pre_div, dai->id); |
| 746 | 728 | |
| 747 | 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 | 732 | switch (params_width(params)) { |
| 751 | 733 | case 16: |
| @@ -882,14 +864,6 @@ static int rt1015_set_component_pll(struct snd_soc_component *component, · 130 unmodified lines | ||
| 882 | 864 | freq_out == rt1015->pll_out) |
| 883 | 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 | 867 | switch (source) { |
| 894 | 868 | case RT1015_PLL_S_MCLK: |
| 895 | 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 | 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 | 906 | static int rt1015_set_tdm_slot(struct snd_soc_dai *dai, |
| 950 | 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 | 1009 | snd_soc_component_get_drvdata(component); |
| 1053 | 1010 | |
| 1054 | 1011 | rt1015->component = component; |
| 1055 | − rt1015->bclk_ratio = 0; | |
| 1056 | − rt1015->cali_done = 0; | |
| 1057 | − | |
| 1058 | 1012 | INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work); |
| 1059 | 1013 | |
| 1060 | 1014 | return 0; |
| @@ -1075,7 +1029,6 @@ static void rt1015_remove(struct snd_soc_component *component) · 14 unmodified lines | ||
| 1075 | 1029 | static struct snd_soc_dai_ops rt1015_aif_dai_ops = { |
| 1076 | 1030 | .hw_params = rt1015_hw_params, |
| 1077 | 1031 | .set_fmt = rt1015_set_dai_fmt, |
| 1078 | − .set_bclk_ratio = rt1015_set_bclk_ratio, | |
| 1079 | 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 | 1065 | regcache_cache_only(rt1015->regmap, false); |
| 1113 | 1066 | regcache_sync(rt1015->regmap); |
| 1067 | + | |
| 1068 | + if (rt1015->cali_done) | |
| 1069 | + rt1015_calibrate(rt1015); | |
| 1070 | + | |
| 1114 | 1071 | return 0; |
| 1115 | 1072 | } |
| 1116 | 1073 | #else |
| @@ -1183,9 +1140,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, · 66 unmodified lines | ||
| 1183 | 1140 | int ret; |
| 1184 | 1141 | unsigned int val; |
| 1185 | 1142 | |
| 1186 | − rt1015 = devm_kzalloc(&i2c->dev, sizeof(struct rt1015_priv), | |
| 1187 | − GFP_KERNEL); | |
| 1188 | − if (rt1015 == NULL) | |
| 1143 | + rt1015 = devm_kzalloc(&i2c->dev, sizeof(*rt1015), GFP_KERNEL); | |
| 1144 | + if (!rt1015) | |
| 1189 | 1145 | return -ENOMEM; |
| 1190 | 1146 | |
| 1191 | 1147 | i2c_set_clientdata(i2c, rt1015); |
| @@ -427,16 +427,11 @@ struct rt1015_priv { · 426 unmodified lines | ||
| 427 | 427 | struct regmap *regmap; |
| 428 | 428 | int sysclk; |
| 429 | 429 | int sysclk_src; |
| 430 | − int lrck; | |
| 431 | − int bclk; | |
| 432 | − int bclk_ratio; | |
| 433 | − int id; | |
| 434 | 430 | int pll_src; |
| 435 | 431 | int pll_in; |
| 436 | 432 | int pll_out; |
| 437 | 433 | int boost_mode; |
| 438 | 434 | int bypass_boost; |
| 439 | − int amp_ver; | |
| 440 | 435 | int dac_is_used; |
| 441 | 436 | int cali_done; |
| 442 | 437 | int hw_config; |
| @@ -701,7 +701,7 @@ static int __maybe_unused rt1308_dev_suspend(struct device *dev) · 700 unmodified lines | ||
| 701 | 701 | return 0; |
| 702 | 702 | } |
| 703 | 703 | |
| 704 | −#define RT1308_PROBE_TIMEOUT 2000 | |
| 704 | +#define RT1308_PROBE_TIMEOUT 5000 | |
| 705 | 705 | |
| 706 | 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 | 1056 | .formats = RT274_FORMATS, |
| 1057 | 1057 | }, |
| 1058 | 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 | 1017 | .formats = RT286_FORMATS, |
| 1018 | 1018 | }, |
| 1019 | 1019 | .ops = &rt286_aif_dai_ops, |
| 1020 | − .symmetric_rates = 1, | |
| 1020 | + .symmetric_rate = 1, | |
| 1021 | 1021 | }, |
| 1022 | 1022 | { |
| 1023 | 1023 | .name = "rt286-aif2", |
| @@ -1037,7 +1037,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { · 13 unmodified lines | ||
| 1037 | 1037 | .formats = RT286_FORMATS, |
| 1038 | 1038 | }, |
| 1039 | 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 | 1084 | .formats = RT298_FORMATS, |
| 1085 | 1085 | }, |
| 1086 | 1086 | .ops = &rt298_aif_dai_ops, |
| 1087 | − .symmetric_rates = 1, | |
| 1087 | + .symmetric_rate = 1, | |
| 1088 | 1088 | }, |
| 1089 | 1089 | { |
| 1090 | 1090 | .name = "rt298-aif2", |
| @@ -1104,7 +1104,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { · 13 unmodified lines | ||
| 1104 | 1104 | .formats = RT298_FORMATS, |
| 1105 | 1105 | }, |
| 1106 | 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 | 34 | #define QUIRK_INV_JD1_1(q) ((q) & 1) |
| 35 | 35 | #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1) |
| 36 | 36 | #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1) |
| 37 | +#define QUIRK_INV_HP_POL(q) (((q) >> 3) & 1) | |
| 37 | 38 | #define QUIRK_JD_MODE(q) (((q) >> 4) & 7) |
| 38 | 39 | #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3) |
| 39 | 40 | #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3) |
| @@ -42,6 +43,8 @@ static unsigned int quirk = -1; · 2 unmodified lines | ||
| 42 | 43 | module_param(quirk, uint, 0444); |
| 43 | 44 | MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override"); |
| 44 | 45 | |
| 46 | +static const struct acpi_gpio_mapping *cht_rt5645_gpios; | |
| 47 | + | |
| 45 | 48 | #define RT5645_DEVICE_ID 0x6308 |
| 46 | 49 | #define RT5650_DEVICE_ID 0x6419 |
| 47 | 50 | |
| @@ -435,7 +438,6 @@ struct rt5645_priv { · 387 unmodified lines | ||
| 435 | 438 | |
| 436 | 439 | int jack_type; |
| 437 | 440 | bool en_button_func; |
| 438 | − bool hp_on; | |
| 439 | 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 | 1648 | static int hp_amp_power_count; |
| 1647 | 1649 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); |
| 1650 | + int i, val; | |
| 1648 | 1651 | |
| 1649 | 1652 | if (on) { |
| 1650 | 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 | 1658 | snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d); |
| 1656 | 1659 | regmap_write(rt5645->regmap, RT5645_PR_BASE + |
| 1657 | 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 | 1668 | snd_soc_component_update_bits(component, RT5645_DEPOP_M1, |
| 1660 | 1669 | RT5645_HP_CO_MASK, RT5645_HP_CO_EN); |
| 1661 | 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 | 1674 | RT5645_MAMP_INT_REG2, 0xfc00); |
| 1666 | 1675 | snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140); |
| 1667 | 1676 | msleep(90); |
| 1668 | − rt5645->hp_on = true; | |
| 1669 | 1677 | } else { |
| 1670 | 1678 | /* depop parameters */ |
| 1671 | 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 | 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 | 1896 | static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, |
| 1910 | 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 | 2229 | SND_SOC_DAPM_OUTPUT("PDM1R"), |
| 2243 | 2230 | SND_SOC_DAPM_OUTPUT("SPOL"), |
| 2244 | 2231 | SND_SOC_DAPM_OUTPUT("SPOR"), |
| 2245 | − SND_SOC_DAPM_POST("DAPM_POST", rt5650_hp_event), | |
| 2246 | 2232 | }; |
| 2247 | 2233 | |
| 2248 | 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 | 3247 | case 0: /* Not using rt5645 JD */ |
| 3262 | 3248 | if (rt5645->gpiod_hp_det) { |
| 3263 | 3249 | gpio_state = gpiod_get_value(rt5645->gpiod_hp_det); |
| 3250 | + if (rt5645->pdata.inv_hp_pol) | |
| 3251 | + gpio_state ^= 1; | |
| 3264 | 3252 | dev_dbg(rt5645->component->dev, "gpio_state = %d\n", |
| 3265 | 3253 | gpio_state); |
| 3266 | 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 | 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 | 3661 | static const struct dmi_system_id dmi_platform_data[] = { |
| 3655 | 3662 | { |
| 3656 | 3663 | .ident = "Chrome Buddy", |
| @@ -3780,6 +3787,22 @@ static const struct dmi_system_id dmi_platform_data[] = { · 123 unmodified lines | ||
| 3780 | 3787 | }, |
| 3781 | 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 | 3866 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); |
| 3844 | 3867 | rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk); |
| 3845 | 3868 | rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk); |
| 3869 | + rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk); | |
| 3846 | 3870 | rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk); |
| 3847 | 3871 | rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk); |
| 3848 | 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 | 3879 | rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", |
| 3852 | 3880 | GPIOD_IN); |
| 3853 | 3881 | |
| @@ -2741,7 +2741,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { · 2740 unmodified lines | ||
| 2741 | 2741 | .formats = RT5670_FORMATS, |
| 2742 | 2742 | }, |
| 2743 | 2743 | .ops = &rt5670_aif_dai_ops, |
| 2744 | − .symmetric_rates = 1, | |
| 2744 | + .symmetric_rate = 1, | |
| 2745 | 2745 | }, |
| 2746 | 2746 | { |
| 2747 | 2747 | .name = "rt5670-aif2", |
| @@ -2761,7 +2761,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { · 13 unmodified lines | ||
| 2761 | 2761 | .formats = RT5670_FORMATS, |
| 2762 | 2762 | }, |
| 2763 | 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 | 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 | 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 | 375 | static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) |
| 376 | 376 | { |
| 377 | 377 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
| 378 | − int ret = 0; | |
| 378 | + int ret = 0, loop = 10; | |
| 379 | 379 | unsigned int val; |
| 380 | 380 | |
| 381 | 381 | if (rt5682->hw_init) |
| 382 | 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 | 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 | 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 | 416 | if (rt5682->first_hw_init) { |
| 410 | 417 | regcache_cache_only(rt5682->regmap, false); |
| 411 | 418 | regcache_cache_bypass(rt5682->regmap, true); |
| @@ -703,7 +710,7 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) · 291 unmodified lines | ||
| 703 | 710 | struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); |
| 704 | 711 | |
| 705 | 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 | 715 | return 0; |
| 709 | 716 | } |
| @@ -721,6 +728,8 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev) · 11 unmodified lines | ||
| 721 | 728 | if (!rt5682->hw_init) |
| 722 | 729 | return 0; |
| 723 | 730 | |
| 731 | + cancel_delayed_work_sync(&rt5682->jack_detect_work); | |
| 732 | + | |
| 724 | 733 | regcache_cache_only(rt5682->regmap, true); |
| 725 | 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 | 953 | case 0x1: |
| 954 | 954 | case 0x2: |
| 955 | 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 | 958 | rt5682_enable_push_button_irq(component, true); |
| 957 | 959 | break; |
| 958 | 960 | default: |
| @@ -982,6 +984,8 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) · 23 unmodified lines | ||
| 982 | 984 | snd_soc_component_update_bits(component, RT5682_MICBIAS_2, |
| 983 | 985 | RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK, |
| 984 | 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 | 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 | 1015 | if (!rt5682->is_sdw) { |
| 1012 | 1016 | switch (rt5682->pdata.jd_src) { |
| 1013 | 1017 | case RT5682_JD1: |
| 1018 | + snd_soc_component_update_bits(component, | |
| 1019 | + RT5682_CBJ_CTRL_5, 0x0700, 0x0600); | |
| 1014 | 1020 | snd_soc_component_update_bits(component, |
| 1015 | 1021 | RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, |
| 1016 | 1022 | RT5682_EXT_JD_SRC_MANUAL); |
| 1017 | 1023 | snd_soc_component_write(component, RT5682_CBJ_CTRL_1, |
| 1018 | − 0xd042); | |
| 1024 | + 0xd142); | |
| 1019 | 1025 | snd_soc_component_update_bits(component, |
| 1020 | 1026 | RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, |
| 1021 | 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 | 1855 | {"CLKDET SYS", NULL, "CLKDET"}, |
| 1850 | 1856 | |
| 1851 | − {"IN1P", NULL, "LDO2"}, | |
| 1852 | − | |
| 1853 | 1857 | {"BST1 CBJ", NULL, "IN1P"}, |
| 1854 | 1858 | |
| 1855 | 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 | 2911 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 2908 | 2912 | |
| 2913 | + if (rt5682->is_sdw) | |
| 2914 | + return 0; | |
| 2915 | + | |
| 2909 | 2916 | regcache_cache_only(rt5682->regmap, true); |
| 2910 | 2917 | regcache_mark_dirty(rt5682->regmap); |
| 2911 | 2918 | return 0; |
| @@ -2915,6 +2922,9 @@ static int rt5682_resume(struct snd_soc_component *component) · 3 unmodified lines | ||
| 2915 | 2922 | { |
| 2916 | 2923 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); |
| 2917 | 2924 | |
| 2925 | + if (rt5682->is_sdw) | |
| 2926 | + return 0; | |
| 2927 | + | |
| 2918 | 2928 | regcache_cache_only(rt5682->regmap, false); |
| 2919 | 2929 | regcache_sync(rt5682->regmap); |
| 2920 | 2930 | |
| @@ -1356,7 +1356,7 @@ · 1355 unmodified lines | ||
| 1356 | 1356 | #define RT5682_SAR_SOUR_TYPE (0x0) |
| 1357 | 1357 | |
| 1358 | 1358 | /* soundwire timeout */ |
| 1359 | −#define RT5682_PROBE_TIMEOUT 2000 | |
| 1359 | +#define RT5682_PROBE_TIMEOUT 5000 | |
| 1360 | 1360 | |
| 1361 | 1361 | |
| 1362 | 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 | 462 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); |
| 463 | 463 | |
| 464 | 464 | if (rt700 && rt700->hw_init) { |
| 465 | − cancel_delayed_work(&rt700->jack_detect_work); | |
| 466 | − cancel_delayed_work(&rt700->jack_btn_check_work); | |
| 465 | + cancel_delayed_work_sync(&rt700->jack_detect_work); | |
| 466 | + cancel_delayed_work_sync(&rt700->jack_btn_check_work); | |
| 467 | 467 | } |
| 468 | 468 | |
| 469 | 469 | return 0; |
| @@ -490,7 +490,7 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev) · 20 unmodified lines | ||
| 490 | 490 | return 0; |
| 491 | 491 | } |
| 492 | 492 | |
| 493 | −#define RT700_PROBE_TIMEOUT 2000 | |
| 493 | +#define RT700_PROBE_TIMEOUT 5000 | |
| 494 | 494 | |
| 495 | 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 | 463 | struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); |
| 464 | 464 | |
| 465 | 465 | if (rt711 && rt711->hw_init) { |
| 466 | − cancel_delayed_work(&rt711->jack_detect_work); | |
| 467 | − cancel_delayed_work(&rt711->jack_btn_check_work); | |
| 466 | + cancel_delayed_work_sync(&rt711->jack_detect_work); | |
| 467 | + cancel_delayed_work_sync(&rt711->jack_btn_check_work); | |
| 468 | 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 | 493 | return 0; |
| 494 | 494 | } |
| 495 | 495 | |
| 496 | −#define RT711_PROBE_TIMEOUT 2000 | |
| 496 | +#define RT711_PROBE_TIMEOUT 5000 | |
| 497 | 497 | |
| 498 | 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 | 533 | return 0; |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | −#define RT715_PROBE_TIMEOUT 2000 | |
| 536 | +#define RT715_PROBE_TIMEOUT 5000 | |
| 537 | 537 | |
| 538 | 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 | 1187 | .formats = SGTL5000_FORMATS, |
| 1188 | 1188 | }, |
| 1189 | 1189 | .ops = &sgtl5000_ops, |
| 1190 | − .symmetric_rates = 1, | |
| 1190 | + .symmetric_rate = 1, | |
| 1191 | 1191 | }; |
| 1192 | 1192 | |
| 1193 | 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 | 526 | .rates = SSM2602_RATES, |
| 527 | 527 | .formats = SSM2602_FORMATS,}, |
| 528 | 528 | .ops = &ssm2602_dai_ops, |
| 529 | − .symmetric_rates = 1, | |
| 530 | − .symmetric_samplebits = 1, | |
| 529 | + .symmetric_rate = 1, | |
| 530 | + .symmetric_sample_bits = 1, | |
| 531 | 531 | }; |
| 532 | 532 | |
| 533 | 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 | 490 | .formats = TAS2764_FORMATS, |
| 491 | 491 | }, |
| 492 | 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 | 499 | .formats = TAS2770_FORMATS, |
| 500 | 500 | }, |
| 501 | 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 | 1069 | .formats = ADCX140_FORMATS, |
| 1070 | 1070 | }, |
| 1071 | 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 | 1395 | .formats = AIC31XX_FORMATS, |
| 1396 | 1396 | }, |
| 1397 | 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 | 1417 | .formats = AIC31XX_FORMATS, |
| 1418 | 1418 | }, |
| 1419 | 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 | 916 | .rates = AIC32X4_RATES, |
| 917 | 917 | .formats = AIC32X4_FORMATS,}, |
| 918 | 918 | .ops = &aic32x4_ops, |
| 919 | − .symmetric_rates = 1, | |
| 919 | + .symmetric_rate = 1, | |
| 920 | 920 | }; |
| 921 | 921 | |
| 922 | 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 | 1503 | .rates = AIC3X_RATES, |
| 1504 | 1504 | .formats = AIC3X_FORMATS,}, |
| 1505 | 1505 | .ops = &aic3x_dai_ops, |
| 1506 | − .symmetric_rates = 1, | |
| 1506 | + .symmetric_rate = 1, | |
| 1507 | 1507 | }; |
| 1508 | 1508 | |
| 1509 | 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 | 1397 | .rates = TSCS42XX_RATES, |
| 1398 | 1398 | .formats = TSCS42XX_FORMATS,}, |
| 1399 | 1399 | .ops = &tscs42xx_dai_ops, |
| 1400 | − .symmetric_rates = 1, | |
| 1400 | + .symmetric_rate = 1, | |
| 1401 | 1401 | .symmetric_channels = 1, |
| 1402 | − .symmetric_samplebits = 1, | |
| 1402 | + .symmetric_sample_bits = 1, | |
| 1403 | 1403 | }; |
| 1404 | 1404 | |
| 1405 | 1405 | static const struct reg_sequence tscs42xx_patch[] = { |
| @@ -3346,9 +3346,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 3345 unmodified lines | ||
| 3346 | 3346 | .rates = TSCS454_RATES, |
| 3347 | 3347 | .formats = TSCS454_FORMATS,}, |
| 3348 | 3348 | .ops = &tscs454_dai1_ops, |
| 3349 | − .symmetric_rates = 1, | |
| 3349 | + .symmetric_rate = 1, | |
| 3350 | 3350 | .symmetric_channels = 1, |
| 3351 | − .symmetric_samplebits = 1, | |
| 3351 | + .symmetric_sample_bits = 1, | |
| 3352 | 3352 | }, |
| 3353 | 3353 | { |
| 3354 | 3354 | .name = "tscs454-dai2", |
| @@ -3366,9 +3366,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 11 unmodified lines | ||
| 3366 | 3366 | .rates = TSCS454_RATES, |
| 3367 | 3367 | .formats = TSCS454_FORMATS,}, |
| 3368 | 3368 | .ops = &tscs454_dai23_ops, |
| 3369 | − .symmetric_rates = 1, | |
| 3369 | + .symmetric_rate = 1, | |
| 3370 | 3370 | .symmetric_channels = 1, |
| 3371 | − .symmetric_samplebits = 1, | |
| 3371 | + .symmetric_sample_bits = 1, | |
| 3372 | 3372 | }, |
| 3373 | 3373 | { |
| 3374 | 3374 | .name = "tscs454-dai3", |
| @@ -3386,9 +3386,9 @@ static struct snd_soc_dai_driver tscs454_dais[] = { · 11 unmodified lines | ||
| 3386 | 3386 | .rates = TSCS454_RATES, |
| 3387 | 3387 | .formats = TSCS454_FORMATS,}, |
| 3388 | 3388 | .ops = &tscs454_dai23_ops, |
| 3389 | − .symmetric_rates = 1, | |
| 3389 | + .symmetric_rate = 1, | |
| 3390 | 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 | 1780 | .formats = WM5102_FORMATS, |
| 1781 | 1781 | }, |
| 1782 | 1782 | .ops = &arizona_dai_ops, |
| 1783 | − .symmetric_rates = 1, | |
| 1784 | − .symmetric_samplebits = 1, | |
| 1783 | + .symmetric_rate = 1, | |
| 1784 | + .symmetric_sample_bits = 1, | |
| 1785 | 1785 | }, |
| 1786 | 1786 | { |
| 1787 | 1787 | .name = "wm5102-aif2", |
| @@ -1802,8 +1802,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 14 unmodified lines | ||
| 1802 | 1802 | .formats = WM5102_FORMATS, |
| 1803 | 1803 | }, |
| 1804 | 1804 | .ops = &arizona_dai_ops, |
| 1805 | − .symmetric_rates = 1, | |
| 1806 | − .symmetric_samplebits = 1, | |
| 1805 | + .symmetric_rate = 1, | |
| 1806 | + .symmetric_sample_bits = 1, | |
| 1807 | 1807 | }, |
| 1808 | 1808 | { |
| 1809 | 1809 | .name = "wm5102-aif3", |
| @@ -1824,8 +1824,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 14 unmodified lines | ||
| 1824 | 1824 | .formats = WM5102_FORMATS, |
| 1825 | 1825 | }, |
| 1826 | 1826 | .ops = &arizona_dai_ops, |
| 1827 | − .symmetric_rates = 1, | |
| 1828 | − .symmetric_samplebits = 1, | |
| 1827 | + .symmetric_rate = 1, | |
| 1828 | + .symmetric_sample_bits = 1, | |
| 1829 | 1829 | }, |
| 1830 | 1830 | { |
| 1831 | 1831 | .name = "wm5102-slim1", |
| @@ -2089,8 +2089,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 2088 unmodified lines | ||
| 2089 | 2089 | .formats = WM5110_FORMATS, |
| 2090 | 2090 | }, |
| 2091 | 2091 | .ops = &arizona_dai_ops, |
| 2092 | − .symmetric_rates = 1, | |
| 2093 | − .symmetric_samplebits = 1, | |
| 2092 | + .symmetric_rate = 1, | |
| 2093 | + .symmetric_sample_bits = 1, | |
| 2094 | 2094 | }, |
| 2095 | 2095 | { |
| 2096 | 2096 | .name = "wm5110-aif2", |
| @@ -2111,8 +2111,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 14 unmodified lines | ||
| 2111 | 2111 | .formats = WM5110_FORMATS, |
| 2112 | 2112 | }, |
| 2113 | 2113 | .ops = &arizona_dai_ops, |
| 2114 | − .symmetric_rates = 1, | |
| 2115 | − .symmetric_samplebits = 1, | |
| 2114 | + .symmetric_rate = 1, | |
| 2115 | + .symmetric_sample_bits = 1, | |
| 2116 | 2116 | }, |
| 2117 | 2117 | { |
| 2118 | 2118 | .name = "wm5110-aif3", |
| @@ -2133,8 +2133,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 14 unmodified lines | ||
| 2133 | 2133 | .formats = WM5110_FORMATS, |
| 2134 | 2134 | }, |
| 2135 | 2135 | .ops = &arizona_dai_ops, |
| 2136 | − .symmetric_rates = 1, | |
| 2137 | − .symmetric_samplebits = 1, | |
| 2136 | + .symmetric_rate = 1, | |
| 2137 | + .symmetric_sample_bits = 1, | |
| 2138 | 2138 | }, |
| 2139 | 2139 | { |
| 2140 | 2140 | .name = "wm5110-slim1", |
| @@ -569,7 +569,7 @@ static struct snd_soc_dai_driver wm8510_dai = { · 568 unmodified lines | ||
| 569 | 569 | .rates = WM8510_RATES, |
| 570 | 570 | .formats = WM8510_FORMATS,}, |
| 571 | 571 | .ops = &wm8510_dai_ops, |
| 572 | − .symmetric_rates = 1, | |
| 572 | + .symmetric_rate = 1, | |
| 573 | 573 | }; |
| 574 | 574 | |
| 575 | 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 | 567 | .rates = WM8731_RATES, |
| 568 | 568 | .formats = WM8731_FORMATS,}, |
| 569 | 569 | .ops = &wm8731_dai_ops, |
| 570 | − .symmetric_rates = 1, | |
| 570 | + .symmetric_rate = 1, | |
| 571 | 571 | }; |
| 572 | 572 | |
| 573 | 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 | 562 | .formats = WM8770_FORMATS |
| 563 | 563 | }, |
| 564 | 564 | .ops = &wm8770_dai_ops, |
| 565 | − .symmetric_rates = 1 | |
| 565 | + .symmetric_rate = 1 | |
| 566 | 566 | }; |
| 567 | 567 | |
| 568 | 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 | 536 | .formats = WM8804_FORMATS, |
| 537 | 537 | }, |
| 538 | 538 | .ops = &wm8804_dai_ops, |
| 539 | − .symmetric_rates = 1 | |
| 539 | + .symmetric_rate = 1 | |
| 540 | 540 | }; |
| 541 | 541 | |
| 542 | 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 | 1760 | .formats = WM8903_FORMATS, |
| 1761 | 1761 | }, |
| 1762 | 1762 | .ops = &wm8903_dai_ops, |
| 1763 | − .symmetric_rates = 1, | |
| 1763 | + .symmetric_rate = 1, | |
| 1764 | 1764 | }; |
| 1765 | 1765 | |
| 1766 | 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 | 1983 | .formats = WM8904_FORMATS, |
| 1984 | 1984 | }, |
| 1985 | 1985 | .ops = &wm8904_dai_ops, |
| 1986 | − .symmetric_rates = 1, | |
| 1986 | + .symmetric_rate = 1, | |
| 1987 | 1987 | }; |
| 1988 | 1988 | |
| 1989 | 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 | 688 | .formats = WM8940_FORMATS, |
| 689 | 689 | }, |
| 690 | 690 | .ops = &wm8940_dai_ops, |
| 691 | − .symmetric_rates = 1, | |
| 691 | + .symmetric_rate = 1, | |
| 692 | 692 | }; |
| 693 | 693 | |
| 694 | 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 | 1338 | .rates = WM8960_RATES, |
| 1339 | 1339 | .formats = WM8960_FORMATS,}, |
| 1340 | 1340 | .ops = &wm8960_dai_ops, |
| 1341 | − .symmetric_rates = 1, | |
| 1341 | + .symmetric_rate = 1, | |
| 1342 | 1342 | }; |
| 1343 | 1343 | |
| 1344 | 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 | 2973 | .formats = WM8962_FORMATS, |
| 2974 | 2974 | }, |
| 2975 | 2975 | .ops = &wm8962_dai_ops, |
| 2976 | − .symmetric_rates = 1, | |
| 2976 | + .symmetric_rate = 1, | |
| 2977 | 2977 | }; |
| 2978 | 2978 | |
| 2979 | 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 | 643 | .rates = WM8974_RATES, |
| 644 | 644 | .formats = WM8974_FORMATS,}, |
| 645 | 645 | .ops = &wm8974_ops, |
| 646 | − .symmetric_rates = 1, | |
| 646 | + .symmetric_rate = 1, | |
| 647 | 647 | }; |
| 648 | 648 | |
| 649 | 649 | static const struct regmap_config wm8974_regmap = { |
| @@ -918,7 +918,7 @@ static struct snd_soc_dai_driver wm8978_dai = { · 917 unmodified lines | ||
| 918 | 918 | .formats = WM8978_FORMATS, |
| 919 | 919 | }, |
| 920 | 920 | .ops = &wm8978_dai_ops, |
| 921 | − .symmetric_rates = 1, | |
| 921 | + .symmetric_rate = 1, | |
| 922 | 922 | }; |
| 923 | 923 | |
| 924 | 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 | 971 | .formats = WM8983_FORMATS, |
| 972 | 972 | }, |
| 973 | 973 | .ops = &wm8983_dai_ops, |
| 974 | − .symmetric_rates = 1 | |
| 974 | + .symmetric_rate = 1 | |
| 975 | 975 | }; |
| 976 | 976 | |
| 977 | 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 | 1100 | .formats = WM8985_FORMATS, |
| 1101 | 1101 | }, |
| 1102 | 1102 | .ops = &wm8985_dai_ops, |
| 1103 | − .symmetric_rates = 1 | |
| 1103 | + .symmetric_rate = 1 | |
| 1104 | 1104 | }; |
| 1105 | 1105 | |
| 1106 | 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 | 787 | .formats = WM8988_FORMATS, |
| 788 | 788 | }, |
| 789 | 789 | .ops = &wm8988_ops, |
| 790 | − .symmetric_rates = 1, | |
| 790 | + .symmetric_rate = 1, | |
| 791 | 791 | }; |
| 792 | 792 | |
| 793 | 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 | 1476 | .sig_bits = 24, |
| 1477 | 1477 | }, |
| 1478 | 1478 | .ops = &wm8993_ops, |
| 1479 | − .symmetric_rates = 1, | |
| 1479 | + .symmetric_rate = 1, | |
| 1480 | 1480 | }; |
| 1481 | 1481 | |
| 1482 | 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 | 4352 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
| 4353 | 4353 | wm8994->lrclk_shared[0] = 1; |
| 4354 | − wm8994_dai[0].symmetric_rates = 1; | |
| 4354 | + wm8994_dai[0].symmetric_rate = 1; | |
| 4355 | 4355 | } else { |
| 4356 | 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 | 4364 | if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { |
| 4365 | 4365 | wm8994->lrclk_shared[1] = 1; |
| 4366 | − wm8994_dai[1].symmetric_rates = 1; | |
| 4366 | + wm8994_dai[1].symmetric_rate = 1; | |
| 4367 | 4367 | } else { |
| 4368 | 4368 | wm8994->lrclk_shared[1] = 0; |
| 4369 | 4369 | } |
| @@ -969,8 +969,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { · 968 unmodified lines | ||
| 969 | 969 | .formats = WM8997_FORMATS, |
| 970 | 970 | }, |
| 971 | 971 | .ops = &arizona_dai_ops, |
| 972 | − .symmetric_rates = 1, | |
| 973 | − .symmetric_samplebits = 1, | |
| 972 | + .symmetric_rate = 1, | |
| 973 | + .symmetric_sample_bits = 1, | |
| 974 | 974 | }, |
| 975 | 975 | { |
| 976 | 976 | .name = "wm8997-aif2", |
| @@ -991,8 +991,8 @@ static struct snd_soc_dai_driver wm8997_dai[] = { · 14 unmodified lines | ||
| 991 | 991 | .formats = WM8997_FORMATS, |
| 992 | 992 | }, |
| 993 | 993 | .ops = &arizona_dai_ops, |
| 994 | − .symmetric_rates = 1, | |
| 995 | − .symmetric_samplebits = 1, | |
| 994 | + .symmetric_rate = 1, | |
| 995 | + .symmetric_sample_bits = 1, | |
| 996 | 996 | }, |
| 997 | 997 | { |
| 998 | 998 | .name = "wm8997-slim1", |
| @@ -1161,8 +1161,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 1160 unmodified lines | ||
| 1161 | 1161 | .formats = WM8998_FORMATS, |
| 1162 | 1162 | }, |
| 1163 | 1163 | .ops = &arizona_dai_ops, |
| 1164 | − .symmetric_rates = 1, | |
| 1165 | − .symmetric_samplebits = 1, | |
| 1164 | + .symmetric_rate = 1, | |
| 1165 | + .symmetric_sample_bits = 1, | |
| 1166 | 1166 | }, |
| 1167 | 1167 | { |
| 1168 | 1168 | .name = "wm8998-aif2", |
| @@ -1183,8 +1183,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 14 unmodified lines | ||
| 1183 | 1183 | .formats = WM8998_FORMATS, |
| 1184 | 1184 | }, |
| 1185 | 1185 | .ops = &arizona_dai_ops, |
| 1186 | − .symmetric_rates = 1, | |
| 1187 | − .symmetric_samplebits = 1, | |
| 1186 | + .symmetric_rate = 1, | |
| 1187 | + .symmetric_sample_bits = 1, | |
| 1188 | 1188 | }, |
| 1189 | 1189 | { |
| 1190 | 1190 | .name = "wm8998-aif3", |
| @@ -1205,8 +1205,8 @@ static struct snd_soc_dai_driver wm8998_dai[] = { · 14 unmodified lines | ||
| 1205 | 1205 | .formats = WM8998_FORMATS, |
| 1206 | 1206 | }, |
| 1207 | 1207 | .ops = &arizona_dai_ops, |
| 1208 | − .symmetric_rates = 1, | |
| 1209 | − .symmetric_samplebits = 1, | |
| 1208 | + .symmetric_rate = 1, | |
| 1209 | + .symmetric_sample_bits = 1, | |
| 1210 | 1210 | }, |
| 1211 | 1211 | { |
| 1212 | 1212 | .name = "wm8998-slim1", |
| @@ -1134,7 +1134,7 @@ static struct snd_soc_dai_driver wm9713_dai[] = { · 1133 unmodified lines | ||
| 1134 | 1134 | .rates = WM9713_PCM_RATES, |
| 1135 | 1135 | .formats = WM9713_PCM_FORMATS,}, |
| 1136 | 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 | 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 | 598 | struct wm_coeff_ctl { |
| 606 | 599 | const char *name; |
| 607 | 600 | const char *fw_name; |
| @@ -609,7 +602,6 @@ struct wm_coeff_ctl { · 1 unmodified line | ||
| 609 | 602 | const char *subname; |
| 610 | 603 | unsigned int subname_len; |
| 611 | 604 | struct wm_adsp_alg_region alg_region; |
| 612 | − struct wm_coeff_ctl_ops ops; | |
| 613 | 605 | struct wm_adsp *dsp; |
| 614 | 606 | unsigned int enabled:1; |
| 615 | 607 | struct list_head list; |
| @@ -619,7 +611,7 @@ struct wm_coeff_ctl { · 3 unmodified lines | ||
| 619 | 611 | unsigned int set:1; |
| 620 | 612 | struct soc_bytes_ext bytes_ext; |
| 621 | 613 | unsigned int flags; |
| 622 | − unsigned int type; | |
| 614 | + snd_ctl_elem_type_t type; | |
| 623 | 615 | }; |
| 624 | 616 | |
| 625 | 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 | 972 | unsigned int event_id) |
| 981 | 973 | { |
| 982 | 974 | struct wm_adsp *dsp = ctl->dsp; |
| 983 | − u32 val = cpu_to_be32(event_id); | |
| 975 | + __be32 val = cpu_to_be32(event_id); | |
| 984 | 976 | unsigned int reg; |
| 985 | 977 | int i, ret; |
| 986 | 978 | |
| @@ -1420,7 +1412,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp, · 433 unmodified lines | ||
| 1420 | 1412 | const struct wm_adsp_alg_region *alg_region, |
| 1421 | 1413 | unsigned int offset, unsigned int len, |
| 1422 | 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 | 1417 | struct wm_coeff_ctl *ctl; |
| 1426 | 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 | 1490 | ctl->enabled = 1; |
| 1499 | 1491 | ctl->set = 0; |
| 1500 | − ctl->ops.xget = wm_coeff_get; | |
| 1501 | − ctl->ops.xput = wm_coeff_put; | |
| 1502 | 1492 | ctl->dsp = dsp; |
| 1503 | 1493 | |
| 1504 | 1494 | ctl->flags = flags; |
| @@ -1554,7 +1544,7 @@ struct wm_coeff_parsed_coeff { · 49 unmodified lines | ||
| 1554 | 1544 | int mem_type; |
| 1555 | 1545 | const u8 *name; |
| 1556 | 1546 | int name_len; |
| 1557 | − int ctl_type; | |
| 1547 | + snd_ctl_elem_type_t ctl_type; | |
| 1558 | 1548 | int flags; |
| 1559 | 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 | 1639 | blk->mem_type = le16_to_cpu(raw->hdr.type); |
| 1650 | 1640 | blk->name = raw->name; |
| 1651 | 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 | 1643 | blk->flags = le16_to_cpu(raw->flags); |
| 1654 | 1644 | blk->len = le32_to_cpu(raw->len); |
| 1655 | 1645 | break; |
| @@ -1662,7 +1652,9 @@ static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, · 6 unmodified lines | ||
| 1662 | 1652 | &blk->name); |
| 1663 | 1653 | wm_coeff_parse_string(sizeof(u8), &tmp, NULL); |
| 1664 | 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 | 1658 | blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); |
| 1667 | 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 | 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, | |
| 3671 | − unsigned int mem_addr, | |
| 3672 | − unsigned int num_words, u32 *data) | |
| 3662 | +static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, | |
| 3663 | + unsigned int mem_addr, | |
| 3664 | + unsigned int num_words, __be32 *data) | |
| 3673 | 3665 | { |
| 3674 | 3666 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); |
| 3675 | − unsigned int i, reg; | |
| 3667 | + unsigned int reg; | |
| 3676 | 3668 | int ret; |
| 3677 | 3669 | |
| 3678 | 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 | 3677 | if (ret < 0) |
| 3686 | 3678 | return ret; |
| 3687 | 3679 | |
| 3688 | − for (i = 0; i < num_words; ++i) | |
| 3689 | − data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; | |
| 3690 | − | |
| 3691 | 3680 | return 0; |
| 3692 | 3681 | } |
| 3693 | 3682 | |
| 3694 | 3683 | static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, |
| 3695 | 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 | 3698 | static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, |
| 3701 | 3699 | unsigned int mem_addr, u32 data) |
| 3702 | 3700 | { |
| 3703 | 3701 | struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); |
| 3702 | + __be32 val = cpu_to_be32(data & 0x00ffffffu); | |
| 3704 | 3703 | unsigned int reg; |
| 3705 | 3704 | |
| 3706 | 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 | 3708 | reg = dsp->ops->region_to_reg(mem, mem_addr); |
| 3710 | 3709 | |
| 3711 | − data = cpu_to_be32(data & 0x00ffffffu); | |
| 3712 | − | |
| 3713 | − return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); | |
| 3710 | + return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); | |
| 3714 | 3711 | } |
| 3715 | 3712 | |
| 3716 | 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 | 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 | 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 | 3738 | for (i = 0; i < nwords; i++) { |
| 3738 | − for (j = 0; j < data_word_size; j++) | |
| 3739 | − *pack_out++ = *pack_in++; | |
| 3740 | − | |
| 3741 | − pack_in += sizeof(*buf) - data_word_size; | |
| 3739 | + u32 word = be32_to_cpu(*pack_in++); | |
| 3740 | + *pack_out++ = (u8)word; | |
| 3741 | + *pack_out++ = (u8)(word >> 8); | |
| 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 | 3865 | struct wm_adsp_host_buf_coeff_v1 coeff_v1; |
| 3865 | 3866 | struct wm_adsp_compr_buf *buf; |
| 3866 | − unsigned int val, reg; | |
| 3867 | + unsigned int reg, version; | |
| 3868 | + __be32 bufp; | |
| 3867 | 3869 | int ret, i; |
| 3868 | 3870 | |
| 3869 | 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 | 3873 | return ret; |
| 3872 | 3874 | |
| 3873 | 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 | 3877 | if (ret < 0) |
| 3876 | 3878 | return ret; |
| 3877 | 3879 | |
| 3878 | − if (val) | |
| 3880 | + if (bufp) | |
| 3879 | 3881 | break; |
| 3880 | 3882 | |
| 3881 | 3883 | usleep_range(1000, 2000); |
| 3882 | 3884 | } |
| 3883 | 3885 | |
| 3884 | − if (!val) { | |
| 3886 | + if (!bufp) { | |
| 3885 | 3887 | adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); |
| 3886 | 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 | 3893 | return -ENOMEM; |
| 3892 | 3894 | |
| 3893 | 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 | 3898 | ret = wm_adsp_buffer_populate(buf); |
| 3897 | 3899 | if (ret < 0) |
| @@ -3911,31 +3913,25 @@ static int wm_adsp_buffer_parse_coeff(struct wm_coeff_ctl *ctl) · 13 unmodified lines | ||
| 3911 | 3913 | if (ret < 0) |
| 3912 | 3914 | return ret; |
| 3913 | 3915 | |
| 3914 | − coeff_v1.versions = be32_to_cpu(coeff_v1.versions); | |
| 3915 | − val = coeff_v1.versions & HOST_BUF_COEFF_COMPAT_VER_MASK; | |
| 3916 | − val >>= HOST_BUF_COEFF_COMPAT_VER_SHIFT; | |
| 3916 | + version = be32_to_cpu(coeff_v1.versions) & HOST_BUF_COEFF_COMPAT_VER_MASK; | |
| 3917 | + version >>= 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 | 3920 | adsp_err(ctl->dsp, |
| 3920 | 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 | 3923 | return -EINVAL; |
| 3923 | 3924 | } |
| 3924 | 3925 | |
| 3925 | − for (i = 0; i < ARRAY_SIZE(coeff_v1.name); i++) | |
| 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); | |
| 3926 | + wm_adsp_remove_padding((u32 *)&coeff_v1.name, ARRAY_SIZE(coeff_v1.name)); | |
| 3931 | 3927 | |
| 3932 | 3928 | buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, |
| 3933 | 3929 | (char *)&coeff_v1.name); |
| 3934 | 3930 | |
| 3935 | 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 | 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 | 4262 | return 0; |
| 4267 | 4263 | |
| 4268 | 4264 | /* Read data from DSP */ |
| 4269 | − ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, | |
| 4270 | − nwords, compr->raw_buf); | |
| 4265 | + ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, | |
| 4266 | + nwords, (__be32 *)compr->raw_buf); | |
| 4271 | 4267 | if (ret < 0) |
| 4272 | 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 | 4272 | /* update read index to account for words read */ |
| 4277 | 4273 | buf->read_index += nwords; |
| @@ -24,9 +24,9 @@ · 23 unmodified lines | ||
| 24 | 24 | #define WMFW_CTL_FLAG_READABLE 0x0001 |
| 25 | 25 | |
| 26 | 26 | /* Non-ALSA coefficient types start at 0x1000 */ |
| 27 | −#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ | |
| 28 | −#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ | |
| 29 | −#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */ | |
| 27 | +#define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */ | |
| 28 | +#define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */ | |
| 29 | +#define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */ | |
| 30 | 30 | |
| 31 | 31 | struct wmfw_header { |
| 32 | 32 | char magic[4]; |
| @@ -640,6 +640,7 @@ static struct regmap_config wsa881x_regmap_config = { · 639 unmodified lines | ||
| 640 | 640 | .val_bits = 8, |
| 641 | 641 | .cache_type = REGCACHE_RBTREE, |
| 642 | 642 | .reg_defaults = wsa881x_defaults, |
| 643 | + .max_register = WSA881X_SPKR_STATUS3, | |
| 643 | 644 | .num_reg_defaults = ARRAY_SIZE(wsa881x_defaults), |
| 644 | 645 | .volatile_reg = wsa881x_volatile_register, |
| 645 | 646 | .readable_reg = wsa881x_readable_register, |
| @@ -360,8 +360,8 @@ static struct snd_soc_dai_driver zl38_dai = { · 359 unmodified lines | ||
| 360 | 360 | .formats = ZL38_FORMATS, |
| 361 | 361 | }, |
| 362 | 362 | .ops = &zl38_dai_ops, |
| 363 | − .symmetric_rates = 1, | |
| 364 | − .symmetric_samplebits = 1, | |
| 363 | + .symmetric_rate = 1, | |
| 364 | + .symmetric_sample_bits = 1, | |
| 365 | 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 | 108 | config SND_SOC_FSL_AUD2HTX |
| 109 | 109 | tristate "AUDIO TO HDMI TX module support" |
| 110 | 110 | depends on ARCH_MXC || COMPILE_TEST |
| 111 | + select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n | |
| 111 | 112 | help |
| 112 | 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 | 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 | 1086 | asrc->use_edma = asrc_priv->soc->use_edma; |
| 1092 | 1087 | asrc->get_dma_channel = fsl_asrc_get_dma_channel; |
| 1093 | 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 | 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 | 1534 | .startup = fsl_easrc_startup, |
| 1535 | 1535 | .trigger = fsl_easrc_trigger, |
| 1536 | 1536 | .hw_params = fsl_easrc_hw_params, |
| @@ -23,11 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | /** |
| 25 | 25 | * struct fsl_esai_soc_data - soc specific data |
| 26 | − * @imx: for imx platform | |
| 27 | 26 | * @reset_at_xrun: flags for enable reset operaton |
| 28 | 27 | */ |
| 29 | 28 | struct fsl_esai_soc_data { |
| 30 | − bool imx; | |
| 31 | 29 | bool reset_at_xrun; |
| 32 | 30 | }; |
| 33 | 31 | |
| @@ -86,17 +84,14 @@ struct fsl_esai { · 52 unmodified lines | ||
| 86 | 84 | }; |
| 87 | 85 | |
| 88 | 86 | static struct fsl_esai_soc_data fsl_esai_vf610 = { |
| 89 | − .imx = false, | |
| 90 | 87 | .reset_at_xrun = true, |
| 91 | 88 | }; |
| 92 | 89 | |
| 93 | 90 | static struct fsl_esai_soc_data fsl_esai_imx35 = { |
| 94 | − .imx = true, | |
| 95 | 91 | .reset_at_xrun = true, |
| 96 | 92 | }; |
| 97 | 93 | |
| 98 | 94 | static struct fsl_esai_soc_data fsl_esai_imx6ull = { |
| 99 | − .imx = true, | |
| 100 | 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 | 962 | snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np); |
| 968 | 963 | |
| 969 | 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 | 966 | /* Get the addresses and IRQ */ |
| 976 | 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 | 1034 | /* Implement full symmetry for synchronous mode */ |
| 1044 | 1035 | if (esai_priv->synchronous) { |
| 1045 | − fsl_esai_dai.symmetric_rates = 1; | |
| 1036 | + fsl_esai_dai.symmetric_rate = 1; | |
| 1046 | 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 | 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 | 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 | 385 | .startup = fsl_micfil_startup, |
| 386 | 386 | .trigger = fsl_micfil_trigger, |
| 387 | 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 | 637 | static int fsl_micfil_probe(struct platform_device *pdev) |
| 638 | 638 | { |
| 639 | 639 | struct device_node *np = pdev->dev.of_node; |
| 640 | − const struct of_device_id *of_id; | |
| 641 | 640 | struct fsl_micfil *micfil; |
| 642 | 641 | struct resource *res; |
| 643 | 642 | void __iomem *regs; |
| @@ -651,11 +650,7 @@ static int fsl_micfil_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 651 | 650 | micfil->pdev = pdev; |
| 652 | 651 | strncpy(micfil->name, np->name, sizeof(micfil->name) - 1); |
| 653 | 652 | |
| 654 | − of_id = of_match_device(fsl_micfil_dt_ids, &pdev->dev); | |
| 655 | − if (!of_id || !of_id->data) | |
| 656 | − return -EINVAL; | |
| 657 | − | |
| 658 | − micfil->soc = of_id->data; | |
| 653 | + micfil->soc = of_device_get_match_data(&pdev->dev); | |
| 659 | 654 | |
| 660 | 655 | /* ipg_clk is used to control the registers |
| 661 | 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 | 1079 | /* Sync Tx with Rx as default by following old DT binding */ |
| 1080 | 1080 | sai->synchronous[RX] = true; |
| 1081 | 1081 | sai->synchronous[TX] = false; |
| 1082 | − sai->cpu_dai_drv.symmetric_rates = 1; | |
| 1082 | + sai->cpu_dai_drv.symmetric_rate = 1; | |
| 1083 | 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 | 1086 | if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && |
| 1087 | 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 | 1098 | /* Discard all settings for asynchronous mode */ |
| 1099 | 1099 | sai->synchronous[RX] = false; |
| 1100 | 1100 | sai->synchronous[TX] = false; |
| 1101 | − sai->cpu_dai_drv.symmetric_rates = 0; | |
| 1101 | + sai->cpu_dai_drv.symmetric_rate = 0; | |
| 1102 | 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 | 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 | 1256 | for (i = 0; i < STC_TXCLK_SRC_MAX; i++) { |
| 1257 | 1257 | sprintf(tmp, "rxtx%d", i); |
| 1258 | − clk = devm_clk_get(&pdev->dev, tmp); | |
| 1258 | + clk = devm_clk_get(dev, tmp); | |
| 1259 | 1259 | if (IS_ERR(clk)) { |
| 1260 | 1260 | dev_err(dev, "no rxtx%d clock in devicetree\n", i); |
| 1261 | 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 | 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 | 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 | 1283 | spdif_priv->txclk_df[index], rate[index]); |
| 1284 | 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 | 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 | 1288 | rate[index], spdif_priv->txrate[index]); |
| 1289 | 1289 | |
| 1290 | 1290 | return 0; |
| @@ -1305,10 +1305,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) · 14 unmodified lines | ||
| 1305 | 1305 | spdif_priv->pdev = pdev; |
| 1306 | 1306 | |
| 1307 | 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 | 1309 | /* Initialize this copy of the CPU DAI driver structure */ |
| 1314 | 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 | 1398 | struct device *dev = ssi->dev; |
| 1399 | 1399 | struct device_node *np = dev->of_node; |
| 1400 | − const struct of_device_id *of_id; | |
| 1401 | 1400 | const char *p, *sprop; |
| 1402 | 1401 | const __be32 *iprop; |
| 1403 | 1402 | u32 dmas[4]; |
| 1404 | 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 | 1405 | ret = of_property_match_string(np, "clock-names", "ipg"); |
| 1413 | 1406 | /* Get error code if not found */ |
| 1414 | 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 | 1485 | return -ENOMEM; |
| 1493 | 1486 | |
| 1494 | 1487 | ssi->dev = dev; |
| 1488 | + ssi->soc = of_device_get_match_data(&pdev->dev); | |
| 1495 | 1489 | |
| 1496 | 1490 | /* Probe from DT */ |
| 1497 | 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 | 1532 | /* Set software limitations for synchronous mode except AC97 */ |
| 1539 | 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 | 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 | 861 | .prepare = fsl_xcvr_prepare, |
| 862 | 862 | .startup = fsl_xcvr_startup, |
| 863 | 863 | .shutdown = fsl_xcvr_shutdown, |
| @@ -1130,16 +1130,11 @@ MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids); · 266 unmodified lines | ||
| 1130 | 1130 | static int fsl_xcvr_probe(struct platform_device *pdev) |
| 1131 | 1131 | { |
| 1132 | 1132 | struct device *dev = &pdev->dev; |
| 1133 | − const struct of_device_id *of_id; | |
| 1134 | 1133 | struct fsl_xcvr *xcvr; |
| 1135 | 1134 | struct resource *ram_res, *regs_res, *rx_res, *tx_res; |
| 1136 | 1135 | void __iomem *regs; |
| 1137 | 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 | 1138 | xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL); |
| 1144 | 1139 | if (!xcvr) |
| 1145 | 1140 | return -ENOMEM; |
| @@ -532,7 +532,7 @@ static int graph_for_each_link(struct asoc_simple_priv *priv, · 531 unmodified lines | ||
| 532 | 532 | static void graph_get_dais_count(struct asoc_simple_priv *priv, |
| 533 | 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 | 537 | struct snd_soc_card *card = simple_priv_to_card(priv); |
| 538 | 538 | struct link_info li; |
| @@ -608,7 +608,7 @@ err: · 69 unmodified lines | ||
| 608 | 608 | |
| 609 | 609 | return ret; |
| 610 | 610 | } |
| 611 | −EXPORT_SYMBOL_GPL(graph_parse_of); | |
| 611 | +EXPORT_SYMBOL_GPL(audio_graph_parse_of); | |
| 612 | 612 | |
| 613 | 613 | static int graph_count_noml(struct asoc_simple_priv *priv, |
| 614 | 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 | 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 | 710 | struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(card); |
| 711 | 711 | int ret; |
| @@ -720,7 +720,7 @@ int graph_card_probe(struct snd_soc_card *card) · 8 unmodified lines | ||
| 720 | 720 | |
| 721 | 721 | return 0; |
| 722 | 722 | } |
| 723 | −EXPORT_SYMBOL_GPL(graph_card_probe); | |
| 723 | +EXPORT_SYMBOL_GPL(audio_graph_card_probe); | |
| 724 | 724 | |
| 725 | 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 | 736 | card = simple_priv_to_card(priv); |
| 737 | 737 | card->dapm_widgets = graph_dapm_widgets; |
| 738 | 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 | 741 | if (of_device_get_match_data(dev)) |
| 742 | 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 | 749 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
| 750 | 750 | |
| 751 | 751 | return asoc_simple_clean_reference(card); |
| 752 | 752 | } |
| 753 | +EXPORT_SYMBOL_GPL(audio_graph_remove); | |
| 753 | 754 | |
| 754 | 755 | static const struct of_device_id graph_of_match[] = { |
| 755 | 756 | { .compatible = "audio-graph-card", }, |
| @@ -766,7 +767,7 @@ static struct platform_driver graph_card = { · 10 unmodified lines | ||
| 766 | 767 | .of_match_table = graph_of_match, |
| 767 | 768 | }, |
| 768 | 769 | .probe = graph_probe, |
| 769 | − .remove = graph_remove, | |
| 770 | + .remove = audio_graph_remove, | |
| 770 | 771 | }; |
| 771 | 772 | module_platform_driver(graph_card); |
| 772 | 773 | |
| @@ -172,16 +172,15 @@ int asoc_simple_parse_clk(struct device *dev, · 171 unmodified lines | ||
| 172 | 172 | * or device's module clock. |
| 173 | 173 | */ |
| 174 | 174 | clk = devm_get_clk_from_child(dev, node, NULL); |
| 175 | − if (!IS_ERR(clk)) { | |
| 176 | − simple_dai->sysclk = clk_get_rate(clk); | |
| 175 | + if (IS_ERR(clk)) | |
| 176 | + clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); | |
| 177 | 177 | |
| 178 | + if (!IS_ERR(clk)) { | |
| 178 | 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 | 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 | 186 | if (of_property_read_bool(node, "system-clock-direction-out")) |
| @@ -203,6 +203,8 @@ config SND_SOC_INTEL_KEEMBAY · 202 unmodified lines | ||
| 203 | 203 | tristate "Keembay Platforms" |
| 204 | 204 | depends on ARCH_KEEMBAY || COMPILE_TEST |
| 205 | 205 | depends on COMMON_CLK |
| 206 | + select SND_DMAENGINE_PCM | |
| 207 | + select SND_SOC_GENERIC_DMAENGINE_PCM | |
| 206 | 208 | help |
| 207 | 209 | If you have a Intel Keembay platform then enable this option |
| 208 | 210 | by saying Y or m. |
| @@ -111,6 +111,18 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH · 110 unmodified lines | ||
| 111 | 111 | Say Y or m if you have such a device. This is a recommended option. |
| 112 | 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 | 126 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH |
| 115 | 127 | tristate "Cherrytrail & Braswell with RT5672 codec" |
| 116 | 128 | depends on I2C && ACPI |
| @@ -10,6 +10,7 @@ snd-soc-sst-sof-wm8804-objs := sof_wm8804.o · 9 unmodified lines | ||
| 10 | 10 | snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o |
| 11 | 11 | snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o |
| 12 | 12 | snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o |
| 13 | +snd-soc-sst-bytcr-wm5102-objs := bytcr_wm5102.o | |
| 13 | 14 | snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o |
| 14 | 15 | snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o |
| 15 | 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 | 52 | obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o |
| 52 | 53 | obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o |
| 53 | 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 | 56 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o |
| 55 | 57 | obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o |
| 56 | 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 | 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 | 334 | .name = "SSP2-Codec", |
| 338 | 335 | .id = 0, |
| 339 | 336 | .no_pcm = 1, |
| @@ -35,6 +35,7 @@ enum { · 34 unmodified lines | ||
| 35 | 35 | BYT_RT5640_DMIC2_MAP, |
| 36 | 36 | BYT_RT5640_IN1_MAP, |
| 37 | 37 | BYT_RT5640_IN3_MAP, |
| 38 | + BYT_RT5640_NO_INTERNAL_MIC_MAP, | |
| 38 | 39 | }; |
| 39 | 40 | |
| 40 | 41 | enum { |
| @@ -71,6 +72,7 @@ enum { · 30 unmodified lines | ||
| 71 | 72 | #define BYT_RT5640_SSP0_AIF2 BIT(21) |
| 72 | 73 | #define BYT_RT5640_MCLK_EN BIT(22) |
| 73 | 74 | #define BYT_RT5640_MCLK_25MHZ BIT(23) |
| 75 | +#define BYT_RT5640_NO_SPEAKERS BIT(24) | |
| 74 | 76 | |
| 75 | 77 | #define BYTCR_INPUT_DEFAULTS \ |
| 76 | 78 | (BYT_RT5640_IN3_MAP | \ |
| @@ -116,6 +118,9 @@ static void log_quirks(struct device *dev) · 39 unmodified lines | ||
| 116 | 118 | case BYT_RT5640_IN3_MAP: |
| 117 | 119 | dev_info(dev, "quirk IN3_MAP enabled\n"); |
| 118 | 120 | break; |
| 121 | + case BYT_RT5640_NO_INTERNAL_MIC_MAP: | |
| 122 | + dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n"); | |
| 123 | + break; | |
| 119 | 124 | default: |
| 120 | 125 | dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); |
| 121 | 126 | break; |
| @@ -132,6 +137,8 @@ static void log_quirks(struct device *dev) · 10 unmodified lines | ||
| 132 | 137 | dev_info(dev, "quirk JD_NOT_INV enabled\n"); |
| 133 | 138 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) |
| 134 | 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 | 142 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) |
| 136 | 143 | dev_info(dev, "quirk DIFF_MIC enabled\n"); |
| 137 | 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 | 406 | BYT_RT5640_SSP0_AIF1 | |
| 400 | 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 | 423 | .matches = { |
| 404 | 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 | 544 | BYT_RT5640_MONO_SPEAKER | |
| 525 | 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 | 558 | .matches = { |
| 529 | 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 | 643 | BYT_RT5640_SSP0_AIF1 | |
| 614 | 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 | 655 | { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */ |
| 617 | 656 | .matches = { |
| 618 | 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 | 837 | BYT_RT5640_SSP0_AIF2 | |
| 799 | 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 | 854 | { /* Catch-all for generic Insyde tablets, must be last */ |
| 802 | 855 | .matches = { |
| 803 | 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 | 926 | struct snd_soc_card *card = runtime->card; |
| 874 | 927 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); |
| 875 | 928 | struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; |
| 876 | − const struct snd_soc_dapm_route *custom_map; | |
| 877 | − int num_routes; | |
| 929 | + const struct snd_soc_dapm_route *custom_map = NULL; | |
| 930 | + int num_routes = 0; | |
| 878 | 931 | int ret; |
| 879 | 932 | |
| 880 | 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 | 962 | custom_map = byt_rt5640_intmic_in3_map; |
| 910 | 963 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map); |
| 911 | 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 | 969 | case BYT_RT5640_DMIC2_MAP: |
| 913 | 970 | custom_map = byt_rt5640_intmic_dmic2_map; |
| 914 | 971 | num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); |
| 915 | 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 | 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 | 1000 | ret = snd_soc_dapm_add_routes(&card->dapm, |
| 947 | 1001 | byt_rt5640_mono_spk_map, |
| 948 | 1002 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); |
| 949 | − } else { | |
| 1003 | + } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { | |
| 950 | 1004 | ret = snd_soc_dapm_add_routes(&card->dapm, |
| 951 | 1005 | byt_rt5640_stereo_spk_map, |
| 952 | 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 | 1241 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
| 1188 | 1242 | { |
| 1189 | 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 | 1246 | const struct dmi_system_id *dmi_id; |
| 1192 | 1247 | struct byt_rt5640_private *priv; |
| 1193 | 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 | 1251 | bool sof_parent; |
| 1197 | 1252 | int ret_val = 0; |
| 1198 | 1253 | int dai_index = 0; |
| 1199 | − int i; | |
| 1254 | + int i, cfg_spk; | |
| 1200 | 1255 | |
| 1201 | 1256 | is_bytcr = false; |
| 1202 | 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 | 1404 | snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), |
| 1339 | − "cfg-spk:%s cfg-mic:%s", | |
| 1340 | − (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? "1" : "2", | |
| 1405 | + "cfg-spk:%d cfg-mic:%s", cfg_spk, | |
| 1341 | 1406 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
| 1342 | 1407 | byt_rt5640_card.components = byt_rt5640_components; |
| 1343 | 1408 | #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) |
| 1344 | 1409 | snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), |
| 1345 | − "bytcr-rt5640-%s-spk-%s-mic", | |
| 1346 | − (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? | |
| 1347 | − "mono" : "stereo", | |
| 1410 | + "bytcr-rt5640-%s-spk-%s-mic", spk_type, | |
| 1348 | 1411 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
| 1349 | 1412 | byt_rt5640_card.long_name = byt_rt5640_long_name; |
| 1350 | 1413 | #endif |
| @@ -435,6 +435,19 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { · 434 unmodified lines | ||
| 435 | 435 | BYT_RT5651_SSP0_AIF1 | |
| 436 | 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 | 452 | /* KIANO SlimNote 14.2 */ |
| 440 | 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 | 100 | struct snd_soc_component *component = codec_dai->component; |
| 101 | 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 | 103 | /* NAU88L24 supports 4 butons headset detection |
| 111 | 104 | * KEY_PLAYPAUSE |
| 112 | 105 | * KEY_VOICECOMMAND |
| @@ -141,6 +134,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, · 28 unmodified lines | ||
| 141 | 134 | SNDRV_PCM_HW_PARAM_CHANNELS); |
| 142 | 135 | struct snd_mask *fmt = |
| 143 | 136 | hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
| 137 | + int ret; | |
| 144 | 138 | |
| 145 | 139 | /* The DSP will covert the FE rate to 48k, stereo, 24bits */ |
| 146 | 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 | 144 | snd_mask_none(fmt); |
| 151 | 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 | 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 | 64 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 65 | 65 | struct snd_soc_dai *codec_dai; |
| 66 | + struct snd_soc_dai *cpu_dai; | |
| 66 | 67 | int j; |
| 67 | 68 | int ret = 0; |
| 68 | 69 | |
| @@ -70,10 +71,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) · 1 unmodified line | ||
| 70 | 71 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
| 71 | 72 | return 0; |
| 72 | 73 | |
| 74 | + cpu_dai = asoc_rtd_to_cpu(rtd, 0); | |
| 73 | 75 | for_each_rtd_codec_dais(rtd, j, codec_dai) { |
| 74 | − struct snd_soc_component *component = codec_dai->component; | |
| 75 | 76 | struct snd_soc_dapm_context *dapm = |
| 76 | − snd_soc_component_get_dapm(component); | |
| 77 | + snd_soc_component_get_dapm(cpu_dai->component); | |
| 77 | 78 | char pin_name[MAX_98373_PIN_NAME]; |
| 78 | 79 | |
| 79 | 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 | 323 | fs = 64; |
| 324 | 324 | |
| 325 | 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 | 326 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 334 | 327 | params_rate(params) * fs, |
| 335 | 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 | 50 | static const struct dmi_system_id sof_sdw_quirk_table[] = { |
| 51 | + /* CometLake devices */ | |
| 51 | 52 | { |
| 52 | 53 | .callback = sof_sdw_quirk_cb, |
| 53 | 54 | .matches = { |
| 54 | − DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
| 55 | − DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") | |
| 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") | |
| 55 | + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | |
| 56 | + DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), | |
| 75 | 57 | }, |
| 76 | − .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | | |
| 77 | − SOF_RT715_DAI_ID_FIX | | |
| 78 | − SOF_SDW_FOUR_SPK), | |
| 58 | + .driver_data = (void *)SOF_SDW_PCH_DMIC, | |
| 79 | 59 | }, |
| 80 | 60 | { |
| 81 | 61 | .callback = sof_sdw_quirk_cb, |
| @@ -106,7 +86,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 24 unmodified lines | ||
| 106 | 86 | SOF_RT715_DAI_ID_FIX | |
| 107 | 87 | SOF_SDW_FOUR_SPK), |
| 108 | 88 | }, |
| 109 | − { | |
| 89 | + { | |
| 110 | 90 | .callback = sof_sdw_quirk_cb, |
| 111 | 91 | .matches = { |
| 112 | 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 | 96 | SOF_RT715_DAI_ID_FIX | |
| 117 | 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 | 110 | .callback = sof_sdw_quirk_cb, |
| 121 | 111 | .matches = { |
| @@ -123,25 +113,31 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 1 unmodified line | ||
| 123 | 113 | DMI_MATCH(DMI_PRODUCT_NAME, |
| 124 | 114 | "Tiger Lake Client Platform"), |
| 125 | 115 | }, |
| 126 | − .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 | | |
| 127 | − SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | | |
| 128 | − SOF_SSP_PORT(SOF_I2S_SSP2)), | |
| 116 | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | | |
| 117 | + SOF_RT711_JD_SRC_JD1 | | |
| 118 | + SOF_SDW_PCH_DMIC | | |
| 119 | + SOF_SSP_PORT(SOF_I2S_SSP2)), | |
| 129 | 120 | }, |
| 130 | 121 | { |
| 131 | 122 | .callback = sof_sdw_quirk_cb, |
| 132 | 123 | .matches = { |
| 133 | − DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | |
| 134 | − DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), | |
| 124 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
| 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 | 132 | .callback = sof_sdw_quirk_cb, |
| 140 | 133 | .matches = { |
| 141 | − DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | |
| 142 | − DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), | |
| 134 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), | |
| 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 | 143 | .callback = sof_sdw_quirk_cb, |
| @@ -149,7 +145,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { · 1 unmodified line | ||
| 149 | 145 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
| 150 | 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 | 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 | 155 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), |
| 159 | 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 | 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 | 476 | return 0; |
| 452 | 477 | } |
| 453 | 478 | |
| 454 | −static void init_dai_link(struct snd_soc_dai_link *dai_links, int be_id, | |
| 455 | − char *name, int playback, int capture, | |
| 456 | − struct snd_soc_dai_link_component *cpus, | |
| 457 | − int cpus_num, | |
| 458 | − struct snd_soc_dai_link_component *codecs, | |
| 459 | − int codecs_num, | |
| 479 | +static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, | |
| 480 | + int be_id, char *name, int playback, int capture, | |
| 481 | + struct snd_soc_dai_link_component *cpus, int cpus_num, | |
| 482 | + struct snd_soc_dai_link_component *codecs, int codecs_num, | |
| 460 | 483 | int (*init)(struct snd_soc_pcm_runtime *rtd), |
| 461 | 484 | const struct snd_soc_ops *ops) |
| 462 | 485 | { |
| 486 | + dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); | |
| 463 | 487 | dai_links->id = be_id; |
| 464 | 488 | dai_links->name = name; |
| 465 | 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 | 822 | playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); |
| 799 | 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 | 825 | playback, capture, |
| 802 | 826 | cpus + *cpu_id, cpu_dai_num, |
| 803 | 827 | codecs, codec_num, |
| @@ -930,7 +954,7 @@ static int sof_card_dai_links_create(struct device *dev, · 126 unmodified lines | ||
| 930 | 954 | ctx->idisp_codec = true; |
| 931 | 955 | |
| 932 | 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 | 958 | comp_num += dmic_num; |
| 935 | 959 | |
| 936 | 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 | 1061 | playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; |
| 1038 | 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 | 1064 | playback, capture, |
| 1041 | 1065 | cpus + cpu_id, 1, |
| 1042 | 1066 | ssp_components, 1, |
| @@ -1053,7 +1077,7 @@ DMIC: · 10 unmodified lines | ||
| 1053 | 1077 | /* dmic */ |
| 1054 | 1078 | if (dmic_num > 0) { |
| 1055 | 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 | 1081 | 0, 1, // DMIC only supports capture |
| 1058 | 1082 | cpus + cpu_id, 1, |
| 1059 | 1083 | dmic_component, 1, |
| @@ -1061,7 +1085,7 @@ DMIC: · 1 unmodified line | ||
| 1061 | 1085 | INC_ID(be_id, cpu_id, link_id); |
| 1062 | 1086 | |
| 1063 | 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 | 1089 | 0, 1, // DMIC only supports capture |
| 1066 | 1090 | cpus + cpu_id, 1, |
| 1067 | 1091 | dmic_component, 1, |
| @@ -1104,7 +1128,7 @@ DMIC: · 36 unmodified lines | ||
| 1104 | 1128 | return -ENOMEM; |
| 1105 | 1129 | |
| 1106 | 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 | 1132 | 1, 0, // HDMI only supports playback |
| 1109 | 1133 | cpus + cpu_id, 1, |
| 1110 | 1134 | idisp_components + i, 1, |
| @@ -1197,6 +1221,15 @@ static int mc_probe(struct platform_device *pdev) · 86 unmodified lines | ||
| 1197 | 1221 | if (!card->components) |
| 1198 | 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 | 1233 | card->long_name = sdw_card_long_name; |
| 1201 | 1234 | |
| 1202 | 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 | 332 | struct catpt_dev *cdev = dev_get_drvdata(dai->dev); |
| 333 | 333 | struct snd_soc_component *component = dai->component; |
| 334 | − struct snd_kcontrol *pos, *kctl = NULL; | |
| 334 | + struct snd_kcontrol *pos; | |
| 335 | 335 | const char *name; |
| 336 | 336 | int ret; |
| 337 | 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 | 352 | break; |
| 353 | 353 | default: |
| 354 | 354 | return 0; |
| 355 | − }; | |
| 355 | + } | |
| 356 | 356 | |
| 357 | 357 | list_for_each_entry(pos, &component->card->snd_card->controls, list) { |
| 358 | 358 | if (pos->private_data == component && |
| 359 | − !strncmp(name, pos->id.name, sizeof(pos->id.name))) { | |
| 360 | − kctl = pos; | |
| 359 | + !strncmp(name, pos->id.name, sizeof(pos->id.name))) | |
| 361 | 360 | break; |
| 362 | − } | |
| 363 | 361 | } |
| 364 | − if (!kctl) | |
| 362 | + if (list_entry_is_head(pos, &component->card->snd_card->controls, list)) | |
| 365 | 363 | return -ENOENT; |
| 366 | 364 | |
| 367 | 365 | if (stream->template->type != CATPT_STRM_TYPE_LOOPBACK) |
| 368 | − return catpt_set_dspvol(cdev, id, (long *)kctl->private_value); | |
| 369 | − ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)kctl->private_value); | |
| 366 | + return catpt_set_dspvol(cdev, id, (long *)pos->private_value); | |
| 367 | + ret = catpt_ipc_mute_loopback(cdev, id, *(bool *)pos->private_value); | |
| 370 | 368 | if (ret) |
| 371 | 369 | return CATPT_IPC_ERROR(ret); |
| 372 | 370 | return 0; |
| @@ -44,7 +44,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { · 43 unmodified lines | ||
| 44 | 44 | .link_mask = 0x1, /* link0 required */ |
| 45 | 45 | .links = adl_rvp, |
| 46 | 46 | .drv_name = "sof_sdw", |
| 47 | − .sof_fw_filename = "sof-adl.ri", | |
| 48 | 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 | 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 | 154 | .sof_fw_filename = "sof-byt.ri", |
| 155 | 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 | 174 | .id = "DLGS7212", |
| 159 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 222 | static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { |
| 209 | 223 | { |
| 210 | 224 | .mask = BIT(0), |
| @@ -358,14 +372,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { · 147 unmodified lines | ||
| 358 | 372 | .link_mask = 0x7, |
| 359 | 373 | .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, |
| 360 | 374 | .drv_name = "sof_sdw", |
| 361 | − .sof_fw_filename = "sof-tgl.ri", | |
| 362 | 375 | .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", |
| 363 | 376 | }, |
| 364 | 377 | { |
| 365 | 378 | .link_mask = 0xF, /* 4 active links required */ |
| 366 | 379 | .links = tgl_3_in_1_default, |
| 367 | 380 | .drv_name = "sof_sdw", |
| 368 | − .sof_fw_filename = "sof-tgl.ri", | |
| 369 | 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 | 389 | .link_mask = 0xF, |
| 378 | 390 | .links = tgl_3_in_1_mono_amp, |
| 379 | 391 | .drv_name = "sof_sdw", |
| 380 | − .sof_fw_filename = "sof-tgl.ri", | |
| 381 | 392 | .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", |
| 382 | 393 | }, |
| 383 | 394 | { |
| 384 | 395 | .link_mask = 0xF, /* 4 active links required */ |
| 385 | 396 | .links = tgl_3_in_1_sdca, |
| 386 | 397 | .drv_name = "sof_sdw", |
| 387 | − .sof_fw_filename = "sof-tgl.ri", | |
| 388 | 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 | 407 | .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ |
| 392 | 408 | .links = tgl_rvp, |
| 393 | 409 | .drv_name = "sof_sdw", |
| 394 | − .sof_fw_filename = "sof-tgl.ri", | |
| 395 | 410 | .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", |
| 396 | 411 | }, |
| 397 | 412 | { |
| 398 | 413 | .link_mask = 0x3, /* rt5682 on link0 & 2xmax98373 on link 1 */ |
| 399 | 414 | .links = tgl_chromebook_base, |
| 400 | 415 | .drv_name = "sof_sdw", |
| 401 | − .sof_fw_filename = "sof-tgl.ri", | |
| 402 | 416 | .sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg", |
| 403 | 417 | }, |
| 404 | 418 | { |
| 405 | 419 | .link_mask = 0x1, /* this will only enable rt5682 for now */ |
| 406 | 420 | .links = tgl_chromebook_base, |
| 407 | 421 | .drv_name = "sof_sdw", |
| 408 | − .sof_fw_filename = "sof-tgl.ri", | |
| 409 | 422 | .sof_tplg_filename = "sof-tgl-rt5682.tplg", |
| 410 | 423 | }, |
| 411 | 424 | {}, |
| 412 | 425 | }; |
| 413 | 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 | 12 | #if IS_ENABLED(CONFIG_X86) |
| 13 | 13 | |
| 14 | +#include <linux/dmi.h> | |
| 14 | 15 | #include <asm/cpu_device_id.h> |
| 15 | 16 | #include <asm/intel-family.h> |
| 16 | 17 | #include <asm/iosf_mbi.h> |
| @@ -38,12 +39,36 @@ SOC_INTEL_IS_CPU(cml, KABYLAKE_L); · 21 unmodified lines | ||
| 38 | 39 | |
| 39 | 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 | 63 | struct device *dev = &pdev->dev; |
| 42 | 64 | int status = 0; |
| 43 | 65 | |
| 44 | 66 | if (!soc_intel_is_byt()) |
| 45 | 67 | return false; |
| 46 | 68 | |
| 69 | + if (dmi_check_system(force_bytcr_table)) | |
| 70 | + return true; | |
| 71 | + | |
| 47 | 72 | if (iosf_mbi_available()) { |
| 48 | 73 | u32 bios_status; |
| 49 | 74 | |
| @@ -5,11 +5,14 @@ · 4 unmodified lines | ||
| 5 | 5 | // Intel KeemBay Platform driver. |
| 6 | 6 | // |
| 7 | 7 | |
| 8 | +#include <linux/bitrev.h> | |
| 8 | 9 | #include <linux/clk.h> |
| 10 | +#include <linux/dma-mapping.h> | |
| 9 | 11 | #include <linux/io.h> |
| 10 | 12 | #include <linux/module.h> |
| 11 | 13 | #include <linux/of.h> |
| 12 | 14 | #include <linux/of_device.h> |
| 15 | +#include <sound/dmaengine_pcm.h> | |
| 13 | 16 | #include <sound/pcm.h> |
| 14 | 17 | #include <sound/pcm_params.h> |
| 15 | 18 | #include <sound/soc.h> |
| @@ -37,7 +40,8 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { · 21 unmodified lines | ||
| 37 | 40 | .rate_max = 48000, |
| 38 | 41 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
| 39 | 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 | 45 | .channels_min = 2, |
| 42 | 46 | .channels_max = 2, |
| 43 | 47 | .buffer_bytes_max = BUFFER_BYTES_MAX, |
| @@ -48,6 +52,50 @@ static const struct snd_pcm_hardware kmb_pcm_hardware = { · 4 unmodified lines | ||
| 48 | 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 | 99 | static unsigned int kmb_pcm_tx_fn(struct kmb_i2s_info *kmb_i2s, |
| 52 | 100 | struct snd_pcm_runtime *runtime, |
| 53 | 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 | 111 | writel(((u16(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); |
| 64 | 112 | writel(((u16(*)[2])buf)[tx_ptr][1], i2s_base + RRBR_RTHR(0)); |
| 65 | 113 | } else { |
| 114 | + if (kmb_i2s->iec958_fmt) | |
| 115 | + hdmi_reformat_iec958(runtime, kmb_i2s, tx_ptr); | |
| 66 | 116 | writel(((u32(*)[2])buf)[tx_ptr][0], i2s_base + LRBR_LTHR(0)); |
| 67 | 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 | 283 | kmb_i2s->tx_substream = NULL; |
| 234 | 284 | else |
| 235 | 285 | kmb_i2s->rx_substream = NULL; |
| 286 | + kmb_i2s->iec958_fmt = false; | |
| 236 | 287 | break; |
| 237 | 288 | default: |
| 238 | 289 | return -EINVAL; |
| @@ -343,6 +394,53 @@ static const struct snd_soc_component_driver kmb_component = { · 104 unmodified lines | ||
| 343 | 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 | 444 | static void kmb_i2s_start(struct kmb_i2s_info *kmb_i2s, |
| 347 | 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 | 454 | else |
| 357 | 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 | 463 | if (kmb_i2s->clock_provider) |
| 362 | 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 | 536 | break; |
| 435 | 537 | case SNDRV_PCM_TRIGGER_STOP: |
| 436 | 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 | 541 | break; |
| 439 | 542 | default: |
| 440 | 543 | return -EINVAL; |
| @@ -485,16 +588,25 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, · 44 unmodified lines | ||
| 485 | 588 | config->data_width = 16; |
| 486 | 589 | kmb_i2s->ccr = 0x00; |
| 487 | 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 | 593 | break; |
| 489 | 594 | case SNDRV_PCM_FORMAT_S24_LE: |
| 490 | 595 | config->data_width = 32; |
| 491 | 596 | kmb_i2s->ccr = 0x14; |
| 492 | 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 | 600 | break; |
| 601 | + case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: | |
| 602 | + kmb_i2s->iec958_fmt = true; | |
| 603 | + fallthrough; | |
| 494 | 604 | case SNDRV_PCM_FORMAT_S32_LE: |
| 495 | 605 | config->data_width = 32; |
| 496 | 606 | kmb_i2s->ccr = 0x10; |
| 497 | 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 | 610 | break; |
| 499 | 611 | default: |
| 500 | 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 | 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 | 732 | static struct snd_soc_dai_ops kmb_dai_ops = { |
| 733 | + .startup = kmb_dai_startup, | |
| 576 | 734 | .trigger = kmb_dai_trigger, |
| 577 | 735 | .hw_params = kmb_dai_hw_params, |
| 736 | + .hw_free = kmb_dai_hw_free, | |
| 578 | 737 | .prepare = kmb_dai_prepare, |
| 579 | 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 | 759 | static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { |
| 583 | 760 | { |
| 584 | 761 | .name = "intel_kmb_i2s", |
| @@ -607,6 +784,7 @@ static struct snd_soc_dai_driver intel_kmb_i2s_dai[] = { · 22 unmodified lines | ||
| 607 | 784 | SNDRV_PCM_FMTBIT_S16_LE), |
| 608 | 785 | }, |
| 609 | 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 | 804 | SNDRV_PCM_FMTBIT_S16_LE), |
| 627 | 805 | }, |
| 628 | 806 | .ops = &kmb_dai_ops, |
| 807 | + .probe = kmb_probe, | |
| 629 | 808 | }, |
| 630 | 809 | }; |
| 631 | 810 | |
| 632 | 811 | static const struct of_device_id kmb_plat_of_match[] = { |
| 633 | 812 | { .compatible = "intel,keembay-i2s", .data = &intel_kmb_i2s_dai}, |
| 813 | + { .compatible = "intel,keembay-hdmi-i2s", .data = &intel_kmb_hdmi_dai}, | |
| 634 | 814 | { .compatible = "intel,keembay-tdm", .data = &intel_kmb_tdm_dai}, |
| 635 | 815 | {} |
| 636 | 816 | }; |
| 637 | 817 | |
| 638 | 818 | static int kmb_plat_dai_probe(struct platform_device *pdev) |
| 639 | 819 | { |
| 820 | + struct device_node *np = pdev->dev.of_node; | |
| 640 | 821 | struct snd_soc_dai_driver *kmb_i2s_dai; |
| 641 | 822 | const struct of_device_id *match; |
| 642 | 823 | struct device *dev = &pdev->dev; |
| 643 | 824 | struct kmb_i2s_info *kmb_i2s; |
| 825 | + struct resource *res; | |
| 644 | 826 | int ret, irq; |
| 645 | 827 | u32 comp1_reg; |
| 646 | 828 | |
| @@ -682,7 +864,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) · 35 unmodified lines | ||
| 682 | 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 | 868 | if (IS_ERR(kmb_i2s->i2s_base)) |
| 687 | 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 | 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 | 877 | comp1_reg = readl(kmb_i2s->i2s_base + I2S_COMP_PARAM_1); |
| 706 | 878 | |
| 707 | 879 | kmb_i2s->fifo_th = (1 << COMP1_FIFO_DEPTH(comp1_reg)) / 2; |
| 708 | 880 | |
| 709 | − ret = devm_snd_soc_register_component(dev, &kmb_component, | |
| 710 | − kmb_i2s_dai, 1); | |
| 881 | + kmb_i2s->use_pio = !(of_property_read_bool(np, "dmas")); | |
| 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 | 909 | if (ret) { |
| 712 | 910 | dev_err(dev, "not able to register dai\n"); |
| 713 | 911 | return ret; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/bits.h> |
| 13 | 13 | #include <linux/bitfield.h> |
| 14 | 14 | #include <linux/types.h> |
| 15 | +#include <sound/dmaengine_pcm.h> | |
| 15 | 16 | |
| 16 | 17 | /* Register values with reference to KMB databook v1.1 */ |
| 17 | 18 | /* common register for all channel */ |
| @@ -103,7 +104,12 @@ · 85 unmodified lines | ||
| 103 | 104 | #define DW_I2S_PROVIDER BIT(3) |
| 104 | 105 | |
| 105 | 106 | #define I2S_RXDMA 0x01C0 |
| 107 | +#define I2S_RRXDMA 0x01C4 | |
| 106 | 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 | 115 | * struct i2s_clk_config_data - represent i2s clk configuration data |
| @@ -131,6 +137,9 @@ struct kmb_i2s_info { · 21 unmodified lines | ||
| 131 | 137 | u32 xfer_resolution; |
| 132 | 138 | u32 fifo_th; |
| 133 | 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 | 144 | struct i2s_clk_config_data config; |
| 136 | 145 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); |
| @@ -141,6 +150,7 @@ struct kmb_i2s_info { · 4 unmodified lines | ||
| 141 | 150 | struct snd_pcm_substream *rx_substream; |
| 142 | 151 | unsigned int tx_ptr; |
| 143 | 152 | unsigned int rx_ptr; |
| 153 | + bool iec958_fmt; | |
| 144 | 154 | }; |
| 145 | 155 | |
| 146 | 156 | #endif /* KMB_PLATFORM_H_ */ |
| @@ -950,12 +950,8 @@ static int skl_first_init(struct hdac_bus *bus) · 949 unmodified lines | ||
| 950 | 950 | bus->num_streams = cp_streams + pb_streams; |
| 951 | 951 | |
| 952 | 952 | /* allow 64bit DMA address if supported by H/W */ |
| 953 | − if (!dma_set_mask(bus->dev, DMA_BIT_MASK(64))) { | |
| 954 | − dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(64)); | |
| 955 | − } else { | |
| 956 | − dma_set_mask(bus->dev, DMA_BIT_MASK(32)); | |
| 957 | − dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(32)); | |
| 958 | − } | |
| 953 | + if (dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(64))) | |
| 954 | + dma_set_mask_and_coherent(bus->dev, DMA_BIT_MASK(32)); | |
| 959 | 955 | |
| 960 | 956 | /* initialize streams */ |
| 961 | 957 | snd_hdac_ext_stream_init_all |
| @@ -455,7 +455,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { · 454 unmodified lines | ||
| 455 | 455 | .rates = SNDRV_PCM_RATE_8000_48000, |
| 456 | 456 | .formats = JZ4740_I2S_FMTS, |
| 457 | 457 | }, |
| 458 | − .symmetric_rates = 1, | |
| 458 | + .symmetric_rate = 1, | |
| 459 | 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 | 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 | 185 | static int kirkwood_dma_prepare(struct snd_soc_component *component, |
| 205 | 186 | struct snd_pcm_substream *substream) |
| 206 | 187 | { |
| @@ -244,82 +225,28 @@ static snd_pcm_uframes_t kirkwood_dma_pointer( · 37 unmodified lines | ||
| 244 | 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 | 228 | static int kirkwood_dma_new(struct snd_soc_component *component, |
| 267 | 229 | struct snd_soc_pcm_runtime *rtd) |
| 268 | 230 | { |
| 231 | + size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; | |
| 269 | 232 | struct snd_card *card = rtd->card->snd_card; |
| 270 | − struct snd_pcm *pcm = rtd->pcm; | |
| 271 | 233 | int ret; |
| 272 | 234 | |
| 273 | 235 | ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); |
| 274 | 236 | if (ret) |
| 275 | 237 | return ret; |
| 276 | 238 | |
| 277 | − if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | |
| 278 | − ret = kirkwood_dma_preallocate_dma_buffer(pcm, | |
| 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 | − } | |
| 239 | + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, | |
| 240 | + card->dev, size, size); | |
| 290 | 241 | |
| 291 | 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 | 245 | const struct snd_soc_component_driver kirkwood_soc_component = { |
| 316 | 246 | .name = DRV_NAME, |
| 317 | 247 | .open = kirkwood_dma_open, |
| 318 | 248 | .close = kirkwood_dma_close, |
| 319 | − .hw_params = kirkwood_dma_hw_params, | |
| 320 | − .hw_free = kirkwood_dma_hw_free, | |
| 321 | 249 | .prepare = kirkwood_dma_prepare, |
| 322 | 250 | .pointer = kirkwood_dma_pointer, |
| 323 | 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 | 172 | config SND_SOC_MT8192_MT6359_RT1015_RT5682 |
| 173 | 173 | tristate "ASoC Audio driver for MT8192 with MT6359 RT1015 RT5682 codec" |
| 174 | 174 | depends on I2C |
| 175 | − depends on SND_SOC_MT8192 | |
| 175 | + depends on SND_SOC_MT8192 && MTK_PMIC_WRAP | |
| 176 | 176 | select SND_SOC_MT6359 |
| 177 | 177 | select SND_SOC_RT1015 |
| 178 | 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 | 657 | .ops = &mt2701_afe_i2s_ops, |
| 658 | − .symmetric_rates = 1, | |
| 658 | + .symmetric_rate = 1, | |
| 659 | 659 | }, |
| 660 | 660 | { |
| 661 | 661 | .name = "I2S1", |
| @@ -679,7 +679,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | ||
| 679 | 679 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 680 | 680 | }, |
| 681 | 681 | .ops = &mt2701_afe_i2s_ops, |
| 682 | − .symmetric_rates = 1, | |
| 682 | + .symmetric_rate = 1, | |
| 683 | 683 | }, |
| 684 | 684 | { |
| 685 | 685 | .name = "I2S2", |
| @@ -703,7 +703,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | ||
| 703 | 703 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 704 | 704 | }, |
| 705 | 705 | .ops = &mt2701_afe_i2s_ops, |
| 706 | − .symmetric_rates = 1, | |
| 706 | + .symmetric_rate = 1, | |
| 707 | 707 | }, |
| 708 | 708 | { |
| 709 | 709 | .name = "I2S3", |
| @@ -727,7 +727,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 17 unmodified lines | ||
| 727 | 727 | | SNDRV_PCM_FMTBIT_S32_LE) |
| 728 | 728 | }, |
| 729 | 729 | .ops = &mt2701_afe_i2s_ops, |
| 730 | − .symmetric_rates = 1, | |
| 730 | + .symmetric_rate = 1, | |
| 731 | 731 | }, |
| 732 | 732 | { |
| 733 | 733 | .name = "MRG BT", |
| @@ -749,7 +749,7 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { · 15 unmodified lines | ||
| 749 | 749 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 750 | 750 | }, |
| 751 | 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 | 270 | .formats = MTK_PCM_FORMATS, |
| 271 | 271 | }, |
| 272 | 272 | .ops = &mtk_dai_pcm_ops, |
| 273 | − .symmetric_rates = 1, | |
| 274 | − .symmetric_samplebits = 1, | |
| 273 | + .symmetric_rate = 1, | |
| 274 | + .symmetric_sample_bits = 1, | |
| 275 | 275 | }, |
| 276 | 276 | { |
| 277 | 277 | .name = "PCM 2", |
| @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | ||
| 291 | 291 | .formats = MTK_PCM_FORMATS, |
| 292 | 292 | }, |
| 293 | 293 | .ops = &mtk_dai_pcm_ops, |
| 294 | − .symmetric_rates = 1, | |
| 295 | − .symmetric_samplebits = 1, | |
| 294 | + .symmetric_rate = 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 | 571 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 572 | 572 | }, |
| 573 | 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 | 125 | for_each_rtd_codec_dais(rtd, i, codec_dai) { |
| 126 | 126 | if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || |
| 127 | 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 | 128 | ret = snd_soc_dai_set_pll(codec_dai, 0, |
| 135 | 129 | RT1015_PLL_S_BCLK, |
| 136 | 130 | rate * 64, rate * 256); |
| @@ -270,8 +270,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 269 unmodified lines | ||
| 270 | 270 | .formats = MTK_PCM_FORMATS, |
| 271 | 271 | }, |
| 272 | 272 | .ops = &mtk_dai_pcm_ops, |
| 273 | − .symmetric_rates = 1, | |
| 274 | − .symmetric_samplebits = 1, | |
| 273 | + .symmetric_rate = 1, | |
| 274 | + .symmetric_sample_bits = 1, | |
| 275 | 275 | }, |
| 276 | 276 | { |
| 277 | 277 | .name = "PCM 2", |
| @@ -291,8 +291,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | ||
| 291 | 291 | .formats = MTK_PCM_FORMATS, |
| 292 | 292 | }, |
| 293 | 293 | .ops = &mtk_dai_pcm_ops, |
| 294 | − .symmetric_rates = 1, | |
| 295 | − .symmetric_samplebits = 1, | |
| 294 | + .symmetric_rate = 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 | 68 | int ret, i; |
| 69 | 69 | |
| 70 | 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 | 71 | ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, |
| 78 | 72 | rate * 64, rate * 256); |
| 79 | 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 | 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 | 159 | static int |
| 127 | 160 | mt8183_mt6358_ts3a227_max98357_bt_sco_startup( |
| 128 | 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 | 395 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 363 | 396 | .dynamic = 1, |
| 364 | 397 | .dpcm_playback = 1, |
| 398 | + .ops = &mt8183_mt6358_ops, | |
| 365 | 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 | 443 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 410 | 444 | .dynamic = 1, |
| 411 | 445 | .dpcm_capture = 1, |
| 446 | + .ops = &mt8183_mt6358_ops, | |
| 412 | 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 | 42 | static int mt8192_memif_fs(struct snd_pcm_substream *substream, |
| 43 | 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 | 46 | struct snd_soc_component *component = |
| 47 | 47 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); |
| 48 | 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 | 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 | 63 | struct snd_soc_component *component = |
| 64 | 64 | snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); |
| 65 | 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 | 360 | .formats = MTK_PCM_FORMATS, |
| 361 | 361 | }, |
| 362 | 362 | .ops = &mtk_dai_pcm_ops, |
| 363 | − .symmetric_rates = 1, | |
| 364 | − .symmetric_samplebits = 1, | |
| 363 | + .symmetric_rate = 1, | |
| 364 | + .symmetric_sample_bits = 1, | |
| 365 | 365 | }, |
| 366 | 366 | { |
| 367 | 367 | .name = "PCM 2", |
| @@ -381,8 +381,8 @@ static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { · 13 unmodified lines | ||
| 381 | 381 | .formats = MTK_PCM_FORMATS, |
| 382 | 382 | }, |
| 383 | 383 | .ops = &mtk_dai_pcm_ops, |
| 384 | − .symmetric_rates = 1, | |
| 385 | − .symmetric_samplebits = 1, | |
| 384 | + .symmetric_rate = 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 | 738 | if (!tdm_priv) |
| 739 | 739 | return NULL; |
| 740 | 740 | |
| 741 | − tdm_priv->mclk_multiple = 128; | |
| 741 | + tdm_priv->mclk_multiple = 512; | |
| 742 | 742 | tdm_priv->bck_id = MT8192_I2S4_BCK; |
| 743 | 743 | tdm_priv->mclk_id = MT8192_I2S4_MCK; |
| 744 | 744 | tdm_priv->id = MT8192_DAI_TDM; |
| @@ -31,12 +31,15 @@ · 30 unmodified lines | ||
| 31 | 31 | #define RT5682_CODEC_DAI "rt5682-aif1" |
| 32 | 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 | 39 | static int mt8192_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, |
| 37 | 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 | 43 | struct snd_soc_card *card = rtd->card; |
| 41 | 44 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
| 42 | 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 | 49 | int ret, i; |
| 47 | 50 | |
| 48 | 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 | 52 | ret = snd_soc_dai_set_pll(codec_dai, 0, |
| 56 | 53 | RT1015_PLL_S_BCLK, |
| 57 | 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 | 74 | static int mt8192_rt5682_i2s_hw_params(struct snd_pcm_substream *substream, |
| 78 | 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 | 78 | struct snd_soc_card *card = rtd->card; |
| 82 | 79 | struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
| 83 | 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 | 309 | struct snd_soc_component *cmpnt_codec = |
| 313 | 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 | 313 | int ret; |
| 316 | 314 | |
| 317 | 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 | 327 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
| 330 | 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 | 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 | 344 | return ret; |
| 336 | 345 | } |
| 337 | 346 | |
| 338 | − return 0; | |
| 339 | −}; | |
| 347 | + return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); | |
| 348 | +} | |
| 340 | 349 | |
| 341 | 350 | static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, |
| 342 | 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 | 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 | 365 | static const unsigned int channels[] = { |
| 363 | 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 | 379 | .mask = 0, |
| 377 | 380 | }; |
| 378 | 381 | |
| 382 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); | |
| 379 | 383 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 384 | + int ret; | |
| 380 | 385 | |
| 381 | 386 | ret = snd_pcm_hw_constraint_list(runtime, 0, |
| 382 | 387 | SNDRV_PCM_HW_PARAM_CHANNELS, |
| 383 | 388 | &constraints_channels); |
| 384 | 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 | 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 | 395 | SNDRV_PCM_HW_PARAM_RATE, |
| 391 | 396 | &constraints_rates); |
| 392 | 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 | 399 | return ret; |
| 395 | 400 | } |
| 396 | 401 | |
| 397 | 402 | return 0; |
| 398 | 403 | } |
| 399 | 404 | |
| 400 | −static const struct snd_soc_ops mt8192_mt6359_rt1015_rt5682_capture1_ops = { | |
| 401 | − .startup = mt8192_mt6359_rt1015_rt5682_cap1_startup, | |
| 405 | +static const struct snd_soc_ops mt8192_mt6359_capture1_ops = { | |
| 406 | + .startup = mt8192_mt6359_cap1_startup, | |
| 402 | 407 | }; |
| 403 | 408 | |
| 404 | 409 | static int |
| @@ -656,7 +661,7 @@ SND_SOC_DAILINK_DEFS(pcm2, · 251 unmodified lines | ||
| 656 | 661 | |
| 657 | 662 | SND_SOC_DAILINK_DEFS(tdm, |
| 658 | 663 | DAILINK_COMP_ARRAY(COMP_CPU("TDM")), |
| 659 | − DAILINK_COMP_ARRAY(COMP_DUMMY()), | |
| 664 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), | |
| 660 | 665 | DAILINK_COMP_ARRAY(COMP_EMPTY())); |
| 661 | 666 | |
| 662 | 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 | 764 | SND_SOC_DPCM_TRIGGER_PRE}, |
| 760 | 765 | .dynamic = 1, |
| 761 | 766 | .dpcm_capture = 1, |
| 762 | − .ops = &mt8192_mt6359_rt1015_rt5682_capture1_ops, | |
| 767 | + .ops = &mt8192_mt6359_capture1_ops, | |
| 763 | 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 | 1000 | .name = "TDM", |
| 996 | 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 | 1005 | .dpcm_playback = 1, |
| 998 | 1006 | .ignore_suspend = 1, |
| 1007 | + .be_hw_params_fixup = mt8192_i2s_hw_params_fixup, | |
| 1008 | + .ignore = 1, | |
| 1009 | + .init = mt8192_mt6359_hdmi_init, | |
| 999 | 1010 | SND_SOC_DAILINK_REG(tdm), |
| 1000 | 1011 | }, |
| 1001 | 1012 | }; |
| @@ -1006,6 +1017,7 @@ mt8192_mt6359_rt1015_rt5682_widgets[] = { · 4 unmodified lines | ||
| 1006 | 1017 | SND_SOC_DAPM_SPK("Right Spk", NULL), |
| 1007 | 1018 | SND_SOC_DAPM_HP("Headphone Jack", NULL), |
| 1008 | 1019 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
| 1020 | + SND_SOC_DAPM_OUTPUT("TDM Out"), | |
| 1009 | 1021 | }; |
| 1010 | 1022 | |
| 1011 | 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 | 1028 | { "Headphone Jack", NULL, "HPOL" }, |
| 1017 | 1029 | { "Headphone Jack", NULL, "HPOR" }, |
| 1018 | 1030 | { "IN1P", NULL, "Headset Mic" }, |
| 1031 | + /* TDM */ | |
| 1032 | + { "TDM Out", NULL, "TDM" }, | |
| 1019 | 1033 | }; |
| 1020 | 1034 | |
| 1021 | 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 | 1103 | static int mt8192_mt6359_dev_probe(struct platform_device *pdev) |
| 1090 | 1104 | { |
| 1091 | 1105 | struct snd_soc_card *card; |
| 1092 | − struct device_node *platform_node; | |
| 1106 | + struct device_node *platform_node, *hdmi_codec; | |
| 1093 | 1107 | int ret, i; |
| 1094 | 1108 | struct snd_soc_dai_link *dai_link; |
| 1095 | 1109 | const struct of_device_id *match; |
| 1110 | + struct mt8192_mt6359_priv *priv; | |
| 1096 | 1111 | |
| 1097 | 1112 | platform_node = of_parse_phandle(pdev->dev.of_node, |
| 1098 | 1113 | "mediatek,platform", 0); |
| @@ -1108,6 +1123,9 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 1108 | 1123 | card = (struct snd_soc_card *)match->data; |
| 1109 | 1124 | card->dev = &pdev->dev; |
| 1110 | 1125 | |
| 1126 | + hdmi_codec = of_parse_phandle(pdev->dev.of_node, | |
| 1127 | + "mediatek,hdmi-codec", 0); | |
| 1128 | + | |
| 1111 | 1129 | for_each_card_prelinks(card, i, dai_link) { |
| 1112 | 1130 | if (strcmp(dai_link->name, "I2S3") == 0) { |
| 1113 | 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 | 1160 | if (!dai_link->platforms->name) |
| 1138 | 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 | 1169 | ret = mt8192_afe_gpio_init(&pdev->dev); |
| 1142 | 1170 | if (ret) { |
| 1143 | 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 | 124 | .trigger = aiu_fifo_i2s_trigger, |
| 125 | 125 | .prepare = aiu_fifo_i2s_prepare, |
| 126 | 126 | .hw_params = aiu_fifo_i2s_hw_params, |
| 127 | − .hw_free = aiu_fifo_hw_free, | |
| 128 | 127 | .startup = aiu_fifo_startup, |
| 129 | 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 | 158 | .trigger = fifo_spdif_trigger, |
| 159 | 159 | .prepare = fifo_spdif_prepare, |
| 160 | 160 | .hw_params = fifo_spdif_hw_params, |
| 161 | − .hw_free = aiu_fifo_hw_free, | |
| 162 | 161 | .startup = aiu_fifo_startup, |
| 163 | 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 | 99 | struct snd_soc_component *component = dai->component; |
| 100 | 100 | struct aiu_fifo *fifo = dai->playback_dma_data; |
| 101 | 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 | 103 | /* Setup the fifo boundaries */ |
| 109 | 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 | 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 | 122 | static irqreturn_t aiu_fifo_isr(int irq, void *dev_id) |
| 134 | 123 | { |
| 135 | 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 | 176 | int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, |
| 188 | 177 | struct snd_soc_dai *dai) |
| 189 | 178 | { |
| 190 | − struct snd_pcm_substream *substream = | |
| 191 | − rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | |
| 192 | 179 | struct snd_card *card = rtd->card->snd_card; |
| 193 | 180 | struct aiu_fifo *fifo = dai->playback_dma_data; |
| 194 | 181 | size_t size = fifo->pcm->buffer_bytes_max; |
| 195 | 182 | |
| 196 | − snd_pcm_lib_preallocate_pages(substream, | |
| 197 | − SNDRV_DMA_TYPE_DEV, | |
| 198 | − card->dev, size, size); | |
| 183 | + snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, | |
| 184 | + card->dev, size, size); | |
| 199 | 185 | |
| 200 | 186 | return 0; |
| 201 | 187 | } |
| @@ -353,7 +353,7 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { · 352 unmodified lines | ||
| 353 | 353 | .rates = PXA2XX_I2S_RATES, |
| 354 | 354 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
| 355 | 355 | .ops = &pxa_i2s_dai_ops, |
| 356 | − .symmetric_rates = 1, | |
| 356 | + .symmetric_rate = 1, | |
| 357 | 357 | }; |
| 358 | 358 | |
| 359 | 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 | 250 | .micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000), |
| 251 | 251 | .micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000), |
| 252 | 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 | 255 | .rdma_dyncclk = REG_FIELD_ID(0x8400, 12, 12, 2, 0x1000), |
| 256 | 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 | 286 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", |
| 287 | 287 | ret); |
| 288 | 288 | |
| 289 | − if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) { | |
| 290 | − ret = clk_enable(drvdata->mi2s_bit_clk[id]); | |
| 291 | − if (ret) { | |
| 292 | − dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); | |
| 293 | − clk_disable(drvdata->mi2s_osr_clk[id]); | |
| 294 | − return ret; | |
| 295 | − } | |
| 296 | − drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE; | |
| 289 | + ret = clk_enable(drvdata->mi2s_bit_clk[id]); | |
| 290 | + if (ret) { | |
| 291 | + dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); | |
| 292 | + clk_disable(drvdata->mi2s_osr_clk[id]); | |
| 293 | + return ret; | |
| 297 | 294 | } |
| 298 | − | |
| 299 | 295 | break; |
| 300 | 296 | case SNDRV_PCM_TRIGGER_STOP: |
| 301 | 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 | 306 | if (ret) |
| 311 | 307 | dev_err(dai->dev, "error writing to i2sctl reg: %d\n", |
| 312 | 308 | ret); |
| 313 | − if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) { | |
| 314 | − clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); | |
| 315 | − drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE; | |
| 316 | − } | |
| 309 | + | |
| 310 | + clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); | |
| 311 | + | |
| 317 | 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 | 477 | static struct regmap_config lpass_cpu_regmap_config = { |
| 478 | + .name = "lpass_cpu", | |
| 483 | 479 | .reg_bits = 32, |
| 484 | 480 | .reg_stride = 4, |
| 485 | 481 | .val_bits = 32, |
| @@ -599,7 +595,7 @@ static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg) · 113 unmodified lines | ||
| 599 | 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 | 599 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) |
| 604 | 600 | return true; |
| 605 | 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 | 641 | if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v)) |
| 646 | 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 | 645 | if (reg == LPAIF_HDMI_RDMACTL_REG(v, i)) |
| 650 | 646 | return true; |
| 651 | 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 | 668 | if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) |
| 673 | 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 | 672 | if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) |
| 677 | 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 | 678 | static struct regmap_config lpass_hdmi_regmap_config = { |
| 679 | + .name = "lpass_hdmi", | |
| 683 | 680 | .reg_bits = 32, |
| 684 | 681 | .reg_stride = 4, |
| 685 | 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 | 746 | if (id == LPASS_DP_RX) { |
| 750 | 747 | data->hdmi_port_enable = 1; |
| 751 | − dev_err(dev, "HDMI Port is enabled: %d\n", id); | |
| 752 | 748 | } else { |
| 753 | 749 | data->mi2s_playback_sd_mode[id] = |
| 754 | 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 | 789 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); |
| 794 | 790 | |
| 795 | 791 | drvdata->lpaif = devm_ioremap_resource(dev, res); |
| 796 | − if (IS_ERR((void const __force *)drvdata->lpaif)) { | |
| 797 | − dev_err(dev, "error mapping reg resource: %ld\n", | |
| 798 | − PTR_ERR((void const __force *)drvdata->lpaif)); | |
| 799 | − return PTR_ERR((void const __force *)drvdata->lpaif); | |
| 800 | − } | |
| 792 | + if (IS_ERR(drvdata->lpaif)) | |
| 793 | + return PTR_ERR(drvdata->lpaif); | |
| 801 | 794 | |
| 802 | 795 | lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, |
| 803 | 796 | variant->wrdma_channels + |
| @@ -815,14 +808,11 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 815 | 808 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif"); |
| 816 | 809 | |
| 817 | 810 | drvdata->hdmiif = devm_ioremap_resource(dev, res); |
| 818 | − if (IS_ERR((void const __force *)drvdata->hdmiif)) { | |
| 819 | − dev_err(dev, "error mapping reg resource: %ld\n", | |
| 820 | − PTR_ERR((void const __force *)drvdata->hdmiif)); | |
| 821 | − return PTR_ERR((void const __force *)drvdata->hdmiif); | |
| 822 | − } | |
| 811 | + if (IS_ERR(drvdata->hdmiif)) | |
| 812 | + return PTR_ERR(drvdata->hdmiif); | |
| 823 | 813 | |
| 824 | 814 | lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant, |
| 825 | − variant->hdmi_rdma_channels); | |
| 815 | + variant->hdmi_rdma_channels - 1); | |
| 826 | 816 | drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif, |
| 827 | 817 | &lpass_hdmi_regmap_config); |
| 828 | 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 | 856 | PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); |
| 867 | 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 | 861 | /* Allocation for i2sctl regmap fields */ |
| @@ -60,9 +60,6 @@ · 59 unmodified lines | ||
| 60 | 60 | #define LPAIF_I2SCTL_BITWIDTH_24 1 |
| 61 | 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 | 63 | #define LPAIF_I2SCTL_RESET_STATE 0x003C0004 |
| 67 | 64 | #define LPAIF_DMACTL_RESET_STATE 0x00200000 |
| 68 | 65 | |
| @@ -171,7 +171,7 @@ static struct lpass_variant sc7180_data = { · 170 unmodified lines | ||
| 171 | 171 | .rdma_channels = 5, |
| 172 | 172 | .hdmi_rdma_reg_base = 0x64000, |
| 173 | 173 | .hdmi_rdma_reg_stride = 0x1000, |
| 174 | − .hdmi_rdma_channels = 3, | |
| 174 | + .hdmi_rdma_channels = 4, | |
| 175 | 175 | .dmactl_audif_start = 1, |
| 176 | 176 | .wrdma_reg_base = 0x18000, |
| 177 | 177 | .wrdma_reg_stride = 0x1000, |
| @@ -68,7 +68,6 @@ struct lpass_data { · 67 unmodified lines | ||
| 68 | 68 | unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; |
| 69 | 69 | unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; |
| 70 | 70 | int hdmi_port_enable; |
| 71 | − int bit_clk_state[LPASS_MAX_MI2S_PORTS]; | |
| 72 | 71 | |
| 73 | 72 | /* low-power audio interface (LPAIF) registers */ |
| 74 | 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 | 1707 | pkt->hdr.token = hw_block_id; |
| 1708 | 1708 | pkt->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST; |
| 1709 | 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 | 1711 | sizeof(vote_cfg->client_name)); |
| 1712 | 1712 | |
| 1713 | 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 | 1255 | static const struct snd_soc_component_driver q6asm_fe_dai_component = { |
| 1237 | 1256 | .name = DRV_NAME, |
| 1238 | 1257 | .open = q6asm_dai_open, |
| @@ -1245,6 +1264,8 @@ static const struct snd_soc_component_driver q6asm_fe_dai_component = { · 6 unmodified lines | ||
| 1245 | 1264 | .pcm_construct = q6asm_dai_pcm_new, |
| 1246 | 1265 | .pcm_destruct = q6asm_dai_pcm_free, |
| 1247 | 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 | 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 | 492 | * @dir: direction of audio stream |
| 493 | 493 | * @ac: audio client instanace |
| 494 | − * @phys: physcial address that needs mapping. | |
| 494 | + * @phys: physical address that needs mapping. | |
| 495 | 495 | * @period_sz: audio period size |
| 496 | 496 | * @periods: number of periods |
| 497 | 497 | * |
| @@ -713,24 +713,6 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { · 712 unmodified lines | ||
| 713 | 713 | Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) }; |
| 714 | 714 | |
| 715 | 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 | 716 | /* Mixer definitions */ |
| 735 | 717 | SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0, |
| 736 | 718 | hdmi_mixer_controls, |
| @@ -373,7 +373,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, · 372 unmodified lines | ||
| 373 | 373 | I2S_DMACR_RDL(16)); |
| 374 | 374 | |
| 375 | 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 | 377 | val = I2S_CKR_TRCM_TXONLY; |
| 378 | 378 | |
| 379 | 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 | 471 | SNDRV_PCM_FMTBIT_S32_LE), |
| 472 | 472 | }, |
| 473 | 473 | .ops = &rockchip_i2s_dai_ops, |
| 474 | − .symmetric_rates = 1, | |
| 474 | + .symmetric_rate = 1, | |
| 475 | 475 | }; |
| 476 | 476 | |
| 477 | 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 | 338 | .formats = ROCKCHIP_PDM_FORMATS, |
| 339 | 339 | }, |
| 340 | 340 | .ops = &rockchip_pdm_dai_ops, |
| 341 | − .symmetric_rates = 1, | |
| 341 | + .symmetric_rate = 1, | |
| 342 | 342 | }; |
| 343 | 343 | |
| 344 | 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 | 1175 | dai_drv->probe = samsung_i2s_dai_probe; |
| 1176 | 1176 | dai_drv->remove = samsung_i2s_dai_remove; |
| 1177 | 1177 | |
| 1178 | − dai_drv->symmetric_rates = 1; | |
| 1178 | + dai_drv->symmetric_rate = 1; | |
| 1179 | 1179 | dai_drv->ops = &samsung_i2s_dai_ops; |
| 1180 | 1180 | |
| 1181 | 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 | 452 | #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 |
| 453 | 453 | |
| 454 | 454 | #define S3C_PCM_DAI_DECLARE \ |
| 455 | − .symmetric_rates = 1, \ | |
| 455 | + .symmetric_rate = 1, \ | |
| 456 | 456 | .probe = s3c_pcm_dai_probe, \ |
| 457 | 457 | .ops = &s3c_pcm_dai_ops, \ |
| 458 | 458 | .playback = { \ |
| @@ -1320,8 +1320,8 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, · 1319 unmodified lines | ||
| 1320 | 1320 | |
| 1321 | 1321 | if (rsnd_ssi_is_pin_sharing(io_capture) || |
| 1322 | 1322 | rsnd_ssi_is_pin_sharing(io_playback)) { |
| 1323 | − /* should have symmetric_rates if pin sharing */ | |
| 1324 | − drv->symmetric_rates = 1; | |
| 1323 | + /* should have symmetric_rate if pin sharing */ | |
| 1324 | + drv->symmetric_rate = 1; | |
| 1325 | 1325 | } |
| 1326 | 1326 | |
| 1327 | 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 | 1472 | uinfo->value.enumerated.items = cfg->max; |
| 1473 | 1473 | if (uinfo->value.enumerated.item >= cfg->max) |
| 1474 | 1474 | uinfo->value.enumerated.item = cfg->max - 1; |
| 1475 | − strlcpy(uinfo->value.enumerated.name, | |
| 1475 | + strscpy(uinfo->value.enumerated.name, | |
| 1476 | 1476 | cfg->texts[uinfo->value.enumerated.item], |
| 1477 | 1477 | sizeof(uinfo->value.enumerated.name)); |
| 1478 | 1478 | } else { |
| @@ -169,7 +169,7 @@ static inline u32 siu_read32(u32 __iomem *addr) · 168 unmodified lines | ||
| 169 | 169 | #define SIU_BRGBSEL (0x108 / sizeof(u32)) |
| 170 | 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 | 173 | extern struct siu_info *siu_i2s_data; |
| 174 | 174 | |
| 175 | 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 | 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 | 547 | .name = DRV_NAME, |
| 548 | 548 | .open = siu_pcm_open, |
| 549 | 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 | 11 | #include <linux/module.h> |
| 12 | 12 | #include <linux/pm_runtime.h> |
| 13 | 13 | #include <sound/soc.h> |
| 14 | +#include <linux/bitops.h> | |
| 14 | 15 | |
| 15 | 16 | #define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret) |
| 16 | 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 | 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 | 51 | * We might want to check substream by using list. |
| 39 | 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 | 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 | 897 | * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed |
| 844 | 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 | 2529 | struct snd_soc_dapm_widget *w; |
| 2530 | 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 | 2543 | for_each_card_widgets(dapm->card, w) { |
| 2533 | − if (!strcmp(w->name, pin)) { | |
| 2544 | + if (!strcmp(w->name, pin_name)) { | |
| 2534 | 2545 | if (w->dapm == dapm) |
| 2535 | 2546 | return w; |
| 2536 | 2547 | else |
| @@ -203,6 +203,34 @@ static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm) · 202 unmodified lines | ||
| 203 | 203 | } |
| 204 | 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 | 235 | * snd_soc_runtime_action() - Increment/Decrement active count for |
| 208 | 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 | 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 | 346 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, |
| 305 | 347 | struct snd_soc_dai *soc_dai) |
| 306 | 348 | { |
| 307 | 349 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 308 | 350 | int ret; |
| 309 | 351 | |
| 310 | − if (soc_dai->rate && (soc_dai->driver->symmetric_rates || | |
| 311 | − rtd->dai_link->symmetric_rates)) { | |
| 312 | − dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", | |
| 313 | − soc_dai->rate); | |
| 314 | − | |
| 315 | − ret = snd_pcm_hw_constraint_single(substream->runtime, | |
| 316 | − SNDRV_PCM_HW_PARAM_RATE, | |
| 317 | − soc_dai->rate); | |
| 318 | − if (ret < 0) { | |
| 319 | − dev_err(soc_dai->dev, | |
| 320 | − "ASoC: Unable to apply rate constraint: %d\n", | |
| 321 | − ret); | |
| 322 | − return ret; | |
| 323 | − } | |
| 324 | − } | |
| 325 | − | |
| 326 | − if (soc_dai->channels && (soc_dai->driver->symmetric_channels || | |
| 327 | − rtd->dai_link->symmetric_channels)) { | |
| 328 | − dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", | |
| 329 | − soc_dai->channels); | |
| 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 | − } | |
| 352 | +#define __soc_pcm_apply_symmetry(name, NAME) \ | |
| 353 | + if (soc_dai->name && (soc_dai->driver->symmetric_##name || \ | |
| 354 | + rtd->dai_link->symmetric_##name)) { \ | |
| 355 | + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %s to %d\n",\ | |
| 356 | + #name, soc_dai->name); \ | |
| 357 | + \ | |
| 358 | + ret = snd_pcm_hw_constraint_single(substream->runtime, \ | |
| 359 | + SNDRV_PCM_HW_PARAM_##NAME,\ | |
| 360 | + soc_dai->name); \ | |
| 361 | + if (ret < 0) { \ | |
| 362 | + dev_err(soc_dai->dev, \ | |
| 363 | + "ASoC: Unable to apply %s constraint: %d\n",\ | |
| 364 | + #name, ret); \ | |
| 365 | + return ret; \ | |
| 366 | + } \ | |
| 367 | + } | |
| 368 | + | |
| 369 | + __soc_pcm_apply_symmetry(rate, RATE); | |
| 370 | + __soc_pcm_apply_symmetry(channels, CHANNELS); | |
| 371 | + __soc_pcm_apply_symmetry(sample_bits, SAMPLE_BITS); | |
| 357 | 372 | |
| 358 | 373 | return 0; |
| 359 | 374 | } |
| @@ -362,61 +377,30 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 362 | 377 | struct snd_pcm_hw_params *params) |
| 363 | 378 | { |
| 364 | 379 | struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
| 380 | + struct snd_soc_dai d; | |
| 365 | 381 | struct snd_soc_dai *dai; |
| 366 | 382 | struct snd_soc_dai *cpu_dai; |
| 367 | − unsigned int rate, channels, sample_bits, 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; | |
| 383 | + unsigned int symmetry, i; | |
| 390 | 384 | |
| 391 | − for_each_rtd_dais(rtd, i, dai) | |
| 392 | − symmetry |= dai->driver->symmetric_channels; | |
| 393 | − | |
| 394 | − if (symmetry) { | |
| 395 | − for_each_rtd_cpu_dais(rtd, i, cpu_dai) { | |
| 396 | − if (cpu_dai->channels && | |
| 397 | − cpu_dai->channels != channels) { | |
| 398 | − dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", | |
| 399 | − cpu_dai->channels, channels); | |
| 400 | − return -EINVAL; | |
| 385 | + soc_pcm_set_dai_params(&d, params); | |
| 386 | + | |
| 387 | +#define __soc_pcm_params_symmetry(name) \ | |
| 388 | + symmetry = rtd->dai_link->symmetric_##name; \ | |
| 389 | + for_each_rtd_dais(rtd, i, dai) \ | |
| 390 | + symmetry |= dai->driver->symmetric_##name; \ | |
| 391 | + \ | |
| 392 | + if (symmetry) \ | |
| 393 | + for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ | |
| 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; | |
| 406 | − | |
| 407 | − for_each_rtd_dais(rtd, i, dai) | |
| 408 | − symmetry |= dai->driver->symmetric_samplebits; | |
| 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 | − } | |
| 400 | + /* reject unmatched parameters when applying symmetry */ | |
| 401 | + __soc_pcm_params_symmetry(rate); | |
| 402 | + __soc_pcm_params_symmetry(channels); | |
| 403 | + __soc_pcm_params_symmetry(sample_bits); | |
| 420 | 404 | |
| 421 | 405 | return 0; |
| 422 | 406 | } |
| @@ -428,15 +412,15 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) · 5 unmodified lines | ||
| 428 | 412 | struct snd_soc_dai *dai; |
| 429 | 413 | unsigned int symmetry, i; |
| 430 | 414 | |
| 431 | − symmetry = link->symmetric_rates || | |
| 415 | + symmetry = link->symmetric_rate || | |
| 432 | 416 | link->symmetric_channels || |
| 433 | − link->symmetric_samplebits; | |
| 417 | + link->symmetric_sample_bits; | |
| 434 | 418 | |
| 435 | 419 | for_each_rtd_dais(rtd, i, dai) |
| 436 | 420 | symmetry = symmetry || |
| 437 | − dai->driver->symmetric_rates || | |
| 421 | + dai->driver->symmetric_rate || | |
| 438 | 422 | dai->driver->symmetric_channels || |
| 439 | − dai->driver->symmetric_samplebits; | |
| 423 | + dai->driver->symmetric_sample_bits; | |
| 440 | 424 | |
| 441 | 425 | return symmetry; |
| 442 | 426 | } |
| @@ -489,6 +473,42 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) · 46 unmodified lines | ||
| 489 | 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 | 513 | * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream |
| 494 | 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 | 525 | struct snd_soc_dai *cpu_dai; |
| 506 | 526 | struct snd_soc_pcm_stream *codec_stream; |
| 507 | 527 | struct snd_soc_pcm_stream *cpu_stream; |
| 508 | − unsigned int chan_min = 0, chan_max = UINT_MAX; | |
| 509 | 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 | 529 | int i; |
| 515 | 530 | |
| 531 | + soc_pcm_hw_init(hw); | |
| 532 | + | |
| 516 | 533 | /* first calculate min/max only for CPUs in the DAI link */ |
| 517 | 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 | 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); | |
| 531 | − cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); | |
| 532 | − cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min); | |
| 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); | |
| 547 | + soc_pcm_hw_update_chan(hw, cpu_stream); | |
| 548 | + soc_pcm_hw_update_rate(hw, cpu_stream); | |
| 549 | + soc_pcm_hw_update_format(hw, cpu_stream); | |
| 537 | 550 | } |
| 551 | + cpu_chan_min = hw->channels_min; | |
| 552 | + cpu_chan_max = hw->channels_max; | |
| 538 | 553 | |
| 539 | 554 | /* second calculate min/max only for CODECs in the DAI link */ |
| 540 | 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 | 566 | codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream); |
| 552 | 567 | |
| 553 | − chan_min = max(chan_min, codec_stream->channels_min); | |
| 554 | − chan_max = min(chan_max, codec_stream->channels_max); | |
| 555 | − rate_min = max(rate_min, codec_stream->rate_min); | |
| 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); | |
| 568 | + soc_pcm_hw_update_chan(hw, codec_stream); | |
| 569 | + soc_pcm_hw_update_rate(hw, codec_stream); | |
| 570 | + soc_pcm_hw_update_format(hw, codec_stream); | |
| 559 | 571 | } |
| 560 | 572 | |
| 561 | 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 | 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 | 580 | * channel allocation be fixed up later |
| 569 | 581 | */ |
| 570 | 582 | if (rtd->num_codecs > 1) { |
| 571 | − chan_min = cpu_chan_min; | |
| 572 | − chan_max = cpu_chan_max; | |
| 583 | + hw->channels_min = cpu_chan_min; | |
| 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 | 587 | return 0; |
| 589 | 588 | } |
| 590 | 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 | 869 | for_each_rtd_dais(rtd, i, dai) { |
| 871 | 870 | int active = snd_soc_dai_stream_active(dai, substream->stream); |
| 872 | 871 | |
| 873 | − if (snd_soc_dai_active(dai) == 1) { | |
| 874 | − dai->rate = 0; | |
| 875 | − dai->channels = 0; | |
| 876 | − dai->sample_bits = 0; | |
| 877 | − } | |
| 872 | + if (snd_soc_dai_active(dai) == 1) | |
| 873 | + soc_pcm_set_dai_params(dai, NULL); | |
| 878 | 874 | |
| 879 | 875 | if (active == 1) |
| 880 | 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 | 967 | if(ret < 0) |
| 972 | 968 | goto out; |
| 973 | 969 | |
| 974 | − codec_dai->rate = params_rate(&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 | − | |
| 970 | + soc_pcm_set_dai_params(codec_dai, &codec_params); | |
| 979 | 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 | 984 | goto out; |
| 993 | 985 | |
| 994 | 986 | /* store the parameters for each DAI */ |
| 995 | − cpu_dai->rate = params_rate(params); | |
| 996 | − cpu_dai->channels = params_channels(params); | |
| 997 | − cpu_dai->sample_bits = | |
| 998 | − snd_pcm_format_physical_width(params_format(params)); | |
| 999 | − | |
| 987 | + soc_pcm_set_dai_params(cpu_dai, params); | |
| 1000 | 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 | 1323 | stream ? "capture" : "playback", |
| 1336 | 1324 | dpcm->be->dai_link->name, fe->dai_link->name); |
| 1337 | 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 | 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 | 1359 | /* is there a valid BE rtd for this widget */ |
| 1372 | 1360 | be = dpcm_get_be(card, widget, stream); |
| 1373 | 1361 | if (!be) { |
| 1374 | − dev_err(fe->dev, "ASoC: no BE found for %s\n", | |
| 1375 | − widget->name); | |
| 1362 | + dev_dbg(fe->dev, "ASoC: no BE found for %s\n", | |
| 1363 | + widget->name); | |
| 1376 | 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 | 1378 | continue; |
| 1391 | 1379 | |
| 1392 | 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 | 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 | 1407 | spin_lock_irqsave(&fe->card->dpcm_lock, flags); |
| 1420 | 1408 | for_each_dpcm_be(fe, stream, dpcm) |
| 1421 | − dpcm->be->dpcm[stream].runtime_update = | |
| 1422 | − SND_SOC_DPCM_UPDATE_NO; | |
| 1409 | + dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_NO); | |
| 1423 | 1410 | spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); |
| 1424 | 1411 | } |
| 1425 | 1412 | |
| @@ -1542,21 +1529,21 @@ unwind: · 116 unmodified lines | ||
| 1542 | 1529 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, |
| 1543 | 1530 | struct snd_soc_pcm_stream *stream) |
| 1544 | 1531 | { |
| 1545 | − runtime->hw.rate_min = stream->rate_min; | |
| 1546 | − runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); | |
| 1547 | − runtime->hw.channels_min = stream->channels_min; | |
| 1548 | − runtime->hw.channels_max = stream->channels_max; | |
| 1532 | + struct snd_pcm_hardware *hw = &runtime->hw; | |
| 1533 | + | |
| 1534 | + soc_pcm_hw_update_rate(hw, stream); | |
| 1535 | + soc_pcm_hw_update_chan(hw, stream); | |
| 1549 | 1536 | if (runtime->hw.formats) |
| 1550 | 1537 | runtime->hw.formats &= stream->formats; |
| 1551 | 1538 | else |
| 1552 | 1539 | runtime->hw.formats = stream->formats; |
| 1553 | − runtime->hw.rates = stream->rates; | |
| 1554 | 1540 | } |
| 1555 | 1541 | |
| 1556 | 1542 | static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, |
| 1557 | − u64 *formats) | |
| 1543 | + struct snd_pcm_runtime *runtime) | |
| 1558 | 1544 | { |
| 1559 | 1545 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1546 | + struct snd_pcm_hardware *hw = &runtime->hw; | |
| 1560 | 1547 | struct snd_soc_dpcm *dpcm; |
| 1561 | 1548 | struct snd_soc_dai *dai; |
| 1562 | 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 | 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 | 1579 | static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, |
| 1593 | − unsigned int *channels_min, | |
| 1594 | − unsigned int *channels_max) | |
| 1580 | + struct snd_pcm_runtime *runtime) | |
| 1595 | 1581 | { |
| 1596 | 1582 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1583 | + struct snd_pcm_hardware *hw = &runtime->hw; | |
| 1597 | 1584 | struct snd_soc_dpcm *dpcm; |
| 1598 | 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 | 1610 | cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); |
| 1624 | 1611 | |
| 1625 | − *channels_min = max(*channels_min, | |
| 1626 | − cpu_stream->channels_min); | |
| 1627 | − *channels_max = min(*channels_max, | |
| 1628 | − cpu_stream->channels_max); | |
| 1612 | + soc_pcm_hw_update_chan(hw, cpu_stream); | |
| 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 | 1619 | if (be->num_codecs == 1) { |
| 1636 | 1620 | codec_stream = snd_soc_dai_get_pcm_stream(asoc_rtd_to_codec(be, 0), stream); |
| 1637 | 1621 | |
| 1638 | − *channels_min = max(*channels_min, | |
| 1639 | − codec_stream->channels_min); | |
| 1640 | − *channels_max = min(*channels_max, | |
| 1641 | − codec_stream->channels_max); | |
| 1622 | + soc_pcm_hw_update_chan(hw, codec_stream); | |
| 1642 | 1623 | } |
| 1643 | 1624 | } |
| 1644 | 1625 | } |
| 1645 | 1626 | |
| 1646 | 1627 | static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, |
| 1647 | − unsigned int *rates, | |
| 1648 | − unsigned int *rate_min, | |
| 1649 | − unsigned int *rate_max) | |
| 1628 | + struct snd_pcm_runtime *runtime) | |
| 1650 | 1629 | { |
| 1651 | 1630 | struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(substream); |
| 1631 | + struct snd_pcm_hardware *hw = &runtime->hw; | |
| 1652 | 1632 | struct snd_soc_dpcm *dpcm; |
| 1653 | 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 | 1657 | pcm = snd_soc_dai_get_pcm_stream(dai, stream); |
| 1678 | 1658 | |
| 1679 | − *rate_min = max(*rate_min, pcm->rate_min); | |
| 1680 | − *rate_max = min_not_zero(*rate_max, pcm->rate_max); | |
| 1681 | − *rates = snd_pcm_rate_mask_intersect(*rates, pcm->rates); | |
| 1659 | + soc_pcm_hw_update_rate(hw, pcm); | |
| 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 | 1664 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) |
| 1687 | 1665 | { |
| 1688 | 1666 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1667 | + struct snd_pcm_hardware *hw = &runtime->hw; | |
| 1689 | 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.