Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'sound-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
"This became again a busy development cycle. There are few ALSA core
updates (merely API cleanups and sparse fixes), with the majority of
other changes are found in ASoC scene.

Here are some highlights:

ALSA core:
- More helper macros for sparse warning fixes (e.g. bitwise types)
- Slight optimization of PCM OSS locks
- Make common handling for PCM / compress buffers (for SOF)

ASoC:
- Lots of code refactoring and modernization for (still ongoing)
componentization works
- Conversion of SND_SOC_ALL_CODECS to use imply
- Continued refactoring and fixing of the Intel SOF/SST support,
including the initial (but still incomplete) SoundWire support
- SoundWire and more advanced clocking support for Realtek RT5682
- Support for amlogic GX, Meson 8, Meson 8B and T9015 DAC, Broadcom
DSL/PON, Ingenic JZ4760 and JZ4770, Realtek RL6231, and TI TAS2563
and TLV320ADCX140

HD-audio:
- Optimizations in HDMI jack handling
- A few new quirks and fixups for Realtek codecs

USB-audio:
- Delayed registration support
- New quirks for Motu, Kingston, Presonus"

* tag 'sound-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (415 commits)
ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra endpoint descriptor
Revert "ALSA: uapi: Drop asound.h inclusion from asoc.h"
ALSA: hda/realtek - Remove now-unnecessary XPS 13 headphone noise fixups
ALSA: hda/realtek - Set principled PC Beep configuration for ALC256
ALSA: doc: Document PC Beep Hidden Register on Realtek ALC256
ALSA: hda/realtek - a fake key event is triggered by running shutup
ALSA: hda: default enable CA0132 DSP support
ASoC: amd: acp3x-pcm-dma: clean up two indentation issues
ASoC: tlv320adcx140: Remove undocumented property
ASoC: Intel: sof_sdw: Add Volteer support with RT5682 SNDW helper function
ASoC: Intel: common: add match table for TGL RT5682 SoundWire driver
ASoC: Intel: boards: add sof_sdw machine driver
ASoC: Intel: soc-acpi: update topology and driver name for SoundWire platforms
ASoC: rt5682: move DAI clock registry to I2S mode
ASoC: pxa: magician: convert to use i2c_new_client_device()
ASoC: SOF: Intel: hda-ctrl: add reset cycle before parsing capabilities
Asoc: SOF: Intel: hda: check SoundWire wakeen interrupt in irq thread
ASoC: SOF: Intel: hda: add WAKEEN interrupt support for SoundWire
ASoC: SOF: Intel: hda: add parameter to control SoundWire clock stop quirks
ASoC: SOF: Intel: hda: merge IPC, stream and SoundWire interrupt handlers
...

+19015 -4294
+113
Documentation/devicetree/bindings/sound/amlogic,aiu.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/amlogic,aiu.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Amlogic AIU audio output controller 8 + 9 + maintainers: 10 + - Jerome Brunet <jbrunet@baylibre.com> 11 + 12 + properties: 13 + $nodename: 14 + pattern: "^audio-controller@.*" 15 + 16 + "#sound-dai-cells": 17 + const: 2 18 + 19 + compatible: 20 + items: 21 + - enum: 22 + - amlogic,aiu-gxbb 23 + - amlogic,aiu-gxl 24 + - amlogic,aiu-meson8 25 + - amlogic,aiu-meson8b 26 + - const: 27 + amlogic,aiu 28 + 29 + clocks: 30 + items: 31 + - description: AIU peripheral clock 32 + - description: I2S peripheral clock 33 + - description: I2S output clock 34 + - description: I2S master clock 35 + - description: I2S mixer clock 36 + - description: SPDIF peripheral clock 37 + - description: SPDIF output clock 38 + - description: SPDIF master clock 39 + - description: SPDIF master clock multiplexer 40 + 41 + clock-names: 42 + items: 43 + - const: pclk 44 + - const: i2s_pclk 45 + - const: i2s_aoclk 46 + - const: i2s_mclk 47 + - const: i2s_mixer 48 + - const: spdif_pclk 49 + - const: spdif_aoclk 50 + - const: spdif_mclk 51 + - const: spdif_mclk_sel 52 + 53 + interrupts: 54 + items: 55 + - description: I2S interrupt line 56 + - description: SPDIF interrupt line 57 + 58 + interrupt-names: 59 + items: 60 + - const: i2s 61 + - const: spdif 62 + 63 + reg: 64 + maxItems: 1 65 + 66 + resets: 67 + maxItems: 1 68 + 69 + required: 70 + - "#sound-dai-cells" 71 + - compatible 72 + - clocks 73 + - clock-names 74 + - interrupts 75 + - interrupt-names 76 + - reg 77 + - resets 78 + 79 + examples: 80 + - | 81 + #include <dt-bindings/clock/gxbb-clkc.h> 82 + #include <dt-bindings/interrupt-controller/irq.h> 83 + #include <dt-bindings/interrupt-controller/arm-gic.h> 84 + #include <dt-bindings/reset/amlogic,meson-gxbb-reset.h> 85 + 86 + aiu: audio-controller@5400 { 87 + compatible = "amlogic,aiu-gxl", "amlogic,aiu"; 88 + #sound-dai-cells = <2>; 89 + reg = <0x0 0x5400 0x0 0x2ac>; 90 + interrupts = <GIC_SPI 48 IRQ_TYPE_EDGE_RISING>, 91 + <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>; 92 + interrupt-names = "i2s", "spdif"; 93 + clocks = <&clkc CLKID_AIU_GLUE>, 94 + <&clkc CLKID_I2S_OUT>, 95 + <&clkc CLKID_AOCLK_GATE>, 96 + <&clkc CLKID_CTS_AMCLK>, 97 + <&clkc CLKID_MIXER_IFACE>, 98 + <&clkc CLKID_IEC958>, 99 + <&clkc CLKID_IEC958_GATE>, 100 + <&clkc CLKID_CTS_MCLK_I958>, 101 + <&clkc CLKID_CTS_I958>; 102 + clock-names = "pclk", 103 + "i2s_pclk", 104 + "i2s_aoclk", 105 + "i2s_mclk", 106 + "i2s_mixer", 107 + "spdif_pclk", 108 + "spdif_aoclk", 109 + "spdif_mclk", 110 + "spdif_mclk_sel"; 111 + resets = <&reset RESET_AIU>; 112 + }; 113 +
+51
Documentation/devicetree/bindings/sound/amlogic,g12a-toacodec.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/amlogic,g12a-toacodec.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Amlogic G12a Internal DAC Control Glue 8 + 9 + maintainers: 10 + - Jerome Brunet <jbrunet@baylibre.com> 11 + 12 + properties: 13 + $nodename: 14 + pattern: "^audio-controller@.*" 15 + 16 + "#sound-dai-cells": 17 + const: 1 18 + 19 + compatible: 20 + oneOf: 21 + - items: 22 + - const: 23 + amlogic,g12a-toacodec 24 + - items: 25 + - enum: 26 + - amlogic,sm1-toacodec 27 + - const: 28 + amlogic,g12a-toacodec 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + resets: 34 + maxItems: 1 35 + 36 + required: 37 + - "#sound-dai-cells" 38 + - compatible 39 + - reg 40 + - resets 41 + 42 + examples: 43 + - | 44 + #include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h> 45 + 46 + toacodec: audio-controller@740 { 47 + compatible = "amlogic,g12a-toacodec"; 48 + reg = <0x0 0x740 0x0 0x4>; 49 + #sound-dai-cells = <1>; 50 + resets = <&clkc_audio AUD_RESET_TOACODEC>; 51 + };
+113
Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/amlogic,gx-sound-card.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Amlogic GX sound card 8 + 9 + maintainers: 10 + - Jerome Brunet <jbrunet@baylibre.com> 11 + 12 + properties: 13 + compatible: 14 + items: 15 + - const: amlogic,gx-sound-card 16 + 17 + audio-aux-devs: 18 + $ref: /schemas/types.yaml#/definitions/phandle-array 19 + description: list of auxiliary devices 20 + 21 + audio-routing: 22 + $ref: /schemas/types.yaml#/definitions/non-unique-string-array 23 + minItems: 2 24 + description: |- 25 + A list of the connections between audio components. Each entry is a 26 + pair of strings, the first being the connection's sink, the second 27 + being the connection's source. 28 + 29 + audio-widgets: 30 + $ref: /schemas/types.yaml#/definitions/non-unique-string-array 31 + minItems: 2 32 + description: |- 33 + A list off component DAPM widget. Each entry is a pair of strings, 34 + the first being the widget type, the second being the widget name 35 + 36 + model: 37 + $ref: /schemas/types.yaml#/definitions/string 38 + description: User specified audio sound card name 39 + 40 + patternProperties: 41 + "^dai-link-[0-9]+$": 42 + type: object 43 + description: |- 44 + dai-link child nodes: 45 + Container for dai-link level properties and the CODEC sub-nodes. 46 + There should be at least one (and probably more) subnode of this type 47 + 48 + properties: 49 + dai-format: 50 + $ref: /schemas/types.yaml#/definitions/string 51 + enum: [ i2s, left-j, dsp_a ] 52 + 53 + mclk-fs: 54 + $ref: /schemas/types.yaml#/definitions/uint32 55 + description: |- 56 + Multiplication factor between the frame rate and master clock 57 + rate 58 + 59 + sound-dai: 60 + $ref: /schemas/types.yaml#/definitions/phandle 61 + description: phandle of the CPU DAI 62 + 63 + patternProperties: 64 + "^codec-[0-9]+$": 65 + type: object 66 + description: |- 67 + Codecs: 68 + dai-link representing backend links should have at least one subnode. 69 + One subnode for each codec of the dai-link. dai-link representing 70 + frontend links have no codec, therefore have no subnodes 71 + 72 + properties: 73 + sound-dai: 74 + $ref: /schemas/types.yaml#/definitions/phandle 75 + description: phandle of the codec DAI 76 + 77 + required: 78 + - sound-dai 79 + 80 + required: 81 + - sound-dai 82 + 83 + required: 84 + - model 85 + - dai-link-0 86 + 87 + examples: 88 + - | 89 + sound { 90 + compatible = "amlogic,gx-sound-card"; 91 + model = "GXL-ACME-S905X-FOO"; 92 + audio-aux-devs = <&amp>; 93 + audio-routing = "I2S ENCODER I2S IN", "I2S FIFO Playback"; 94 + 95 + dai-link-0 { 96 + sound-dai = <&i2s_fifo>; 97 + }; 98 + 99 + dai-link-1 { 100 + sound-dai = <&i2s_encoder>; 101 + dai-format = "i2s"; 102 + mclk-fs = <256>; 103 + 104 + codec-0 { 105 + sound-dai = <&codec0>; 106 + }; 107 + 108 + codec-1 { 109 + sound-dai = <&codec1>; 110 + }; 111 + }; 112 + }; 113 +
+58
Documentation/devicetree/bindings/sound/amlogic,t9015.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/amlogic,t9015.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Amlogic T9015 Internal Audio DAC 8 + 9 + maintainers: 10 + - Jerome Brunet <jbrunet@baylibre.com> 11 + 12 + properties: 13 + $nodename: 14 + pattern: "^audio-controller@.*" 15 + 16 + "#sound-dai-cells": 17 + const: 0 18 + 19 + compatible: 20 + items: 21 + - const: amlogic,t9015 22 + 23 + clocks: 24 + items: 25 + - description: Peripheral clock 26 + 27 + clock-names: 28 + items: 29 + - const: pclk 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + resets: 35 + maxItems: 1 36 + 37 + required: 38 + - "#sound-dai-cells" 39 + - compatible 40 + - reg 41 + - clocks 42 + - clock-names 43 + - resets 44 + 45 + examples: 46 + - | 47 + #include <dt-bindings/clock/g12a-clkc.h> 48 + #include <dt-bindings/reset/amlogic,meson-g12a-reset.h> 49 + 50 + acodec: audio-controller@32000 { 51 + compatible = "amlogic,t9015"; 52 + reg = <0x0 0x32000 0x0 0x14>; 53 + #sound-dai-cells = <0>; 54 + clocks = <&clkc CLKID_AUDIO_CODEC>; 55 + clock-names = "pclk"; 56 + resets = <&reset RESET_AUDIO_CODEC>; 57 + }; 58 +
+29
Documentation/devicetree/bindings/sound/brcm,bcm63xx-audio.txt
··· 1 + Broadcom DSL/PON BCM63xx Audio I2S controller 2 + 3 + Required properties: 4 + - compatible: Should be "brcm,bcm63xx-i2s". 5 + - #address-cells: 32bit valued, 1 cell. 6 + - #size-cells: 32bit valued, 0 cell. 7 + - reg: Should contain audio registers location and length 8 + - interrupts: Should contain the interrupt for the controller. 9 + - clocks: Must contain an entry for each entry in clock-names. 10 + Please refer to clock-bindings.txt. 11 + - clock-names: One of each entry matching the clocks phandles list: 12 + - "i2sclk" (generated clock) Required. 13 + - "i2sosc" (fixed 200MHz clock) Required. 14 + 15 + (1) : The generated clock is required only when any of TX and RX 16 + works on Master Mode. 17 + (2) : The fixed 200MHz clock is from internal chip and always on 18 + 19 + Example: 20 + 21 + i2s: bcm63xx-i2s { 22 + #address-cells = <1>; 23 + #size-cells = <0>; 24 + compatible = "brcm,bcm63xx-i2s"; 25 + reg = <0xFF802080 0xFF>; 26 + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; 27 + clocks = <&i2sclk>, <&osc>; 28 + clock-names = "i2sclk","i2sosc"; 29 + };
+69
Documentation/devicetree/bindings/sound/cirrus,cs42l51.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/cirrus,cs42l51.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: CS42L51 audio codec DT bindings 8 + 9 + maintainers: 10 + - Olivier Moysan <olivier.moysan@st.com> 11 + 12 + properties: 13 + compatible: 14 + const: cirrus,cs42l51 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + "#sound-dai-cells": 20 + const: 0 21 + 22 + clocks: 23 + maxItems: 1 24 + 25 + clock-names: 26 + items: 27 + - const: MCLK 28 + 29 + reset-gpios: 30 + maxItems: 1 31 + 32 + VL-supply: 33 + description: phandle to voltage regulator of digital interface section 34 + 35 + VD-supply: 36 + description: phandle to voltage regulator of digital internal section 37 + 38 + VA-supply: 39 + description: phandle to voltage regulator of analog internal section 40 + 41 + VAHP-supply: 42 + description: phandle to voltage regulator of headphone 43 + 44 + required: 45 + - compatible 46 + - reg 47 + - "#sound-dai-cells" 48 + 49 + examples: 50 + - | 51 + #include <dt-bindings/gpio/gpio.h> 52 + i2c@0 { 53 + #address-cells = <1>; 54 + #size-cells = <0>; 55 + 56 + cs42l51@4a { 57 + compatible = "cirrus,cs42l51"; 58 + reg = <0x4a>; 59 + #sound-dai-cells = <0>; 60 + clocks = <&mclk_prov>; 61 + clock-names = "MCLK"; 62 + VL-supply = <&reg_audio>; 63 + VD-supply = <&reg_audio>; 64 + VA-supply = <&reg_audio>; 65 + VAHP-supply = <&reg_audio>; 66 + reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>; 67 + }; 68 + }; 69 + ...
-33
Documentation/devicetree/bindings/sound/cs42l51.txt
··· 1 - CS42L51 audio CODEC 2 - 3 - Required properties: 4 - 5 - - compatible : "cirrus,cs42l51" 6 - 7 - - reg : the I2C address of the device for I2C. 8 - 9 - Optional properties: 10 - - VL-supply, VD-supply, VA-supply, VAHP-supply: power supplies for the device, 11 - as covered in Documentation/devicetree/bindings/regulator/regulator.txt. 12 - 13 - - reset-gpios : GPIO specification for the reset pin. If specified, it will be 14 - deasserted before starting the communication with the codec. 15 - 16 - - clocks : a list of phandles + clock-specifiers, one for each entry in 17 - clock-names 18 - 19 - - clock-names : must contain "MCLK" 20 - 21 - Example: 22 - 23 - cs42l51: cs42l51@4a { 24 - compatible = "cirrus,cs42l51"; 25 - reg = <0x4a>; 26 - clocks = <&mclk_prov>; 27 - clock-names = "MCLK"; 28 - VL-supply = <&reg_audio>; 29 - VD-supply = <&reg_audio>; 30 - VA-supply = <&reg_audio>; 31 - VAHP-supply = <&reg_audio>; 32 - reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>; 33 - };
-44
Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt
··· 1 - Audio codec controlled by ChromeOS EC 2 - 3 - Google's ChromeOS EC codec is a digital mic codec provided by the 4 - Embedded Controller (EC) and is controlled via a host-command interface. 5 - 6 - An EC codec node should only be found as a sub-node of the EC node (see 7 - Documentation/devicetree/bindings/mfd/cros-ec.txt). 8 - 9 - Required properties: 10 - - compatible: Must contain "google,cros-ec-codec" 11 - - #sound-dai-cells: Should be 1. The cell specifies number of DAIs. 12 - 13 - Optional properties: 14 - - reg: Pysical base address and length of shared memory region from EC. 15 - It contains 3 unsigned 32-bit integer. The first 2 integers 16 - combine to become an unsigned 64-bit physical address. The last 17 - one integer is length of the shared memory. 18 - - memory-region: Shared memory region to EC. A "shared-dma-pool". See 19 - ../reserved-memory/reserved-memory.txt for details. 20 - 21 - Example: 22 - 23 - { 24 - ... 25 - 26 - reserved_mem: reserved_mem { 27 - compatible = "shared-dma-pool"; 28 - reg = <0 0x52800000 0 0x100000>; 29 - no-map; 30 - }; 31 - } 32 - 33 - cros-ec@0 { 34 - compatible = "google,cros-ec-spi"; 35 - 36 - ... 37 - 38 - cros_ec_codec: ec-codec { 39 - compatible = "google,cros-ec-codec"; 40 - #sound-dai-cells = <1>; 41 - reg = <0x0 0x10500000 0x80000>; 42 - memory-region = <&reserved_mem>; 43 - }; 44 - };
+67
Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/google,cros-ec-codec.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Audio codec controlled by ChromeOS EC 8 + 9 + maintainers: 10 + - Cheng-Yi Chiang <cychiang@chromium.org> 11 + 12 + description: | 13 + Google's ChromeOS EC codec is a digital mic codec provided by the 14 + Embedded Controller (EC) and is controlled via a host-command interface. 15 + An EC codec node should only be found as a sub-node of the EC node (see 16 + Documentation/devicetree/bindings/mfd/cros-ec.txt). 17 + 18 + properties: 19 + compatible: 20 + const: google,cros-ec-codec 21 + 22 + "#sound-dai-cells": 23 + const: 1 24 + 25 + reg: 26 + items: 27 + - description: | 28 + Physical base address and length of shared memory region from EC. 29 + It contains 3 unsigned 32-bit integer. The first 2 integers 30 + combine to become an unsigned 64-bit physical address. 31 + The last one integer is the length of the shared memory. 32 + 33 + memory-region: 34 + $ref: '/schemas/types.yaml#/definitions/phandle' 35 + description: | 36 + Shared memory region to EC. A "shared-dma-pool". 37 + See ../reserved-memory/reserved-memory.txt for details. 38 + 39 + required: 40 + - compatible 41 + - '#sound-dai-cells' 42 + 43 + additionalProperties: false 44 + 45 + examples: 46 + - | 47 + reserved_mem: reserved-mem@52800000 { 48 + compatible = "shared-dma-pool"; 49 + reg = <0x52800000 0x100000>; 50 + no-map; 51 + }; 52 + spi { 53 + #address-cells = <1>; 54 + #size-cells = <0>; 55 + cros-ec@0 { 56 + compatible = "google,cros-ec-spi"; 57 + #address-cells = <2>; 58 + #size-cells = <1>; 59 + reg = <0>; 60 + cros_ec_codec: ec-codec@10500000 { 61 + compatible = "google,cros-ec-codec"; 62 + #sound-dai-cells = <1>; 63 + reg = <0x0 0x10500000 0x80000>; 64 + memory-region = <&reserved_mem>; 65 + }; 66 + }; 67 + };
+92
Documentation/devicetree/bindings/sound/ingenic,aic.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/ingenic,aic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Ingenic SoCs AC97 / I2S Controller (AIC) DT bindings 8 + 9 + maintainers: 10 + - Paul Cercueil <paul@crapouillou.net> 11 + 12 + properties: 13 + $nodename: 14 + pattern: '^audio-controller@' 15 + 16 + compatible: 17 + oneOf: 18 + - enum: 19 + - ingenic,jz4740-i2s 20 + - ingenic,jz4760-i2s 21 + - ingenic,jz4770-i2s 22 + - ingenic,jz4780-i2s 23 + - items: 24 + - const: ingenic,jz4725b-i2s 25 + - const: ingenic,jz4740-i2s 26 + 27 + '#sound-dai-cells': 28 + const: 0 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + interrupts: 34 + maxItems: 1 35 + 36 + clocks: 37 + items: 38 + - description: AIC clock 39 + - description: I2S clock 40 + - description: EXT clock 41 + - description: PLL/2 clock 42 + 43 + clock-names: 44 + items: 45 + - const: aic 46 + - const: i2s 47 + - const: ext 48 + - const: pll half 49 + 50 + dmas: 51 + items: 52 + - description: DMA controller phandle and request line for I2S RX 53 + - description: DMA controller phandle and request line for I2S TX 54 + 55 + dma-names: 56 + items: 57 + - const: rx 58 + - const: tx 59 + 60 + additionalProperties: false 61 + 62 + required: 63 + - compatible 64 + - reg 65 + - interrupts 66 + - clocks 67 + - clock-names 68 + - dmas 69 + - dma-names 70 + - '#sound-dai-cells' 71 + 72 + examples: 73 + - | 74 + #include <dt-bindings/clock/jz4740-cgu.h> 75 + aic: audio-controller@10020000 { 76 + compatible = "ingenic,jz4740-i2s"; 77 + reg = <0x10020000 0x38>; 78 + 79 + #sound-dai-cells = <0>; 80 + 81 + interrupt-parent = <&intc>; 82 + interrupts = <18>; 83 + 84 + clocks = <&cgu JZ4740_CLK_AIC>, 85 + <&cgu JZ4740_CLK_I2S>, 86 + <&cgu JZ4740_CLK_EXT>, 87 + <&cgu JZ4740_CLK_PLL_HALF>; 88 + clock-names = "aic", "i2s", "ext", "pll half"; 89 + 90 + dmas = <&dmac 25 0xffffffff>, <&dmac 24 0xffffffff>; 91 + dma-names = "rx", "tx"; 92 + };
-23
Documentation/devicetree/bindings/sound/ingenic,jz4740-i2s.txt
··· 1 - Ingenic JZ4740 I2S controller 2 - 3 - Required properties: 4 - - compatible : "ingenic,jz4740-i2s" or "ingenic,jz4780-i2s" 5 - - reg : I2S registers location and length 6 - - clocks : AIC and I2S PLL clock specifiers. 7 - - clock-names: "aic" and "i2s" 8 - - dmas: DMA controller phandle and DMA request line for I2S Tx and Rx channels 9 - - dma-names: Must be "tx" and "rx" 10 - 11 - Example: 12 - 13 - i2s: i2s@10020000 { 14 - compatible = "ingenic,jz4740-i2s"; 15 - reg = <0x10020000 0x94>; 16 - 17 - clocks = <&cgu JZ4740_CLK_AIC>, <&cgu JZ4740_CLK_I2SPLL>; 18 - clock-names = "aic", "i2s"; 19 - 20 - dmas = <&dma 2>, <&dma 3>; 21 - dma-names = "tx", "rx"; 22 - 23 - };
+1
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt
··· 18 18 * Headphone Jack 19 19 * Int Spk 20 20 * Mic Jack 21 + * Int Mic 21 22 22 23 - nvidia,i2s-controller : The phandle of the Tegra I2S1 controller 23 24 - nvidia,audio-codec : The phandle of the WM8903 audio codec
+6 -1
Documentation/devicetree/bindings/sound/rockchip,rk3328-codec.txt
··· 10 10 - clock-names: should be "pclk". 11 11 - spk-depop-time-ms: speak depop time msec. 12 12 13 + Optional properties: 14 + 15 + - mute-gpios: GPIO specifier for external line driver control (typically the 16 + dedicated GPIO_MUTE pin) 17 + 13 18 Example for rk3328 internal codec: 14 19 15 20 codec: codec@ff410000 { ··· 23 18 rockchip,grf = <&grf>; 24 19 clocks = <&cru PCLK_ACODEC>; 25 20 clock-names = "pclk"; 21 + mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; 26 22 spk-depop-time-ms = 100; 27 - status = "disabled"; 28 23 };
-49
Documentation/devicetree/bindings/sound/rockchip-i2s.txt
··· 1 - * Rockchip I2S controller 2 - 3 - The I2S bus (Inter-IC sound bus) is a serial link for digital 4 - audio data transfer between devices in the system. 5 - 6 - Required properties: 7 - 8 - - compatible: should be one of the following: 9 - - "rockchip,rk3066-i2s": for rk3066 10 - - "rockchip,px30-i2s", "rockchip,rk3066-i2s": for px30 11 - - "rockchip,rk3036-i2s", "rockchip,rk3066-i2s": for rk3036 12 - - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 13 - - "rockchip,rk3228-i2s", "rockchip,rk3066-i2s": for rk3228 14 - - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 15 - - "rockchip,rk3328-i2s", "rockchip,rk3066-i2s": for rk3328 16 - - "rockchip,rk3366-i2s", "rockchip,rk3066-i2s": for rk3366 17 - - "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368 18 - - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 19 - - reg: physical base address of the controller and length of memory mapped 20 - region. 21 - - interrupts: should contain the I2S interrupt. 22 - - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, 23 - Documentation/devicetree/bindings/dma/dma.txt 24 - - dma-names: should include "tx" and "rx". 25 - - clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names. 26 - - clock-names: should contain the following: 27 - - "i2s_hclk": clock for I2S BUS 28 - - "i2s_clk" : clock for I2S controller 29 - - rockchip,playback-channels: max playback channels, if not set, 8 channels default. 30 - - rockchip,capture-channels: max capture channels, if not set, 2 channels default. 31 - 32 - Required properties for controller which support multi channels 33 - playback/capture: 34 - 35 - - rockchip,grf: the phandle of the syscon node for GRF register. 36 - 37 - Example for rk3288 I2S controller: 38 - 39 - i2s@ff890000 { 40 - compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; 41 - reg = <0xff890000 0x10000>; 42 - interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; 43 - dmas = <&pdma1 0>, <&pdma1 1>; 44 - dma-names = "tx", "rx"; 45 - clock-names = "i2s_hclk", "i2s_clk"; 46 - clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; 47 - rockchip,playback-channels = <8>; 48 - rockchip,capture-channels = <2>; 49 - };
+111
Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/rockchip-i2s.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rockchip I2S controller 8 + 9 + description: 10 + The I2S bus (Inter-IC sound bus) is a serial link for digital 11 + audio data transfer between devices in the system. 12 + 13 + maintainers: 14 + - Heiko Stuebner <heiko@sntech.de> 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - const: rockchip,rk3066-i2s 20 + - items: 21 + - enum: 22 + - rockchip,px30-i2s 23 + - rockchip,rk3036-i2s 24 + - rockchip,rk3188-i2s 25 + - rockchip,rk3228-i2s 26 + - rockchip,rk3288-i2s 27 + - rockchip,rk3328-i2s 28 + - rockchip,rk3366-i2s 29 + - rockchip,rk3368-i2s 30 + - rockchip,rk3399-i2s 31 + - const: rockchip,rk3066-i2s 32 + 33 + reg: 34 + maxItems: 1 35 + 36 + interrupts: 37 + maxItems: 1 38 + 39 + clocks: 40 + items: 41 + - description: clock for I2S controller 42 + - description: clock for I2S BUS 43 + 44 + clock-names: 45 + items: 46 + - const: i2s_clk 47 + - const: i2s_hclk 48 + 49 + dmas: 50 + items: 51 + - description: TX DMA Channel 52 + - description: RX DMA Channel 53 + 54 + dma-names: 55 + items: 56 + - const: tx 57 + - const: rx 58 + 59 + rockchip,capture-channels: 60 + allOf: 61 + - $ref: /schemas/types.yaml#/definitions/uint32 62 + default: 2 63 + description: 64 + Max capture channels, if not set, 2 channels default. 65 + 66 + rockchip,playback-channels: 67 + allOf: 68 + - $ref: /schemas/types.yaml#/definitions/uint32 69 + default: 8 70 + description: 71 + Max playback channels, if not set, 8 channels default. 72 + 73 + rockchip,grf: 74 + $ref: /schemas/types.yaml#/definitions/phandle 75 + description: 76 + The phandle of the syscon node for the GRF register. 77 + Required property for controllers which support multi channel 78 + playback/capture. 79 + 80 + "#sound-dai-cells": 81 + const: 0 82 + 83 + required: 84 + - compatible 85 + - reg 86 + - interrupts 87 + - clocks 88 + - clock-names 89 + - dmas 90 + - dma-names 91 + - "#sound-dai-cells" 92 + 93 + additionalProperties: false 94 + 95 + examples: 96 + - | 97 + #include <dt-bindings/clock/rk3288-cru.h> 98 + #include <dt-bindings/interrupt-controller/arm-gic.h> 99 + #include <dt-bindings/interrupt-controller/irq.h> 100 + i2s@ff890000 { 101 + compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; 102 + reg = <0xff890000 0x10000>; 103 + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; 104 + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>; 105 + clock-names = "i2s_clk", "i2s_hclk"; 106 + dmas = <&pdma1 0>, <&pdma1 1>; 107 + dma-names = "tx", "rx"; 108 + rockchip,capture-channels = <2>; 109 + rockchip,playback-channels = <8>; 110 + #sound-dai-cells = <0>; 111 + };
+18
Documentation/devicetree/bindings/sound/rt5682.txt
··· 32 32 The delay time is realtek,btndet-delay value multiple of 8.192 ms. 33 33 If absent, the default is 16. 34 34 35 + - #clock-cells : Should be set to '<1>', wclk and bclk sources provided. 36 + - clock-output-names : Name given for DAI clocks output. 37 + 38 + - clocks : phandle and clock specifier for codec MCLK. 39 + - clock-names : Clock name string for 'clocks' attribute, should be "mclk". 40 + 41 + - realtek,dmic-clk-rate-hz : Set the clock rate (hz) for the requirement of 42 + the particular DMIC. 43 + 44 + - realtek,dmic-delay-ms : Set the delay time (ms) for the requirement of 45 + the particular DMIC. 46 + 35 47 Pins on the device (for linking into audio routes) for RT5682: 36 48 37 49 * DMIC L1 ··· 65 53 realtek,dmic1-clk-pin = <1>; 66 54 realtek,jd-src = <1>; 67 55 realtek,btndet-delay = <16>; 56 + 57 + #clock-cells = <1>; 58 + clock-output-names = "rt5682-dai-wclk", "rt5682-dai-bclk"; 59 + 60 + clocks = <&osc>; 61 + clock-names = "mclk"; 68 62 };
-62
Documentation/devicetree/bindings/sound/st,stm32-i2s.txt
··· 1 - STMicroelectronics STM32 SPI/I2S Controller 2 - 3 - The SPI/I2S block supports I2S/PCM protocols when configured on I2S mode. 4 - Only some SPI instances support I2S. 5 - 6 - Required properties: 7 - - compatible: Must be "st,stm32h7-i2s" 8 - - reg: Offset and length of the device's register set. 9 - - interrupts: Must contain the interrupt line id. 10 - - clocks: Must contain phandle and clock specifier pairs for each entry 11 - in clock-names. 12 - - clock-names: Must contain "i2sclk", "pclk", "x8k" and "x11k". 13 - "i2sclk": clock which feeds the internal clock generator 14 - "pclk": clock which feeds the peripheral bus interface 15 - "x8k": I2S parent clock for sampling rates multiple of 8kHz. 16 - "x11k": I2S parent clock for sampling rates multiple of 11.025kHz. 17 - - dmas: DMA specifiers for tx and rx dma. 18 - See Documentation/devicetree/bindings/dma/stm32-dma.txt. 19 - - dma-names: Identifier for each DMA request line. Must be "tx" and "rx". 20 - - pinctrl-names: should contain only value "default" 21 - - pinctrl-0: see Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml 22 - 23 - Optional properties: 24 - - resets: Reference to a reset controller asserting the reset controller 25 - 26 - The device node should contain one 'port' child node with one child 'endpoint' 27 - node, according to the bindings defined in Documentation/devicetree/bindings/ 28 - graph.txt. 29 - 30 - Example: 31 - sound_card { 32 - compatible = "audio-graph-card"; 33 - dais = <&i2s2_port>; 34 - }; 35 - 36 - i2s2: audio-controller@40003800 { 37 - compatible = "st,stm32h7-i2s"; 38 - reg = <0x40003800 0x400>; 39 - interrupts = <36>; 40 - clocks = <&rcc PCLK1>, <&rcc SPI2_CK>, <&rcc PLL1_Q>, <&rcc PLL2_P>; 41 - clock-names = "pclk", "i2sclk", "x8k", "x11k"; 42 - dmas = <&dmamux2 2 39 0x400 0x1>, 43 - <&dmamux2 3 40 0x400 0x1>; 44 - dma-names = "rx", "tx"; 45 - pinctrl-names = "default"; 46 - pinctrl-0 = <&pinctrl_i2s2>; 47 - 48 - i2s2_port: port@0 { 49 - cpu_endpoint: endpoint { 50 - remote-endpoint = <&codec_endpoint>; 51 - format = "i2s"; 52 - }; 53 - }; 54 - }; 55 - 56 - audio-codec { 57 - codec_port: port@0 { 58 - codec_endpoint: endpoint { 59 - remote-endpoint = <&cpu_endpoint>; 60 - }; 61 - }; 62 - };
+87
Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/st,stm32-i2s.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics STM32 SPI/I2S Controller 8 + 9 + maintainers: 10 + - Olivier Moysan <olivier.moysan@st.com> 11 + 12 + description: 13 + The SPI/I2S block supports I2S/PCM protocols when configured on I2S mode. 14 + Only some SPI instances support I2S. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - st,stm32h7-i2s 20 + 21 + "#sound-dai-cells": 22 + const: 0 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + clocks: 28 + items: 29 + - description: clock feeding the peripheral bus interface. 30 + - description: clock feeding the internal clock generator. 31 + - description: I2S parent clock for sampling rates multiple of 8kHz. 32 + - description: I2S parent clock for sampling rates multiple of 11.025kHz. 33 + 34 + clock-names: 35 + items: 36 + - const: pclk 37 + - const: i2sclk 38 + - const: x8k 39 + - const: x11k 40 + 41 + interrupts: 42 + maxItems: 1 43 + 44 + dmas: 45 + items: 46 + - description: audio capture DMA. 47 + - description: audio playback DMA. 48 + 49 + dma-names: 50 + items: 51 + - const: rx 52 + - const: tx 53 + 54 + resets: 55 + maxItems: 1 56 + 57 + required: 58 + - compatible 59 + - "#sound-dai-cells" 60 + - reg 61 + - clocks 62 + - clock-names 63 + - interrupts 64 + - dmas 65 + - dma-names 66 + 67 + additionalProperties: false 68 + 69 + examples: 70 + - | 71 + #include <dt-bindings/interrupt-controller/arm-gic.h> 72 + #include <dt-bindings/clock/stm32mp1-clks.h> 73 + i2s2: audio-controller@4000b000 { 74 + compatible = "st,stm32h7-i2s"; 75 + #sound-dai-cells = <0>; 76 + reg = <0x4000b000 0x400>; 77 + clocks = <&rcc SPI2>, <&rcc SPI2_K>, <&rcc PLL3_Q>, <&rcc PLL3_R>; 78 + clock-names = "pclk", "i2sclk", "x8k", "x11k"; 79 + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; 80 + dmas = <&dmamux1 39 0x400 0x01>, 81 + <&dmamux1 40 0x400 0x01>; 82 + dma-names = "rx", "tx"; 83 + pinctrl-names = "default"; 84 + pinctrl-0 = <&i2s2_pins_a>; 85 + }; 86 + 87 + ...
-56
Documentation/devicetree/bindings/sound/st,stm32-spdifrx.txt
··· 1 - STMicroelectronics STM32 S/PDIF receiver (SPDIFRX). 2 - 3 - The SPDIFRX peripheral, is designed to receive an S/PDIF flow compliant with 4 - IEC-60958 and IEC-61937. 5 - 6 - Required properties: 7 - - compatible: should be "st,stm32h7-spdifrx" 8 - - reg: cpu DAI IP base address and size 9 - - clocks: must contain an entry for kclk (used as S/PDIF signal reference) 10 - - clock-names: must contain "kclk" 11 - - interrupts: cpu DAI interrupt line 12 - - dmas: DMA specifiers for audio data DMA and iec control flow DMA 13 - See STM32 DMA bindings, Documentation/devicetree/bindings/dma/st,stm32-dma.yaml 14 - - dma-names: two dmas have to be defined, "rx" and "rx-ctrl" 15 - 16 - Optional properties: 17 - - resets: Reference to a reset controller asserting the SPDIFRX 18 - 19 - The device node should contain one 'port' child node with one child 'endpoint' 20 - node, according to the bindings defined in Documentation/devicetree/bindings/ 21 - graph.txt. 22 - 23 - Example: 24 - spdifrx: spdifrx@40004000 { 25 - compatible = "st,stm32h7-spdifrx"; 26 - reg = <0x40004000 0x400>; 27 - clocks = <&rcc SPDIFRX_CK>; 28 - clock-names = "kclk"; 29 - interrupts = <97>; 30 - dmas = <&dmamux1 2 93 0x400 0x0>, 31 - <&dmamux1 3 94 0x400 0x0>; 32 - dma-names = "rx", "rx-ctrl"; 33 - pinctrl-0 = <&spdifrx_pins>; 34 - pinctrl-names = "default"; 35 - 36 - spdifrx_port: port { 37 - cpu_endpoint: endpoint { 38 - remote-endpoint = <&codec_endpoint>; 39 - }; 40 - }; 41 - }; 42 - 43 - spdif_in: spdif-in { 44 - compatible = "linux,spdif-dir"; 45 - 46 - codec_port: port { 47 - codec_endpoint: endpoint { 48 - remote-endpoint = <&cpu_endpoint>; 49 - }; 50 - }; 51 - }; 52 - 53 - soundcard { 54 - compatible = "audio-graph-card"; 55 - dais = <&spdifrx_port>; 56 - };
+80
Documentation/devicetree/bindings/sound/st,stm32-spdifrx.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/st,stm32-spdifrx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics STM32 S/PDIF receiver (SPDIFRX) 8 + 9 + maintainers: 10 + - Olivier Moysan <olivier.moysan@st.com> 11 + 12 + description: | 13 + The SPDIFRX peripheral, is designed to receive an S/PDIF flow compliant with 14 + IEC-60958 and IEC-61937. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - st,stm32h7-spdifrx 20 + 21 + "#sound-dai-cells": 22 + const: 0 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + clocks: 28 + maxItems: 1 29 + 30 + clock-names: 31 + items: 32 + - const: kclk 33 + 34 + interrupts: 35 + maxItems: 1 36 + 37 + dmas: 38 + items: 39 + - description: audio data capture DMA 40 + - description: IEC status bits capture DMA 41 + 42 + dma-names: 43 + items: 44 + - const: rx 45 + - const: rx-ctrl 46 + 47 + resets: 48 + maxItems: 1 49 + 50 + required: 51 + - compatible 52 + - "#sound-dai-cells" 53 + - reg 54 + - clocks 55 + - clock-names 56 + - interrupts 57 + - dmas 58 + - dma-names 59 + 60 + additionalProperties: false 61 + 62 + examples: 63 + - | 64 + #include <dt-bindings/interrupt-controller/arm-gic.h> 65 + #include <dt-bindings/clock/stm32mp1-clks.h> 66 + spdifrx: spdifrx@40004000 { 67 + compatible = "st,stm32h7-spdifrx"; 68 + #sound-dai-cells = <0>; 69 + reg = <0x40004000 0x400>; 70 + clocks = <&rcc SPDIF_K>; 71 + clock-names = "kclk"; 72 + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; 73 + dmas = <&dmamux1 2 93 0x400 0x0>, 74 + <&dmamux1 3 94 0x400 0x0>; 75 + dma-names = "rx", "rx-ctrl"; 76 + pinctrl-0 = <&spdifrx_pins>; 77 + pinctrl-names = "default"; 78 + }; 79 + 80 + ...
+1 -1
Documentation/devicetree/bindings/sound/tas2562.txt
··· 8 8 Required properties: 9 9 - #address-cells - Should be <1>. 10 10 - #size-cells - Should be <0>. 11 - - compatible: - Should contain "ti,tas2562". 11 + - compatible: - Should contain "ti,tas2562", "ti,tas2563". 12 12 - reg: - The i2c address. Should be 0x4c, 0x4d, 0x4e or 0x4f. 13 13 - ti,imon-slot-no:- TDM TX current sense time slot. 14 14
+82
Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) 2 + # Copyright (C) 2019 Texas Instruments Incorporated 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/sound/tlv320adcx140.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Texas Instruments TLV320ADCX140 Quad Channel Analog-to-Digital Converter 9 + 10 + maintainers: 11 + - Dan Murphy <dmurphy@ti.com> 12 + 13 + description: | 14 + The TLV320ADCX140 are multichannel (4-ch analog recording or 8-ch digital 15 + PDM microphones recording), high-performance audio, analog-to-digital 16 + converter (ADC) with analog inputs supporting up to 2V RMS. The TLV320ADCX140 17 + family supports line and microphone Inputs, and offers a programmable 18 + microphone bias or supply voltage generation. 19 + 20 + Specifications can be found at: 21 + http://www.ti.com/lit/ds/symlink/tlv320adc3140.pdf 22 + http://www.ti.com/lit/ds/symlink/tlv320adc5140.pdf 23 + http://www.ti.com/lit/ds/symlink/tlv320adc6140.pdf 24 + 25 + properties: 26 + compatible: 27 + oneOf: 28 + - const: ti,tlv320adc3140 29 + - const: ti,tlv320adc5140 30 + - const: ti,tlv320adc6140 31 + 32 + reg: 33 + maxItems: 1 34 + description: | 35 + I2C addresss of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f 36 + 37 + reset-gpios: 38 + description: | 39 + GPIO used for hardware reset. 40 + 41 + areg-supply: 42 + description: | 43 + Regulator with AVDD at 3.3V. If not defined then the internal regulator 44 + is enabled. 45 + 46 + ti,mic-bias-source: 47 + description: | 48 + Indicates the source for MIC Bias. 49 + 0 - Mic bias is set to VREF 50 + 1 - Mic bias is set to VREF × 1.096 51 + 6 - Mic bias is set to AVDD 52 + allOf: 53 + - $ref: /schemas/types.yaml#/definitions/uint32 54 + - enum: [0, 1, 6] 55 + 56 + ti,vref-source: 57 + description: | 58 + Indicates the source for MIC Bias. 59 + 0 - Set VREF to 2.75V 60 + 1 - Set VREF to 2.5V 61 + 2 - Set VREF to 1.375V 62 + allOf: 63 + - $ref: /schemas/types.yaml#/definitions/uint32 64 + - enum: [0, 1, 2] 65 + 66 + required: 67 + - compatible 68 + - reg 69 + 70 + examples: 71 + - | 72 + #include <dt-bindings/gpio/gpio.h> 73 + i2c0 { 74 + #address-cells = <1>; 75 + #size-cells = <0>; 76 + codec: codec@4c { 77 + compatible = "ti,tlv320adc5140"; 78 + reg = <0x4c>; 79 + ti,mic-bias-source = <6>; 80 + reset-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; 81 + }; 82 + };
+13
Documentation/sound/alsa-configuration.rst
··· 2234 2234 buffers. If mmap is used on such architectures, turn off this 2235 2235 option, so that the DMA-coherent buffers are allocated and used 2236 2236 instead. 2237 + delayed_register 2238 + The option is needed for devices that have multiple streams 2239 + defined in multiple USB interfaces. The driver may invoke 2240 + registrations multiple times (once per interface) and this may 2241 + lead to the insufficient device enumeration. 2242 + This option receives an array of strings, and you can pass 2243 + ID:INTERFACE like ``0123abcd:4`` for performing the delayed 2244 + registration to the given device. In this example, when a USB 2245 + device 0123:abcd is probed, the driver waits the registration 2246 + until the USB interface 4 gets probed. 2247 + The driver prints a message like "Found post-registration device 2248 + assignment: 1234abcd:04" for such a device, so that user can 2249 + notice the need. 2237 2250 2238 2251 This module supports multiple devices, autoprobe and hotplugging. 2239 2252
+1
Documentation/sound/hd-audio/index.rst
··· 8 8 models 9 9 controls 10 10 dp-mst 11 + realtek-pc-beep
-2
Documentation/sound/hd-audio/models.rst
··· 216 216 ALC298 fixups on Dell AIO machines 217 217 alc275-dell-xps 218 218 ALC275 fixups on Dell XPS models 219 - alc256-dell-xps13 220 - ALC256 fixups on Dell XPS13 221 219 lenovo-spk-noise 222 220 Workaround for speaker noise on Lenovo machines 223 221 lenovo-hotkey
+129
Documentation/sound/hd-audio/realtek-pc-beep.rst
··· 1 + =============================== 2 + Realtek PC Beep Hidden Register 3 + =============================== 4 + 5 + This file documents the "PC Beep Hidden Register", which is present in certain 6 + Realtek HDA codecs and controls a muxer and pair of passthrough mixers that can 7 + route audio between pins but aren't themselves exposed as HDA widgets. As far 8 + as I can tell, these hidden routes are designed to allow flexible PC Beep output 9 + for codecs that don't have mixer widgets in their output paths. Why it's easier 10 + to hide a mixer behind an undocumented vendor register than to just expose it 11 + as a widget, I have no idea. 12 + 13 + Register Description 14 + ==================== 15 + 16 + The register is accessed via processing coefficient 0x36 on NID 20h. Bits not 17 + identified below have no discernible effect on my machine, a Dell XPS 13 9350:: 18 + 19 + MSB LSB 20 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21 + | |h|S|L| | B |R| | Known bits 22 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 23 + |0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value 24 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 + 26 + 1Ah input select (B): 2 bits 27 + When zero, expose the PC Beep line (from the internal beep generator, when 28 + enabled with the Set Beep Generation verb on NID 01h, or else from the 29 + external PCBEEP pin) on the 1Ah pin node. When nonzero, expose the headphone 30 + jack (or possibly Line In on some machines) input instead. If PC Beep is 31 + selected, the 1Ah boost control has no effect. 32 + 33 + Amplify 1Ah loopback, left (L): 1 bit 34 + Amplify the left channel of 1Ah before mixing it into outputs as specified 35 + by h and S bits. Does not affect the level of 1Ah exposed to other widgets. 36 + 37 + Amplify 1Ah loopback, right (R): 1 bit 38 + Amplify the right channel of 1Ah before mixing it into outputs as specified 39 + by h and S bits. Does not affect the level of 1Ah exposed to other widgets. 40 + 41 + Loopback 1Ah to 21h [active low] (h): 1 bit 42 + When zero, mix 1Ah (possibly with amplification, depending on L and R bits) 43 + into 21h (headphone jack on my machine). Mixed signal respects the mute 44 + setting on 21h. 45 + 46 + Loopback 1Ah to 14h (S): 1 bit 47 + When one, mix 1Ah (possibly with amplification, depending on L and R bits) 48 + into 14h (internal speaker on my machine). Mixed signal **ignores** the mute 49 + setting on 14h and is present whenever 14h is configured as an output. 50 + 51 + Path diagrams 52 + ============= 53 + 54 + 1Ah input selection (DIV is the PC Beep divider set on NID 01h):: 55 + 56 + <Beep generator> <PCBEEP pin> <Headphone jack> 57 + | | | 58 + +--DIV--+--!DIV--+ {1Ah boost control} 59 + | | 60 + +--(b == 0)--+--(b != 0)--+ 61 + | 62 + >1Ah (Beep/Headphone Mic/Line In)< 63 + 64 + Loopback of 1Ah to 21h/14h:: 65 + 66 + <1Ah (Beep/Headphone Mic/Line In)> 67 + | 68 + {amplify if L/R} 69 + | 70 + +-----!h-----+-----S-----+ 71 + | | 72 + {21h mute control} | 73 + | | 74 + >21h (Headphone)< >14h (Internal Speaker)< 75 + 76 + Background 77 + ========== 78 + 79 + All Realtek HDA codecs have a vendor-defined widget with node ID 20h which 80 + provides access to a bank of registers that control various codec functions. 81 + Registers are read and written via the standard HDA processing coefficient 82 + verbs (Set/Get Coefficient Index, Set/Get Processing Coefficient). The node is 83 + named "Realtek Vendor Registers" in public datasheets' verb listings and, 84 + apart from that, is entirely undocumented. 85 + 86 + This particular register, exposed at coefficient 0x36 and named in commits from 87 + Realtek, is of note: unlike most registers, which seem to control detailed 88 + amplifier parameters not in scope of the HDA specification, it controls audio 89 + routing which could just as easily have been defined using standard HDA mixer 90 + and selector widgets. 91 + 92 + Specifically, it selects between two sources for the input pin widget with Node 93 + ID (NID) 1Ah: the widget's signal can come either from an audio jack (on my 94 + laptop, a Dell XPS 13 9350, it's the headphone jack, but comments in Realtek 95 + commits indicate that it might be a Line In on some machines) or from the PC 96 + Beep line (which is itself multiplexed between the codec's internal beep 97 + generator and external PCBEEP pin, depending on if the beep generator is 98 + enabled via verbs on NID 01h). Additionally, it can mix (with optional 99 + amplification) that signal onto the 21h and/or 14h output pins. 100 + 101 + The register's reset value is 0x3717, corresponding to PC Beep on 1Ah that is 102 + then amplified and mixed into both the headphones and the speakers. Not only 103 + does this violate the HDA specification, which says that "[a vendor defined 104 + beep input pin] connection may be maintained *only* while the Link reset 105 + (**RST#**) is asserted", it means that we cannot ignore the register if we care 106 + about the input that 1Ah would otherwise expose or if the PCBEEP trace is 107 + poorly shielded and picks up chassis noise (both of which are the case on my 108 + machine). 109 + 110 + Unfortunately, there are lots of ways to get this register configuration wrong. 111 + Linux, it seems, has gone through most of them. For one, the register resets 112 + after S3 suspend: judging by existing code, this isn't the case for all vendor 113 + registers, and it's led to some fixes that improve behavior on cold boot but 114 + don't last after suspend. Other fixes have successfully switched the 1Ah input 115 + away from PC Beep but have failed to disable both loopback paths. On my 116 + machine, this means that the headphone input is amplified and looped back to 117 + the headphone output, which uses the exact same pins! As you might expect, this 118 + causes terrible headphone noise, the character of which is controlled by the 119 + 1Ah boost control. (If you've seen instructions online to fix XPS 13 headphone 120 + noise by changing "Headphone Mic Boost" in ALSA, now you know why.) 121 + 122 + The information here has been obtained through black-box reverse engineering of 123 + the ALC256 codec's behavior and is not guaranteed to be correct. It likely 124 + also applies for the ALC255, ALC257, ALC235, and ALC236, since those codecs 125 + seem to be close relatives of the ALC256. (They all share one initialization 126 + function.) Additionally, other codecs like the ALC225 and ALC285 also have this 127 + register, judging by existing fixups in ``patch_realtek.c``, but specific 128 + data (e.g. node IDs, bit positions, pin mappings) for those codecs may differ 129 + from what I've described here.
+7 -2
Documentation/sound/soc/codec-to-codec.rst
··· 104 104 dai names ending with "Playback" and "Capture" respectively as dapm core 105 105 will link and power those dais based on the name. 106 106 107 - Note that in current device tree there is no way to mark a dai_link 108 - as codec to codec. However, it may change in future. 107 + A dai_link in a "simple-audio-card" will automatically be detected as 108 + codec to codec when all DAIs on the link belong to codec components. 109 + The dai_link will be initialized with the subset of stream parameters 110 + (channels, format, sample rate) supported by all DAIs on the link. Since 111 + there is no way to provide these parameters in the device tree, this is 112 + mostly useful for communication with simple fixed-function codecs, such 113 + as a Bluetooth controller or cellular modem.
+13 -2
MAINTAINERS
··· 4055 4055 F: sound/soc/codecs/cros_ec_codec.* 4056 4056 4057 4057 CIRRUS LOGIC AUDIO CODEC DRIVERS 4058 - M: Brian Austin <brian.austin@cirrus.com> 4059 - M: Paul Handrigan <Paul.Handrigan@cirrus.com> 4058 + M: James Schulman <james.schulman@cirrus.com> 4059 + M: David Rhodes <david.rhodes@cirrus.com> 4060 4060 L: alsa-devel@alsa-project.org (moderated for non-subscribers) 4061 4061 S: Maintained 4062 4062 F: sound/soc/codecs/cs* ··· 15749 15749 F: sound/soc/ 15750 15750 F: include/dt-bindings/sound/ 15751 15751 F: include/sound/soc* 15752 + 15753 + SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS 15754 + M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> 15755 + M: Liam Girdwood <lgirdwood@gmail.com> 15756 + M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 15757 + M: Kai Vehmanen <kai.vehmanen@linux.intel.com> 15758 + M: Daniel Baluta <daniel.baluta@nxp.com> 15759 + L: sound-open-firmware@alsa-project.org (moderated for non-subscribers) 15760 + W: https://github.com/thesofproject/linux/ 15761 + S: Supported 15762 + F: sound/soc/sof/ 15752 15763 15753 15764 SOUNDWIRE SUBSYSTEM 15754 15765 M: Vinod Koul <vkoul@kernel.org>
+48 -6
drivers/gpu/drm/mediatek/mtk_hdmi.c
··· 12 12 #include <linux/io.h> 13 13 #include <linux/kernel.h> 14 14 #include <linux/mfd/syscon.h> 15 + #include <linux/mutex.h> 15 16 #include <linux/of_platform.h> 16 17 #include <linux/of.h> 17 18 #include <linux/of_gpio.h> ··· 170 169 bool audio_enable; 171 170 bool powered; 172 171 bool enabled; 172 + hdmi_codec_plugged_cb plugged_cb; 173 + struct device *codec_dev; 174 + struct mutex update_plugged_status_lock; 173 175 }; 174 176 175 177 static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b) ··· 1198 1194 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]); 1199 1195 } 1200 1196 1197 + static enum drm_connector_status 1198 + mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi) 1199 + { 1200 + bool connected; 1201 + 1202 + mutex_lock(&hdmi->update_plugged_status_lock); 1203 + connected = mtk_cec_hpd_high(hdmi->cec_dev); 1204 + if (hdmi->plugged_cb && hdmi->codec_dev) 1205 + hdmi->plugged_cb(hdmi->codec_dev, connected); 1206 + mutex_unlock(&hdmi->update_plugged_status_lock); 1207 + 1208 + return connected ? 1209 + connector_status_connected : connector_status_disconnected; 1210 + } 1211 + 1201 1212 static enum drm_connector_status hdmi_conn_detect(struct drm_connector *conn, 1202 1213 bool force) 1203 1214 { 1204 1215 struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); 1205 - 1206 - return mtk_cec_hpd_high(hdmi->cec_dev) ? 1207 - connector_status_connected : connector_status_disconnected; 1216 + return mtk_hdmi_update_plugged_status(hdmi); 1208 1217 } 1209 1218 1210 1219 static void hdmi_conn_destroy(struct drm_connector *conn) ··· 1674 1657 return 0; 1675 1658 } 1676 1659 1660 + static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data, 1661 + hdmi_codec_plugged_cb fn, 1662 + struct device *codec_dev) 1663 + { 1664 + struct mtk_hdmi *hdmi = data; 1665 + 1666 + mutex_lock(&hdmi->update_plugged_status_lock); 1667 + hdmi->plugged_cb = fn; 1668 + hdmi->codec_dev = codec_dev; 1669 + mutex_unlock(&hdmi->update_plugged_status_lock); 1670 + 1671 + mtk_hdmi_update_plugged_status(hdmi); 1672 + 1673 + return 0; 1674 + } 1675 + 1677 1676 static const struct hdmi_codec_ops mtk_hdmi_audio_codec_ops = { 1678 1677 .hw_params = mtk_hdmi_audio_hw_params, 1679 1678 .audio_startup = mtk_hdmi_audio_startup, 1680 1679 .audio_shutdown = mtk_hdmi_audio_shutdown, 1681 1680 .digital_mute = mtk_hdmi_audio_digital_mute, 1682 1681 .get_eld = mtk_hdmi_audio_get_eld, 1682 + .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb, 1683 1683 }; 1684 1684 1685 - static void mtk_hdmi_register_audio_driver(struct device *dev) 1685 + static int mtk_hdmi_register_audio_driver(struct device *dev) 1686 1686 { 1687 + struct mtk_hdmi *hdmi = dev_get_drvdata(dev); 1687 1688 struct hdmi_codec_pdata codec_data = { 1688 1689 .ops = &mtk_hdmi_audio_codec_ops, 1689 1690 .max_i2s_channels = 2, 1690 1691 .i2s = 1, 1692 + .data = hdmi, 1691 1693 }; 1692 1694 struct platform_device *pdev; 1693 1695 ··· 1714 1678 PLATFORM_DEVID_AUTO, &codec_data, 1715 1679 sizeof(codec_data)); 1716 1680 if (IS_ERR(pdev)) 1717 - return; 1681 + return PTR_ERR(pdev); 1718 1682 1719 1683 DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME); 1684 + return 0; 1720 1685 } 1721 1686 1722 1687 static int mtk_drm_hdmi_probe(struct platform_device *pdev) ··· 1743 1706 return ret; 1744 1707 } 1745 1708 1709 + mutex_init(&hdmi->update_plugged_status_lock); 1746 1710 platform_set_drvdata(pdev, hdmi); 1747 1711 1748 1712 ret = mtk_hdmi_output_init(hdmi); ··· 1752 1714 return ret; 1753 1715 } 1754 1716 1755 - mtk_hdmi_register_audio_driver(dev); 1717 + ret = mtk_hdmi_register_audio_driver(dev); 1718 + if (ret) { 1719 + dev_err(dev, "Failed to register audio driver: %d\n", ret); 1720 + return ret; 1721 + } 1756 1722 1757 1723 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs; 1758 1724 hdmi->bridge.of_node = pdev->dev.of_node;
+4 -3
drivers/soundwire/qcom.c
··· 594 594 struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev); 595 595 struct snd_soc_pcm_runtime *rtd = substream->private_data; 596 596 struct sdw_stream_runtime *sruntime; 597 + struct snd_soc_dai *codec_dai; 597 598 int ret, i; 598 599 599 600 sruntime = sdw_alloc_stream(dai->name); ··· 603 602 604 603 ctrl->sruntime[dai->id] = sruntime; 605 604 606 - for (i = 0; i < rtd->num_codecs; i++) { 607 - ret = snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], sruntime, 605 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 606 + ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime, 608 607 substream->stream); 609 608 if (ret < 0 && ret != -ENOTSUPP) { 610 609 dev_err(dai->dev, "Failed to set sdw stream on %s", 611 - rtd->codec_dais[i]->name); 610 + codec_dai->name); 612 611 sdw_release_stream(sruntime); 613 612 return ret; 614 613 }
+9 -7
drivers/soundwire/stream.c
··· 167 167 return ret; 168 168 } 169 169 170 - /* Program DPN_BlockCtrl1 register */ 171 - ret = sdw_write(s_rt->slave, addr2, (p_params->bps - 1)); 172 - if (ret < 0) { 173 - dev_err(&s_rt->slave->dev, 174 - "DPN_BlockCtrl1 register write failed for port %d\n", 175 - t_params->port_num); 176 - return ret; 170 + if (!dpn_prop->read_only_wordlength) { 171 + /* Program DPN_BlockCtrl1 register */ 172 + ret = sdw_write(s_rt->slave, addr2, (p_params->bps - 1)); 173 + if (ret < 0) { 174 + dev_err(&s_rt->slave->dev, 175 + "DPN_BlockCtrl1 register write failed for port %d\n", 176 + t_params->port_num); 177 + return ret; 178 + } 177 179 } 178 180 179 181 /* Program DPN_SampleCtrl1 register */
+1 -1
drivers/spi/Kconfig
··· 575 575 576 576 config SPI_PXA2XX 577 577 tristate "PXA2xx SSP SPI master" 578 - depends on (ARCH_PXA || ARCH_MMP || PCI || ACPI) 578 + depends on ARCH_PXA || ARCH_MMP || PCI || ACPI || COMPILE_TEST 579 579 select PXA_SSP if ARCH_PXA || ARCH_MMP 580 580 help 581 581 This enables using a PXA2xx or Sodaville SSP port as a SPI master
+18
include/dt-bindings/sound/meson-aiu.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __DT_MESON_AIU_H 3 + #define __DT_MESON_AIU_H 4 + 5 + #define AIU_CPU 0 6 + #define AIU_HDMI 1 7 + #define AIU_ACODEC 2 8 + 9 + #define CPU_I2S_FIFO 0 10 + #define CPU_SPDIF_FIFO 1 11 + #define CPU_I2S_ENCODER 2 12 + #define CPU_SPDIF_ENCODER 3 13 + 14 + #define CTRL_I2S 0 15 + #define CTRL_PCM 1 16 + #define CTRL_OUT 2 17 + 18 + #endif /* __DT_MESON_AIU_H */
+10
include/dt-bindings/sound/meson-g12a-toacodec.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __DT_MESON_G12A_TOACODEC_H 3 + #define __DT_MESON_G12A_TOACODEC_H 4 + 5 + #define TOACODEC_IN_A 0 6 + #define TOACODEC_IN_B 1 7 + #define TOACODEC_IN_C 2 8 + #define TOACODEC_OUT 3 9 + 10 + #endif /* __DT_MESON_G12A_TOACODEC_H */
+2
include/linux/soundwire/sdw.h
··· 284 284 * @max_async_buffer: Number of samples that this port can buffer in 285 285 * asynchronous modes 286 286 * @block_pack_mode: Type of block port mode supported 287 + * @read_only_wordlength: Read Only wordlength field in DPN_BlockCtrl1 register 287 288 * @port_encoding: Payload Channel Sample encoding schemes supported 288 289 * @audio_modes: Audio modes supported 289 290 */ ··· 308 307 u32 modes; 309 308 u32 max_async_buffer; 310 309 bool block_pack_mode; 310 + bool read_only_wordlength; 311 311 u32 port_encoding; 312 312 struct sdw_dpn_audio_mode *audio_modes; 313 313 };
+12
include/linux/usb/audio-v2.h
··· 156 156 __u8 bmaControls[]; /* variable length */ 157 157 } __attribute__((packed)); 158 158 159 + /* 4.7.2.10 Effect Unit Descriptor */ 160 + 161 + struct uac2_effect_unit_descriptor { 162 + __u8 bLength; 163 + __u8 bDescriptorType; 164 + __u8 bDescriptorSubtype; 165 + __u8 bUnitID; 166 + __le16 wEffectType; 167 + __u8 bSourceID; 168 + __u8 bmaControls[]; /* variable length */ 169 + } __attribute__((packed)); 170 + 159 171 /* 4.9.2 Class-Specific AS Interface Descriptor */ 160 172 161 173 struct uac2_as_header_descriptor {
+30 -8
include/sound/compress_driver.h
··· 23 23 * struct snd_compr_runtime: runtime stream description 24 24 * @state: stream state 25 25 * @ops: pointer to DSP callbacks 26 - * @dma_buffer_p: runtime dma buffer pointer 27 26 * @buffer: pointer to kernel buffer, valid only when not in mmap mode or 28 27 * DSP doesn't implement copy 29 28 * @buffer_size: size of the above buffer ··· 33 34 * @total_bytes_transferred: cumulative bytes transferred by offload DSP 34 35 * @sleep: poll sleep 35 36 * @private_data: driver private data pointer 37 + * @dma_area: virtual buffer address 38 + * @dma_addr: physical buffer address (not accessible from main CPU) 39 + * @dma_bytes: size of DMA area 40 + * @dma_buffer_p: runtime dma buffer pointer 36 41 */ 37 42 struct snd_compr_runtime { 38 43 snd_pcm_state_t state; 39 44 struct snd_compr_ops *ops; 40 - struct snd_dma_buffer *dma_buffer_p; 41 45 void *buffer; 42 46 u64 buffer_size; 43 47 u32 fragment_size; ··· 49 47 u64 total_bytes_transferred; 50 48 wait_queue_head_t sleep; 51 49 void *private_data; 50 + 51 + unsigned char *dma_area; 52 + dma_addr_t dma_addr; 53 + size_t dma_bytes; 54 + struct snd_dma_buffer *dma_buffer_p; 52 55 }; 53 56 54 57 /** ··· 67 60 * @metadata_set: metadata set flag, true when set 68 61 * @next_track: has userspace signal next track transition, true when set 69 62 * @private_data: pointer to DSP private data 63 + * @dma_buffer: allocated buffer if any 70 64 */ 71 65 struct snd_compr_stream { 72 66 const char *name; ··· 79 71 bool metadata_set; 80 72 bool next_track; 81 73 void *private_data; 74 + struct snd_dma_buffer dma_buffer; 82 75 }; 83 76 84 77 /** ··· 189 180 190 181 /** 191 182 * snd_compr_set_runtime_buffer - Set the Compress runtime buffer 192 - * @substream: compress substream to set 183 + * @stream: compress stream to set 193 184 * @bufp: the buffer information, NULL to clear 194 185 * 195 186 * Copy the buffer information to runtime buffer when @bufp is non-NULL. 196 187 * Otherwise it clears the current buffer information. 197 188 */ 198 - static inline void snd_compr_set_runtime_buffer( 199 - struct snd_compr_stream *substream, 200 - struct snd_dma_buffer *bufp) 189 + static inline void 190 + snd_compr_set_runtime_buffer(struct snd_compr_stream *stream, 191 + struct snd_dma_buffer *bufp) 201 192 { 202 - struct snd_compr_runtime *runtime = substream->runtime; 193 + struct snd_compr_runtime *runtime = stream->runtime; 203 194 204 - runtime->dma_buffer_p = bufp; 195 + if (bufp) { 196 + runtime->dma_buffer_p = bufp; 197 + runtime->dma_area = bufp->area; 198 + runtime->dma_addr = bufp->addr; 199 + runtime->dma_bytes = bufp->bytes; 200 + } else { 201 + runtime->dma_buffer_p = NULL; 202 + runtime->dma_area = NULL; 203 + runtime->dma_addr = 0; 204 + runtime->dma_bytes = 0; 205 + } 205 206 } 207 + 208 + int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size); 209 + int snd_compr_free_pages(struct snd_compr_stream *stream); 206 210 207 211 int snd_compr_stop_error(struct snd_compr_stream *stream, 208 212 snd_pcm_state_t state);
+1
include/sound/core.h
··· 266 266 void snd_device_disconnect_all(struct snd_card *card); 267 267 void snd_device_free(struct snd_card *card, void *device_data); 268 268 void snd_device_free_all(struct snd_card *card); 269 + int snd_device_get_state(struct snd_card *card, void *device_data); 269 270 270 271 /* isadma.c */ 271 272
+2
include/sound/hdaudio.h
··· 513 513 struct snd_pcm_substream *substream; /* assigned substream, 514 514 * set in PCM open 515 515 */ 516 + struct snd_compr_stream *cstream; 516 517 unsigned int format_val; /* format value to be set in the 517 518 * controller and the codec 518 519 */ ··· 528 527 bool locked:1; 529 528 bool stripe:1; /* apply stripe control */ 530 529 530 + u64 curr_pos; 531 531 /* timestamp */ 532 532 unsigned long start_wallclk; /* start + minimum wallclk */ 533 533 unsigned long period_wallclk; /* wallclk for period */
+22 -1
include/sound/pcm.h
··· 644 644 #define snd_pcm_group_for_each_entry(s, substream) \ 645 645 list_for_each_entry(s, &substream->group->substreams, link_list) 646 646 647 + #define for_each_pcm_streams(stream) \ 648 + for (stream = SNDRV_PCM_STREAM_PLAYBACK; \ 649 + stream <= SNDRV_PCM_STREAM_LAST; \ 650 + stream++) 651 + 647 652 /** 648 653 * snd_pcm_running - Check whether the substream is in a running state 649 654 * @substream: substream to check ··· 1127 1122 return __snd_pcm_lib_xfer(substream, bufs, false, frames, true); 1128 1123 } 1129 1124 1130 - int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); 1125 + int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw); 1126 + 1127 + static inline int 1128 + snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) 1129 + { 1130 + return snd_pcm_hw_limit_rates(&runtime->hw); 1131 + } 1132 + 1131 1133 unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); 1132 1134 unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); 1133 1135 unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, ··· 1426 1414 { 1427 1415 return 1ULL << (__force int) pcm_format; 1428 1416 } 1417 + 1418 + /** 1419 + * pcm_for_each_format - helper to iterate for each format type 1420 + * @f: the iterator variable in snd_pcm_format_t type 1421 + */ 1422 + #define pcm_for_each_format(f) \ 1423 + for ((f) = SNDRV_PCM_FORMAT_FIRST; \ 1424 + (__force int)(f) <= (__force int)SNDRV_PCM_FORMAT_LAST; \ 1425 + (f) = (__force snd_pcm_format_t)((__force int)(f) + 1)) 1429 1426 1430 1427 /* printk helpers */ 1431 1428 #define pcm_err(pcm, fmt, args...) \
+7
include/sound/pcm_params.h
··· 133 133 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 134 134 } 135 135 136 + /* Most of drivers need only this one */ 137 + static inline int snd_mask_test_format(const struct snd_mask *mask, 138 + snd_pcm_format_t format) 139 + { 140 + return snd_mask_test(mask, (__force unsigned int)format); 141 + } 142 + 136 143 static inline int snd_mask_single(const struct snd_mask *mask) 137 144 { 138 145 int i, c = 0;
+10
include/sound/rt5682.h
··· 24 24 RT5682_JD1, 25 25 }; 26 26 27 + enum rt5682_dai_clks { 28 + RT5682_DAI_WCLK_IDX, 29 + RT5682_DAI_BCLK_IDX, 30 + RT5682_DAI_NUM_CLKS, 31 + }; 32 + 27 33 struct rt5682_platform_data { 28 34 29 35 int ldo1_en; /* GPIO for LDO1_EN */ ··· 38 32 enum rt5682_dmic1_clk_pin dmic1_clk_pin; 39 33 enum rt5682_jd_src jd_src; 40 34 unsigned int btndet_delay; 35 + unsigned int dmic_clk_rate; 36 + unsigned int dmic_delay; 37 + 38 + const char *dai_clk_names[RT5682_DAI_NUM_CLKS]; 41 39 }; 42 40 43 41 #endif
+33 -6
include/sound/soc-acpi.h
··· 75 75 }; 76 76 77 77 /** 78 - * snd_soc_acpi_link_adr: ACPI-based list of _ADR, with a variable 79 - * number of devices per link 80 - * 78 + * snd_soc_acpi_endpoint - endpoint descriptor 79 + * @num: endpoint number (mandatory, unique per device) 80 + * @aggregated: 0 (independent) or 1 (logically grouped) 81 + * @group_position: zero-based order (only when @aggregated is 1) 82 + * @group_id: platform-unique group identifier (only when @aggregrated is 1) 83 + */ 84 + struct snd_soc_acpi_endpoint { 85 + u8 num; 86 + u8 aggregated; 87 + u8 group_position; 88 + u8 group_id; 89 + }; 90 + 91 + /** 92 + * snd_soc_acpi_adr_device - descriptor for _ADR-enumerated device 93 + * @adr: 64 bit ACPI _ADR value 94 + * @num_endpoints: number of endpoints for this device 95 + * @endpoints: array of endpoints 96 + */ 97 + struct snd_soc_acpi_adr_device { 98 + const u64 adr; 99 + const u8 num_endpoints; 100 + const struct snd_soc_acpi_endpoint *endpoints; 101 + }; 102 + 103 + /** 104 + * snd_soc_acpi_link_adr - ACPI-based list of _ADR enumerated devices 81 105 * @mask: one bit set indicates the link this list applies to 82 - * @num_adr: ARRAY_SIZE of adr 83 - * @adr: array of _ADR (represented as u64). 106 + * @num_adr: ARRAY_SIZE of devices 107 + * @adr_d: array of devices 108 + * 109 + * The number of devices per link can be more than 1, e.g. in SoundWire 110 + * multi-drop configurations. 84 111 */ 85 112 86 113 struct snd_soc_acpi_link_adr { 87 114 const u32 mask; 88 115 const u32 num_adr; 89 - const u64 *adr; 116 + const struct snd_soc_acpi_adr_device *adr_d; 90 117 }; 91 118 92 119 /**
+41 -3
include/sound/soc-dai.h
··· 202 202 203 203 int (*set_sdw_stream)(struct snd_soc_dai *dai, 204 204 void *stream, int direction); 205 + void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction); 206 + 205 207 /* 206 208 * DAI digital mute - optional. 207 209 * Called by soc-core to minimise any pops. ··· 324 322 struct snd_soc_dai_driver *driver; 325 323 326 324 /* DAI runtime info */ 327 - unsigned int capture_active; /* stream usage count */ 328 - unsigned int playback_active; /* stream usage count */ 329 - unsigned int probed:1; 325 + unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1]; /* usage count */ 330 326 331 327 unsigned int active; 332 328 ··· 348 348 unsigned int rx_mask; 349 349 350 350 struct list_head list; 351 + 352 + /* bit field */ 353 + unsigned int probed:1; 354 + unsigned int started:1; 351 355 }; 356 + 357 + static inline struct snd_soc_pcm_stream * 358 + snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream) 359 + { 360 + return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? 361 + &dai->driver->playback : &dai->driver->capture; 362 + } 363 + 364 + static inline 365 + struct snd_soc_dapm_widget *snd_soc_dai_get_widget( 366 + struct snd_soc_dai *dai, int stream) 367 + { 368 + return (stream == SNDRV_PCM_STREAM_PLAYBACK) ? 369 + dai->playback_widget : dai->capture_widget; 370 + } 352 371 353 372 static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, 354 373 const struct snd_pcm_substream *ss) ··· 423 404 return dai->driver->ops->set_sdw_stream(dai, stream, direction); 424 405 else 425 406 return -ENOTSUPP; 407 + } 408 + 409 + /** 410 + * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI 411 + * @dai: DAI 412 + * @direction: Stream direction(Playback/Capture) 413 + * 414 + * This routine only retrieves that was previously configured 415 + * with snd_soc_dai_get_sdw_stream() 416 + * 417 + * Returns pointer to stream or -ENOTSUPP if callback is not supported; 418 + */ 419 + static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai, 420 + int direction) 421 + { 422 + if (dai->driver->ops->get_sdw_stream) 423 + return dai->driver->ops->get_sdw_stream(dai, direction); 424 + else 425 + return ERR_PTR(-ENOTSUPP); 426 426 } 427 427 428 428 #endif
+6
include/sound/soc-dapm.h
··· 482 482 struct snd_soc_dapm_widget_list **list, 483 483 bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, 484 484 enum snd_soc_dapm_direction)); 485 + void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list); 485 486 486 487 struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( 487 488 struct snd_kcontrol *kcontrol); ··· 691 690 int num_widgets; 692 691 struct snd_soc_dapm_widget *widgets[0]; 693 692 }; 693 + 694 + #define for_each_dapm_widgets(list, i, widget) \ 695 + for ((i) = 0; \ 696 + (i) < list->num_widgets && (widget = list->widgets[i]); \ 697 + (i)++) 694 698 695 699 struct snd_soc_dapm_stats { 696 700 int power_checks;
+3 -17
include/sound/soc-dpcm.h
··· 132 132 struct snd_pcm_substream * 133 133 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream); 134 134 135 - /* get the BE runtime state */ 136 - enum snd_soc_dpcm_state 137 - snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream); 138 - 139 - /* set the BE runtime state */ 140 - void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream, 141 - enum snd_soc_dpcm_state state); 142 - 143 - /* internal use only */ 144 - int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); 145 - int soc_dpcm_runtime_update(struct snd_soc_card *); 135 + /* update audio routing between PCMs and any DAI links */ 136 + int snd_soc_dpcm_runtime_update(struct snd_soc_card *card); 146 137 147 138 #ifdef CONFIG_DEBUG_FS 148 139 void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); ··· 145 154 146 155 int dpcm_path_get(struct snd_soc_pcm_runtime *fe, 147 156 int stream, struct snd_soc_dapm_widget_list **list_); 157 + void dpcm_path_put(struct snd_soc_dapm_widget_list **list); 148 158 int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, 149 159 int stream, struct snd_soc_dapm_widget_list **list, int new); 150 160 int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream); ··· 158 166 int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream); 159 167 int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, 160 168 int event); 161 - 162 - static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list) 163 - { 164 - kfree(*list); 165 - } 166 - 167 169 168 170 #endif
+40 -4
include/sound/soc.h
··· 471 471 void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream); 472 472 void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream); 473 473 474 + int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, 475 + struct snd_pcm_hardware *hw, int stream); 476 + 474 477 int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, 475 478 unsigned int dai_fmt); 476 479 ··· 858 855 ((platform) = &link->platforms[i]); \ 859 856 (i)++) 860 857 858 + #define for_each_link_cpus(link, i, cpu) \ 859 + for ((i) = 0; \ 860 + ((i) < link->num_cpus) && ((cpu) = &link->cpus[i]); \ 861 + (i)++) 862 + 861 863 /* 862 864 * Sample 1 : Single CPU/Codec/Platform 863 865 * ··· 1066 1058 const struct snd_soc_dapm_route *of_dapm_routes; 1067 1059 int num_of_dapm_routes; 1068 1060 bool fully_routed; 1061 + bool disable_route_checks; 1069 1062 1070 1063 /* lists of probed devices belonging to this card */ 1071 1064 struct list_head component_dev_list; ··· 1118 1109 #define for_each_card_components(card, component) \ 1119 1110 list_for_each_entry(component, &(card)->component_dev_list, card_list) 1120 1111 1112 + #define for_each_card_dapms(card, dapm) \ 1113 + list_for_each_entry(dapm, &card->dapm_list, list) 1114 + 1115 + #define for_each_card_widgets(card, w)\ 1116 + list_for_each_entry(w, &card->widgets, list) 1117 + #define for_each_card_widgets_safe(card, w, _w) \ 1118 + list_for_each_entry_safe(w, _w, &card->widgets, list) 1119 + 1121 1120 /* SoC machine DAI configuration, glues a codec and cpu DAI together */ 1122 1121 struct snd_soc_pcm_runtime { 1123 1122 struct device *dev; ··· 1145 1128 struct snd_compr *compr; 1146 1129 struct snd_soc_dai *codec_dai; 1147 1130 struct snd_soc_dai *cpu_dai; 1131 + struct snd_soc_dai **dais; 1148 1132 1149 1133 struct snd_soc_dai **codec_dais; 1150 1134 unsigned int num_codecs; 1135 + 1136 + struct snd_soc_dai **cpu_dais; 1137 + unsigned int num_cpus; 1151 1138 1152 1139 struct delayed_work delayed_work; 1153 1140 void (*close_delayed_work_func)(struct snd_soc_pcm_runtime *rtd); ··· 1169 1148 int num_components; 1170 1149 struct snd_soc_component *components[0]; /* CPU/Codec/Platform */ 1171 1150 }; 1151 + /* see soc_new_pcm_runtime() */ 1152 + #define asoc_rtd_to_cpu(rtd, n) (rtd)->dais[n] 1153 + #define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus] 1154 + 1172 1155 #define for_each_rtd_components(rtd, i, component) \ 1173 1156 for ((i) = 0; \ 1174 1157 ((i) < rtd->num_components) && ((component) = rtd->components[i]);\ 1175 1158 (i)++) 1176 - #define for_each_rtd_codec_dai(rtd, i, dai)\ 1177 - for ((i) = 0; \ 1178 - ((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \ 1159 + #define for_each_rtd_cpu_dais(rtd, i, dai) \ 1160 + for ((i) = 0; \ 1161 + ((i) < rtd->num_cpus) && ((dai) = rtd->cpu_dais[i]); \ 1179 1162 (i)++) 1180 - #define for_each_rtd_codec_dai_rollback(rtd, i, dai) \ 1163 + #define for_each_rtd_cpu_dais_rollback(rtd, i, dai) \ 1164 + for (; (--(i) >= 0) && ((dai) = rtd->cpu_dais[i]);) 1165 + #define for_each_rtd_codec_dais(rtd, i, dai) \ 1166 + for ((i) = 0; \ 1167 + ((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \ 1168 + (i)++) 1169 + #define for_each_rtd_codec_dais_rollback(rtd, i, dai) \ 1181 1170 for (; (--(i) >= 0) && ((dai) = rtd->codec_dais[i]);) 1171 + #define for_each_rtd_dais(rtd, i, dai) \ 1172 + for ((i) = 0; \ 1173 + ((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \ 1174 + ((dai) = (rtd)->dais[i]); \ 1175 + (i)++) 1182 1176 1183 1177 void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd); 1184 1178
+9 -9
include/sound/sof/dai-intel.h
··· 87 87 uint32_t link_dma_ch; 88 88 } __packed; 89 89 90 + /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ 91 + struct sof_ipc_dai_alh_params { 92 + struct sof_ipc_hdr hdr; 93 + uint32_t stream_id; 94 + 95 + /* reserved for future use */ 96 + uint32_t reserved[15]; 97 + } __packed; 98 + 90 99 /* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */ 91 100 92 101 /* This struct is defined per 2ch PDM controller available in the platform. ··· 186 177 187 178 /**< variable number of pdm controller config */ 188 179 struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; 189 - } __packed; 190 - 191 - /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ 192 - struct sof_ipc_dai_alh_params { 193 - struct sof_ipc_hdr hdr; 194 - uint32_t stream_id; 195 - 196 - /* reserved for future use */ 197 - uint32_t reserved[15]; 198 180 } __packed; 199 181 200 182 #endif
+11
include/sound/sof/header.h
··· 51 51 #define SOF_IPC_GLB_TRACE_MSG SOF_GLB_TYPE(0x9U) 52 52 #define SOF_IPC_GLB_GDB_DEBUG SOF_GLB_TYPE(0xAU) 53 53 #define SOF_IPC_GLB_TEST_MSG SOF_GLB_TYPE(0xBU) 54 + #define SOF_IPC_GLB_PROBE SOF_GLB_TYPE(0xCU) 54 55 55 56 /* 56 57 * DSP Command Message Types ··· 102 101 #define SOF_IPC_STREAM_POSITION SOF_CMD_TYPE(0x00a) 103 102 #define SOF_IPC_STREAM_VORBIS_PARAMS SOF_CMD_TYPE(0x010) 104 103 #define SOF_IPC_STREAM_VORBIS_FREE SOF_CMD_TYPE(0x011) 104 + 105 + /* probe */ 106 + #define SOF_IPC_PROBE_INIT SOF_CMD_TYPE(0x001) 107 + #define SOF_IPC_PROBE_DEINIT SOF_CMD_TYPE(0x002) 108 + #define SOF_IPC_PROBE_DMA_ADD SOF_CMD_TYPE(0x003) 109 + #define SOF_IPC_PROBE_DMA_INFO SOF_CMD_TYPE(0x004) 110 + #define SOF_IPC_PROBE_DMA_REMOVE SOF_CMD_TYPE(0x005) 111 + #define SOF_IPC_PROBE_POINT_ADD SOF_CMD_TYPE(0x006) 112 + #define SOF_IPC_PROBE_POINT_INFO SOF_CMD_TYPE(0x007) 113 + #define SOF_IPC_PROBE_POINT_REMOVE SOF_CMD_TYPE(0x008) 105 114 106 115 /* trace */ 107 116 #define SOF_IPC_TRACE_DMA_PARAMS SOF_CMD_TYPE(0x001)
+3 -19
include/sound/sof/info.h
··· 28 28 29 29 /* extended data types that can be appended onto end of sof_ipc_fw_ready */ 30 30 enum sof_ipc_ext_data { 31 - SOF_IPC_EXT_DMA_BUFFER = 0, 32 - SOF_IPC_EXT_WINDOW, 33 - SOF_IPC_EXT_CC_INFO, 31 + SOF_IPC_EXT_UNUSED = 0, 32 + SOF_IPC_EXT_WINDOW = 1, 33 + SOF_IPC_EXT_CC_INFO = 2, 34 34 }; 35 35 36 36 /* FW version - SOF_IPC_GLB_VERSION */ ··· 82 82 struct sof_ipc_cmd_hdr hdr; 83 83 uint32_t type; /**< SOF_IPC_EXT_ */ 84 84 } __packed; 85 - 86 - struct sof_ipc_dma_buffer_elem { 87 - struct sof_ipc_hdr hdr; 88 - uint32_t type; /**< SOF_IPC_REGION_ */ 89 - uint32_t id; /**< platform specific - used to map to host memory */ 90 - struct sof_ipc_host_buffer buffer; 91 - } __packed; 92 - 93 - /* extended data DMA buffers for IPC, trace and debug */ 94 - struct sof_ipc_dma_buffer_data { 95 - struct sof_ipc_ext_data_hdr ext_hdr; 96 - uint32_t num_buffers; 97 - 98 - /* host files in buffer[n].buffer */ 99 - struct sof_ipc_dma_buffer_elem buffer[]; 100 - } __packed; 101 85 102 86 struct sof_ipc_window_elem { 103 87 struct sof_ipc_hdr hdr;
+2 -1
include/sound/sof/topology.h
··· 53 53 uint32_t id; 54 54 enum sof_comp_type type; 55 55 uint32_t pipeline_id; 56 + uint32_t core; 56 57 57 58 /* reserved for future use */ 58 - uint32_t reserved[2]; 59 + uint32_t reserved[1]; 59 60 } __packed; 60 61 61 62 /*
+1
include/uapi/sound/asoc.h
··· 17 17 #define __LINUX_UAPI_SND_ASOC_H 18 18 19 19 #include <linux/types.h> 20 + #include <sound/asound.h> 20 21 21 22 /* 22 23 * Maximum number of channels topology kcontrol can represent.
+1 -1
include/uapi/sound/compress_offload.h
··· 31 31 #include <sound/compress_params.h> 32 32 33 33 34 - #define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2) 34 + #define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 2, 0) 35 35 /** 36 36 * struct snd_compressed_buffer - compressed buffer 37 37 * @fragment_size: size of buffer fragment in bytes
+36 -1
include/uapi/sound/compress_params.h
··· 75 75 #define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C) 76 76 #define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D) 77 77 #define SND_AUDIOCODEC_BESPOKE ((__u32) 0x0000000E) 78 - #define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_BESPOKE 78 + #define SND_AUDIOCODEC_ALAC ((__u32) 0x0000000F) 79 + #define SND_AUDIOCODEC_APE ((__u32) 0x00000010) 80 + #define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_APE 79 81 80 82 /* 81 83 * Profile and modes are listed with bit masks. This allows for a ··· 144 142 #define SND_AUDIOPROFILE_WMA8 ((__u32) 0x00000002) 145 143 #define SND_AUDIOPROFILE_WMA9 ((__u32) 0x00000004) 146 144 #define SND_AUDIOPROFILE_WMA10 ((__u32) 0x00000008) 145 + #define SND_AUDIOPROFILE_WMA9_PRO ((__u32) 0x00000010) 146 + #define SND_AUDIOPROFILE_WMA9_LOSSLESS ((__u32) 0x00000020) 147 + #define SND_AUDIOPROFILE_WMA10_LOSSLESS ((__u32) 0x00000040) 147 148 148 149 #define SND_AUDIOMODE_WMA_LEVEL1 ((__u32) 0x00000001) 149 150 #define SND_AUDIOMODE_WMA_LEVEL2 ((__u32) 0x00000002) ··· 331 326 __u16 reserved; 332 327 } __attribute__((packed, aligned(4))); 333 328 329 + struct snd_dec_wma { 330 + __u32 encoder_option; 331 + __u32 adv_encoder_option; 332 + __u32 adv_encoder_option2; 333 + __u32 reserved; 334 + } __attribute__((packed, aligned(4))); 335 + 336 + struct snd_dec_alac { 337 + __u32 frame_length; 338 + __u8 compatible_version; 339 + __u8 pb; 340 + __u8 mb; 341 + __u8 kb; 342 + __u32 max_run; 343 + __u32 max_frame_bytes; 344 + } __attribute__((packed, aligned(4))); 345 + 346 + struct snd_dec_ape { 347 + __u16 compatible_version; 348 + __u16 compression_level; 349 + __u32 format_flags; 350 + __u32 blocks_per_frame; 351 + __u32 final_frame_blocks; 352 + __u32 total_frames; 353 + __u32 seek_table_present; 354 + } __attribute__((packed, aligned(4))); 355 + 334 356 union snd_codec_options { 335 357 struct snd_enc_wma wma; 336 358 struct snd_enc_vorbis vorbis; ··· 365 333 struct snd_enc_flac flac; 366 334 struct snd_enc_generic generic; 367 335 struct snd_dec_flac flac_d; 336 + struct snd_dec_wma wma_d; 337 + struct snd_dec_alac alac_d; 338 + struct snd_dec_ape ape_d; 368 339 } __attribute__((packed, aligned(4))); 369 340 370 341 /** struct snd_codec_desc - description of codec capabilities
+1 -1
include/uapi/sound/sof/abi.h
··· 26 26 27 27 /* SOF ABI version major, minor and patch numbers */ 28 28 #define SOF_ABI_MAJOR 3 29 - #define SOF_ABI_MINOR 12 29 + #define SOF_ABI_MINOR 13 30 30 #define SOF_ABI_PATCH 0 31 31 32 32 /* SOF ABI version number. Format within 32bit word is MMmmmppp */
+4 -4
sound/arm/pxa2xx-pcm-lib.c
··· 38 38 struct dma_slave_config config; 39 39 int ret; 40 40 41 - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 41 + dma_params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 42 42 if (!dma_params) 43 43 return 0; 44 44 ··· 47 47 return ret; 48 48 49 49 snd_dmaengine_pcm_set_config_from_dai_data(substream, 50 - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream), 50 + snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream), 51 51 &config); 52 52 53 53 ret = dmaengine_slave_config(chan, &config); ··· 95 95 96 96 runtime->hw = pxa2xx_pcm_hardware; 97 97 98 - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 98 + dma_params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 99 99 if (!dma_params) 100 100 return 0; 101 101 ··· 120 120 return ret; 121 121 122 122 return snd_dmaengine_pcm_open( 123 - substream, dma_request_slave_channel(rtd->cpu_dai->dev, 123 + substream, dma_request_slave_channel(asoc_rtd_to_cpu(rtd, 0)->dev, 124 124 dma_params->chan_name)); 125 125 } 126 126 EXPORT_SYMBOL(pxa2xx_pcm_open);
+42
sound/core/compress_offload.c
··· 488 488 } 489 489 #endif /* !COMPR_CODEC_CAPS_OVERFLOW */ 490 490 491 + int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size) 492 + { 493 + struct snd_dma_buffer *dmab; 494 + int ret; 495 + 496 + if (snd_BUG_ON(!(stream) || !(stream)->runtime)) 497 + return -EINVAL; 498 + dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); 499 + if (!dmab) 500 + return -ENOMEM; 501 + dmab->dev = stream->dma_buffer.dev; 502 + ret = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab); 503 + if (ret < 0) { 504 + kfree(dmab); 505 + return ret; 506 + } 507 + 508 + snd_compr_set_runtime_buffer(stream, dmab); 509 + stream->runtime->dma_bytes = size; 510 + return 1; 511 + } 512 + EXPORT_SYMBOL(snd_compr_malloc_pages); 513 + 514 + int snd_compr_free_pages(struct snd_compr_stream *stream) 515 + { 516 + struct snd_compr_runtime *runtime = stream->runtime; 517 + 518 + if (snd_BUG_ON(!(stream) || !(stream)->runtime)) 519 + return -EINVAL; 520 + if (runtime->dma_area == NULL) 521 + return 0; 522 + if (runtime->dma_buffer_p != &stream->dma_buffer) { 523 + /* It's a newly allocated buffer. Release it now. */ 524 + snd_dma_free_pages(runtime->dma_buffer_p); 525 + kfree(runtime->dma_buffer_p); 526 + } 527 + 528 + snd_compr_set_runtime_buffer(stream, NULL); 529 + return 0; 530 + } 531 + EXPORT_SYMBOL(snd_compr_free_pages); 532 + 491 533 /* revisit this with snd_pcm_preallocate_xxx */ 492 534 static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, 493 535 struct snd_compr_params *params)
+21
sound/core/device.c
··· 237 237 list_for_each_entry_safe_reverse(dev, next, &card->devices, list) 238 238 __snd_device_free(dev); 239 239 } 240 + 241 + /** 242 + * snd_device_get_state - Get the current state of the given device 243 + * @card: the card instance 244 + * @device_data: the data pointer to release 245 + * 246 + * Returns the current state of the given device object. For the valid 247 + * device, either @SNDRV_DEV_BUILD, @SNDRV_DEV_REGISTERED or 248 + * @SNDRV_DEV_DISCONNECTED is returned. 249 + * Or for a non-existing device, -1 is returned as an error. 250 + */ 251 + int snd_device_get_state(struct snd_card *card, void *device_data) 252 + { 253 + struct snd_device *dev; 254 + 255 + dev = look_for_dev(card, device_data); 256 + if (dev) 257 + return dev->state; 258 + return -1; 259 + } 260 + EXPORT_SYMBOL_GPL(snd_device_get_state);
+1 -1
sound/core/info.c
··· 604 604 */ 605 605 int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) 606 606 { 607 - int c = -1; 607 + int c; 608 608 609 609 if (snd_BUG_ON(!buffer || !buffer->buffer)) 610 610 return 1;
+12 -11
sound/core/oss/pcm_oss.c
··· 884 884 sformat = snd_pcm_plug_slave_format(format, sformat_mask); 885 885 886 886 if ((__force int)sformat < 0 || 887 - !snd_mask_test(sformat_mask, (__force int)sformat)) { 888 - for (sformat = (__force snd_pcm_format_t)0; 889 - (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST; 890 - sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) { 891 - if (snd_mask_test(sformat_mask, (__force int)sformat) && 887 + !snd_mask_test_format(sformat_mask, sformat)) { 888 + pcm_for_each_format(sformat) { 889 + if (snd_mask_test_format(sformat_mask, sformat) && 892 890 snd_pcm_oss_format_to(sformat) >= 0) 893 - break; 891 + goto format_found; 894 892 } 895 - if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) { 896 - pcm_dbg(substream->pcm, "Cannot find a format!!!\n"); 897 - err = -EINVAL; 898 - goto failure; 899 - } 893 + pcm_dbg(substream->pcm, "Cannot find a format!!!\n"); 894 + err = -EINVAL; 895 + goto failure; 900 896 } 897 + format_found: 901 898 err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0); 902 899 if (err < 0) 903 900 goto failure; ··· 1217 1220 if (ret < 0) 1218 1221 break; 1219 1222 } 1223 + mutex_unlock(&runtime->oss.params_lock); 1220 1224 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true, 1221 1225 frames, in_kernel); 1226 + mutex_lock(&runtime->oss.params_lock); 1222 1227 if (ret != -EPIPE && ret != -ESTRPIPE) 1223 1228 break; 1224 1229 /* test, if we can't store new data, because the stream */ ··· 1256 1257 ret = snd_pcm_oss_capture_position_fixup(substream, &delay); 1257 1258 if (ret < 0) 1258 1259 break; 1260 + mutex_unlock(&runtime->oss.params_lock); 1259 1261 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true, 1260 1262 frames, in_kernel); 1263 + mutex_lock(&runtime->oss.params_lock); 1261 1264 if (ret == -EPIPE) { 1262 1265 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 1263 1266 ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
+56 -64
sound/core/oss/pcm_plugin.c
··· 196 196 return 0; 197 197 } 198 198 199 + static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, 200 + snd_pcm_sframes_t frames) 201 + { 202 + struct snd_pcm_plugin *plugin, *plugin_next; 203 + 204 + plugin = snd_pcm_plug_first(plug); 205 + while (plugin && frames > 0) { 206 + plugin_next = plugin->next; 207 + if (plugin->dst_frames) { 208 + frames = plugin->dst_frames(plugin, frames); 209 + if (frames < 0) 210 + return frames; 211 + } 212 + if (frames > plugin->buf_frames) 213 + frames = plugin->buf_frames; 214 + plugin = plugin_next; 215 + } 216 + return frames; 217 + } 218 + 219 + static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug, 220 + snd_pcm_sframes_t frames) 221 + { 222 + struct snd_pcm_plugin *plugin, *plugin_prev; 223 + 224 + plugin = snd_pcm_plug_last(plug); 225 + while (plugin && frames > 0) { 226 + if (frames > plugin->buf_frames) 227 + frames = plugin->buf_frames; 228 + plugin_prev = plugin->prev; 229 + if (plugin->src_frames) { 230 + frames = plugin->src_frames(plugin, frames); 231 + if (frames < 0) 232 + return frames; 233 + } 234 + plugin = plugin_prev; 235 + } 236 + return frames; 237 + } 238 + 199 239 snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames) 200 240 { 201 - struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next; 202 - int stream; 203 - 204 241 if (snd_BUG_ON(!plug)) 205 242 return -ENXIO; 206 - if (drv_frames == 0) 207 - return 0; 208 - stream = snd_pcm_plug_stream(plug); 209 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 210 - plugin = snd_pcm_plug_last(plug); 211 - while (plugin && drv_frames > 0) { 212 - if (drv_frames > plugin->buf_frames) 213 - drv_frames = plugin->buf_frames; 214 - plugin_prev = plugin->prev; 215 - if (plugin->src_frames) 216 - drv_frames = plugin->src_frames(plugin, drv_frames); 217 - plugin = plugin_prev; 218 - } 219 - } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { 220 - plugin = snd_pcm_plug_first(plug); 221 - while (plugin && drv_frames > 0) { 222 - plugin_next = plugin->next; 223 - if (plugin->dst_frames) 224 - drv_frames = plugin->dst_frames(plugin, drv_frames); 225 - if (drv_frames > plugin->buf_frames) 226 - drv_frames = plugin->buf_frames; 227 - plugin = plugin_next; 228 - } 229 - } else 243 + switch (snd_pcm_plug_stream(plug)) { 244 + case SNDRV_PCM_STREAM_PLAYBACK: 245 + return calc_src_frames(plug, drv_frames); 246 + case SNDRV_PCM_STREAM_CAPTURE: 247 + return calc_dst_frames(plug, drv_frames); 248 + default: 230 249 snd_BUG(); 231 - return drv_frames; 250 + return -EINVAL; 251 + } 232 252 } 233 253 234 254 snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t clt_frames) 235 255 { 236 - struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next; 237 - snd_pcm_sframes_t frames; 238 - int stream; 239 - 240 256 if (snd_BUG_ON(!plug)) 241 257 return -ENXIO; 242 - if (clt_frames == 0) 243 - return 0; 244 - frames = clt_frames; 245 - stream = snd_pcm_plug_stream(plug); 246 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 247 - plugin = snd_pcm_plug_first(plug); 248 - while (plugin && frames > 0) { 249 - plugin_next = plugin->next; 250 - if (plugin->dst_frames) { 251 - frames = plugin->dst_frames(plugin, frames); 252 - if (frames < 0) 253 - return frames; 254 - } 255 - if (frames > plugin->buf_frames) 256 - frames = plugin->buf_frames; 257 - plugin = plugin_next; 258 - } 259 - } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { 260 - plugin = snd_pcm_plug_last(plug); 261 - while (plugin) { 262 - if (frames > plugin->buf_frames) 263 - frames = plugin->buf_frames; 264 - plugin_prev = plugin->prev; 265 - if (plugin->src_frames) { 266 - frames = plugin->src_frames(plugin, frames); 267 - if (frames < 0) 268 - return frames; 269 - } 270 - plugin = plugin_prev; 271 - } 272 - } else 258 + switch (snd_pcm_plug_stream(plug)) { 259 + case SNDRV_PCM_STREAM_PLAYBACK: 260 + return calc_dst_frames(plug, clt_frames); 261 + case SNDRV_PCM_STREAM_CAPTURE: 262 + return calc_src_frames(plug, clt_frames); 263 + default: 273 264 snd_BUG(); 274 - return frames; 265 + return -EINVAL; 266 + } 275 267 } 276 268 277 269 static int snd_pcm_plug_formats(const struct snd_mask *mask,
+1 -1
sound/core/oss/rate.c
··· 47 47 unsigned int pos; 48 48 rate_f func; 49 49 snd_pcm_sframes_t old_src_frames, old_dst_frames; 50 - struct rate_channel channels[0]; 50 + struct rate_channel channels[]; 51 51 }; 52 52 53 53 static void rate_init(struct snd_pcm_plugin *plugin)
+1 -1
sound/core/pcm.c
··· 1019 1019 str = "none"; 1020 1020 else 1021 1021 str = strs[pcm->dev_class]; 1022 - return snprintf(buf, PAGE_SIZE, "%s\n", str); 1022 + return sprintf(buf, "%s\n", str); 1023 1023 } 1024 1024 1025 1025 static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL);
+6 -2
sound/core/pcm_dmaengine.c
··· 240 240 snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) 241 241 { 242 242 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 243 + struct snd_pcm_runtime *runtime = substream->runtime; 243 244 struct dma_tx_state state; 244 245 enum dma_status status; 245 246 unsigned int buf_size; ··· 251 250 buf_size = snd_pcm_lib_buffer_bytes(substream); 252 251 if (state.residue > 0 && state.residue <= buf_size) 253 252 pos = buf_size - state.residue; 253 + 254 + runtime->delay = bytes_to_frames(runtime, 255 + state.in_flight_bytes); 254 256 } 255 257 256 - return bytes_to_frames(substream->runtime, pos); 258 + return bytes_to_frames(runtime, pos); 257 259 } 258 260 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); 259 261 ··· 430 426 * default assumption is that it supports 1, 2 and 4 bytes 431 427 * widths. 432 428 */ 433 - for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) { 429 + pcm_for_each_format(i) { 434 430 int bits = snd_pcm_format_physical_width(i); 435 431 436 432 /*
+20 -15
sound/core/pcm_misc.c
··· 42 42 /* we do lots of calculations on snd_pcm_format_t; shut up sparse */ 43 43 #define INT __force int 44 44 45 + static bool valid_format(snd_pcm_format_t format) 46 + { 47 + return (INT)format >= 0 && (INT)format <= (INT)SNDRV_PCM_FORMAT_LAST; 48 + } 49 + 45 50 static const struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { 46 51 [SNDRV_PCM_FORMAT_S8] = { 47 52 .width = 8, .phys = 8, .le = -1, .signd = 1, ··· 264 259 int snd_pcm_format_signed(snd_pcm_format_t format) 265 260 { 266 261 int val; 267 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 262 + if (!valid_format(format)) 268 263 return -EINVAL; 269 264 if ((val = pcm_formats[(INT)format].signd) < 0) 270 265 return -EINVAL; ··· 312 307 int snd_pcm_format_little_endian(snd_pcm_format_t format) 313 308 { 314 309 int val; 315 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 310 + if (!valid_format(format)) 316 311 return -EINVAL; 317 312 if ((val = pcm_formats[(INT)format].le) < 0) 318 313 return -EINVAL; ··· 348 343 int snd_pcm_format_width(snd_pcm_format_t format) 349 344 { 350 345 int val; 351 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 346 + if (!valid_format(format)) 352 347 return -EINVAL; 353 348 if ((val = pcm_formats[(INT)format].width) == 0) 354 349 return -EINVAL; ··· 366 361 int snd_pcm_format_physical_width(snd_pcm_format_t format) 367 362 { 368 363 int val; 369 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 364 + if (!valid_format(format)) 370 365 return -EINVAL; 371 366 if ((val = pcm_formats[(INT)format].phys) == 0) 372 367 return -EINVAL; ··· 399 394 */ 400 395 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) 401 396 { 402 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 397 + if (!valid_format(format)) 403 398 return NULL; 404 399 if (! pcm_formats[(INT)format].phys) 405 400 return NULL; ··· 423 418 unsigned char *dst; 424 419 const unsigned char *pat; 425 420 426 - if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 421 + if (!valid_format(format)) 427 422 return -EINVAL; 428 423 if (samples == 0) 429 424 return 0; ··· 479 474 EXPORT_SYMBOL(snd_pcm_format_set_silence); 480 475 481 476 /** 482 - * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 483 - * @runtime: the runtime instance 477 + * snd_pcm_hw_limit_rates - determine rate_min/rate_max fields 478 + * @hw: the pcm hw instance 484 479 * 485 480 * Determines the rate_min and rate_max fields from the rates bits of 486 - * the given runtime->hw. 481 + * the given hw. 487 482 * 488 483 * Return: Zero if successful. 489 484 */ 490 - int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) 485 + int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw) 491 486 { 492 487 int i; 493 488 for (i = 0; i < (int)snd_pcm_known_rates.count; i++) { 494 - if (runtime->hw.rates & (1 << i)) { 495 - runtime->hw.rate_min = snd_pcm_known_rates.list[i]; 489 + if (hw->rates & (1 << i)) { 490 + hw->rate_min = snd_pcm_known_rates.list[i]; 496 491 break; 497 492 } 498 493 } 499 494 for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) { 500 - if (runtime->hw.rates & (1 << i)) { 501 - runtime->hw.rate_max = snd_pcm_known_rates.list[i]; 495 + if (hw->rates & (1 << i)) { 496 + hw->rate_max = snd_pcm_known_rates.list[i]; 502 497 break; 503 498 } 504 499 } 505 500 return 0; 506 501 } 507 - EXPORT_SYMBOL(snd_pcm_limit_hw_rates); 502 + EXPORT_SYMBOL(snd_pcm_hw_limit_rates); 508 503 509 504 /** 510 505 * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
+26 -21
sound/core/pcm_native.c
··· 228 228 return err; 229 229 } 230 230 231 + /* macro for simplified cast */ 232 + #define PARAM_MASK_BIT(b) (1U << (__force int)(b)) 233 + 231 234 static bool hw_support_mmap(struct snd_pcm_substream *substream) 232 235 { 233 236 if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP)) ··· 260 257 return -EINVAL; 261 258 262 259 /* This parameter is not requested to change by a caller. */ 263 - if (!(params->rmask & (1 << k))) 260 + if (!(params->rmask & PARAM_MASK_BIT(k))) 264 261 continue; 265 262 266 263 if (trace_hw_mask_param_enabled()) ··· 274 271 275 272 /* Set corresponding flag so that the caller gets it. */ 276 273 trace_hw_mask_param(substream, k, 0, &old_mask, m); 277 - params->cmask |= 1 << k; 274 + params->cmask |= PARAM_MASK_BIT(k); 278 275 } 279 276 280 277 return 0; ··· 296 293 return -EINVAL; 297 294 298 295 /* This parameter is not requested to change by a caller. */ 299 - if (!(params->rmask & (1 << k))) 296 + if (!(params->rmask & PARAM_MASK_BIT(k))) 300 297 continue; 301 298 302 299 if (trace_hw_interval_param_enabled()) ··· 310 307 311 308 /* Set corresponding flag so that the caller gets it. */ 312 309 trace_hw_interval_param(substream, k, 0, &old_interval, i); 313 - params->cmask |= 1 << k; 310 + params->cmask |= PARAM_MASK_BIT(k); 314 311 } 315 312 316 313 return 0; ··· 352 349 * have 0 so that the parameters are never changed anymore. 353 350 */ 354 351 for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) 355 - vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0; 352 + vstamps[k] = (params->rmask & PARAM_MASK_BIT(k)) ? 1 : 0; 356 353 357 354 /* Due to the above design, actual sequence number starts at 2. */ 358 355 stamp = 2; ··· 420 417 hw_param_interval(params, r->var)); 421 418 } 422 419 423 - params->cmask |= (1 << r->var); 420 + params->cmask |= PARAM_MASK_BIT(r->var); 424 421 vstamps[r->var] = stamp; 425 422 again = true; 426 423 } ··· 489 486 490 487 params->info = 0; 491 488 params->fifo_size = 0; 492 - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) 489 + if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) 493 490 params->msbits = 0; 494 - if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { 491 + if (params->rmask & PARAM_MASK_BIT(SNDRV_PCM_HW_PARAM_RATE)) { 495 492 params->rate_num = 0; 496 493 params->rate_den = 0; 497 494 } ··· 2296 2293 static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, 2297 2294 struct snd_pcm_hw_rule *rule) 2298 2295 { 2299 - unsigned int k; 2296 + snd_pcm_format_t k; 2300 2297 const struct snd_interval *i = 2301 2298 hw_param_interval_c(params, rule->deps[0]); 2302 2299 struct snd_mask m; 2303 2300 struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 2304 2301 snd_mask_any(&m); 2305 - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { 2302 + pcm_for_each_format(k) { 2306 2303 int bits; 2307 - if (! snd_mask_test(mask, k)) 2304 + if (!snd_mask_test_format(mask, k)) 2308 2305 continue; 2309 2306 bits = snd_pcm_format_physical_width(k); 2310 2307 if (bits <= 0) 2311 2308 continue; /* ignore invalid formats */ 2312 2309 if ((unsigned)bits < i->min || (unsigned)bits > i->max) 2313 - snd_mask_reset(&m, k); 2310 + snd_mask_reset(&m, (__force unsigned)k); 2314 2311 } 2315 2312 return snd_mask_refine(mask, &m); 2316 2313 } ··· 2319 2316 struct snd_pcm_hw_rule *rule) 2320 2317 { 2321 2318 struct snd_interval t; 2322 - unsigned int k; 2319 + snd_pcm_format_t k; 2320 + 2323 2321 t.min = UINT_MAX; 2324 2322 t.max = 0; 2325 2323 t.openmin = 0; 2326 2324 t.openmax = 0; 2327 - for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) { 2325 + pcm_for_each_format(k) { 2328 2326 int bits; 2329 - if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k)) 2327 + if (!snd_mask_test_format(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k)) 2330 2328 continue; 2331 2329 bits = snd_pcm_format_physical_width(k); 2332 2330 if (bits <= 0) ··· 2509 2505 unsigned int mask = 0; 2510 2506 2511 2507 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) 2512 - mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED; 2508 + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_INTERLEAVED); 2513 2509 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2514 - mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED; 2510 + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_RW_NONINTERLEAVED); 2515 2511 if (hw_support_mmap(substream)) { 2516 2512 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED) 2517 - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED; 2513 + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); 2518 2514 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED) 2519 - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED; 2515 + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED); 2520 2516 if (hw->info & SNDRV_PCM_INFO_COMPLEX) 2521 - mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; 2517 + mask |= PARAM_MASK_BIT(SNDRV_PCM_ACCESS_MMAP_COMPLEX); 2522 2518 } 2523 2519 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); 2524 2520 if (err < 0) ··· 2528 2524 if (err < 0) 2529 2525 return err; 2530 2526 2531 - err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); 2527 + err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 2528 + PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD)); 2532 2529 if (err < 0) 2533 2530 return err; 2534 2531
+3 -3
sound/drivers/aloop.c
··· 118 118 struct loopback_setup { 119 119 unsigned int notify: 1; 120 120 unsigned int rate_shift; 121 - unsigned int format; 121 + snd_pcm_format_t format; 122 122 unsigned int rate; 123 123 unsigned int channels; 124 124 struct snd_ctl_elem_id active_id; ··· 1432 1432 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1433 1433 uinfo->count = 1; 1434 1434 uinfo->value.integer.min = 0; 1435 - uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST; 1435 + uinfo->value.integer.max = (__force int)SNDRV_PCM_FORMAT_LAST; 1436 1436 uinfo->value.integer.step = 1; 1437 1437 return 0; 1438 1438 } ··· 1443 1443 struct loopback *loopback = snd_kcontrol_chip(kcontrol); 1444 1444 1445 1445 ucontrol->value.integer.value[0] = 1446 - loopback->setup[kcontrol->id.subdevice] 1446 + (__force int)loopback->setup[kcontrol->id.subdevice] 1447 1447 [kcontrol->id.device].format; 1448 1448 return 0; 1449 1449 }
+3 -3
sound/drivers/dummy.c
··· 901 901 static void print_formats(struct snd_dummy *dummy, 902 902 struct snd_info_buffer *buffer) 903 903 { 904 - int i; 904 + snd_pcm_format_t i; 905 905 906 - for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { 907 - if (dummy->pcm_hw.formats & (1ULL << i)) 906 + pcm_for_each_format(i) { 907 + if (dummy->pcm_hw.formats & pcm_format_to_bits(i)) 908 908 snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); 909 909 } 910 910 }
+1 -1
sound/firewire/bebob/bebob.c
··· 509 509 static struct fw_driver bebob_driver = { 510 510 .driver = { 511 511 .owner = THIS_MODULE, 512 - .name = "snd-bebob", 512 + .name = KBUILD_MODNAME, 513 513 .bus = &fw_bus_type, 514 514 }, 515 515 .probe = bebob_probe,
+1 -1
sound/firewire/digi00x/digi00x.c
··· 192 192 static struct fw_driver dg00x_driver = { 193 193 .driver = { 194 194 .owner = THIS_MODULE, 195 - .name = "snd-firewire-digi00x", 195 + .name = KBUILD_MODNAME, 196 196 .bus = &fw_bus_type, 197 197 }, 198 198 .probe = snd_dg00x_probe,
+1 -1
sound/firewire/fireface/ff.c
··· 224 224 static struct fw_driver ff_driver = { 225 225 .driver = { 226 226 .owner = THIS_MODULE, 227 - .name = "snd-fireface", 227 + .name = KBUILD_MODNAME, 228 228 .bus = &fw_bus_type, 229 229 }, 230 230 .probe = snd_ff_probe,
+1 -1
sound/firewire/fireworks/fireworks.c
··· 362 362 static struct fw_driver efw_driver = { 363 363 .driver = { 364 364 .owner = THIS_MODULE, 365 - .name = "snd-fireworks", 365 + .name = KBUILD_MODNAME, 366 366 .bus = &fw_bus_type, 367 367 }, 368 368 .probe = efw_probe,
+2
sound/firewire/tascam/tascam-hwdep.c
··· 17 17 18 18 static long tscm_hwdep_read_locked(struct snd_tscm *tscm, char __user *buf, 19 19 long count, loff_t *offset) 20 + __releases(&tscm->lock) 20 21 { 21 22 struct snd_firewire_event_lock_status event = { 22 23 .type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS, ··· 37 36 38 37 static long tscm_hwdep_read_queue(struct snd_tscm *tscm, char __user *buf, 39 38 long remained, loff_t *offset) 39 + __releases(&tscm->lock) 40 40 { 41 41 char __user *pos = buf; 42 42 unsigned int type = SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL;
+1 -1
sound/firewire/tascam/tascam.c
··· 224 224 static struct fw_driver tscm_driver = { 225 225 .driver = { 226 226 .owner = THIS_MODULE, 227 - .name = "snd-firewire-tascam", 227 + .name = KBUILD_MODNAME, 228 228 .bus = &fw_bus_type, 229 229 }, 230 230 .probe = snd_tscm_probe,
+1 -1
sound/hda/hdac_device.c
··· 204 204 */ 205 205 int snd_hdac_codec_modalias(struct hdac_device *codec, char *buf, size_t size) 206 206 { 207 - return snprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n", 207 + return scnprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n", 208 208 codec->vendor_id, codec->revision_id, codec->type); 209 209 } 210 210 EXPORT_SYMBOL_GPL(snd_hdac_codec_modalias);
+2 -2
sound/isa/sb/emu8000_pcm.c
··· 435 435 #define LOOP_WRITE(rec, offset, _buf, count, mode) \ 436 436 do { \ 437 437 struct snd_emu8000 *emu = (rec)->emu; \ 438 - unsigned short *buf = (unsigned short *)(_buf); \ 438 + unsigned short *buf = (__force unsigned short *)(_buf); \ 439 439 snd_emu8000_write_wait(emu, 1); \ 440 440 EMU8000_SMALW_WRITE(emu, offset); \ 441 441 while (count > 0) { \ ··· 492 492 #define LOOP_WRITE(rec, pos, _buf, count, mode) \ 493 493 do { \ 494 494 struct snd_emu8000 *emu = rec->emu; \ 495 - unsigned short *buf = (unsigned short *)(_buf); \ 495 + unsigned short *buf = (__force unsigned short *)(_buf); \ 496 496 snd_emu8000_write_wait(emu, 1); \ 497 497 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ 498 498 if (rec->voices > 1) \
+2 -4
sound/pci/ali5451/ali5451.c
··· 1070 1070 { 1071 1071 struct snd_ali *codec = snd_pcm_substream_chip(substream); 1072 1072 struct snd_pcm_substream *s; 1073 - unsigned int what, whati, capture_flag; 1073 + unsigned int what, whati; 1074 1074 struct snd_ali_voice *pvoice, *evoice; 1075 1075 unsigned int val; 1076 1076 int do_start; ··· 1088 1088 return -EINVAL; 1089 1089 } 1090 1090 1091 - what = whati = capture_flag = 0; 1091 + what = whati = 0; 1092 1092 snd_pcm_group_for_each_entry(s, substream) { 1093 1093 if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { 1094 1094 pvoice = s->runtime->private_data; ··· 1110 1110 evoice->running = 0; 1111 1111 } 1112 1112 snd_pcm_trigger_done(s, substream); 1113 - if (pvoice->mode) 1114 - capture_flag = 1; 1115 1113 } 1116 1114 } 1117 1115 spin_lock(&codec->reg_lock);
+3 -1
sound/pci/emu10k1/emu10k1_main.c
··· 1789 1789 int idx, err; 1790 1790 int is_audigy; 1791 1791 size_t page_table_size; 1792 + __le32 *pgtbl; 1792 1793 unsigned int silent_page; 1793 1794 const struct snd_emu_chip_details *c; 1794 1795 static const struct snd_device_ops ops = { ··· 2010 2009 /* Clear silent pages and set up pointers */ 2011 2010 memset(emu->silent_page.area, 0, emu->silent_page.bytes); 2012 2011 silent_page = emu->silent_page.addr << emu->address_mode; 2012 + pgtbl = (__le32 *)emu->ptb_pages.area; 2013 2013 for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++) 2014 - ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); 2014 + pgtbl[idx] = cpu_to_le32(silent_page | idx); 2015 2015 2016 2016 /* set up voice indices */ 2017 2017 for (idx = 0; idx < NUM_G; idx++) {
+1
sound/pci/hda/Kconfig
··· 184 184 config SND_HDA_CODEC_CA0132_DSP 185 185 bool "Support new DSP code for CA0132 codec" 186 186 depends on SND_HDA_CODEC_CA0132 187 + default y 187 188 select SND_HDA_DSP_LOADER 188 189 select FW_LOADER 189 190 help
+1 -1
sound/pci/hda/hda_codec.c
··· 88 88 struct list_head list; 89 89 int len; 90 90 hda_nid_t nid; 91 - hda_nid_t conns[0]; 91 + hda_nid_t conns[]; 92 92 }; 93 93 94 94 /* look up the cached results */
+1 -1
sound/pci/hda/hda_controller.c
··· 373 373 u32 wallclk_ctr, wallclk_cycles; 374 374 bool direction; 375 375 u32 dma_select; 376 - u32 timeout = 200; 376 + u32 timeout; 377 377 u32 retry_count = 0; 378 378 379 379 runtime = substream->runtime;
+2 -1
sound/pci/hda/patch_ca0132.c
··· 1180 1180 SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), 1181 1181 SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), 1182 1182 SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), 1183 + SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI), 1183 1184 SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D), 1184 1185 SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5), 1185 1186 {} ··· 2699 2698 u32 magic; 2700 2699 u32 chip_addr; 2701 2700 u32 count; 2702 - u32 data[0]; 2701 + u32 data[]; 2703 2702 }; 2704 2703 2705 2704 static const u32 g_magic_value = 0x4c46584d;
+90 -223
sound/pci/hda/patch_hdmi.c
··· 154 154 struct hda_multi_out multiout; 155 155 struct hda_pcm_stream pcm_playback; 156 156 157 - bool use_jack_detect; /* jack detection enabled */ 158 157 bool use_acomp_notifier; /* use eld_notify callback for hotplug */ 159 158 bool acomp_registered; /* audio component registered in this driver */ 160 159 struct drm_audio_component_audio_ops drm_audio_ops; ··· 752 753 * Unsolicited events 753 754 */ 754 755 755 - static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); 756 + static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); 756 757 757 758 static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid, 758 759 int dev_id) ··· 763 764 if (pin_idx < 0) 764 765 return; 765 766 mutex_lock(&spec->pcm_lock); 766 - if (hdmi_present_sense(get_pin(spec, pin_idx), 1)) 767 - snd_hda_jack_report_sync(codec); 767 + hdmi_present_sense(get_pin(spec, pin_idx), 1); 768 768 mutex_unlock(&spec->pcm_lock); 769 769 } 770 770 ··· 777 779 check_presence_and_report(codec, jack->nid, jack->dev_id); 778 780 } 779 781 780 - static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) 782 + static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res, 783 + struct hda_jack_tbl *jack) 781 784 { 782 - int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 783 - struct hda_jack_tbl *jack; 784 - 785 - if (codec->dp_mst) { 786 - int dev_entry = 787 - (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; 788 - 789 - jack = snd_hda_jack_tbl_get_from_tag(codec, tag, dev_entry); 790 - } else { 791 - jack = snd_hda_jack_tbl_get_from_tag(codec, tag, 0); 792 - } 793 - if (!jack) 794 - return; 795 785 jack->jack_dirty = 1; 796 786 797 787 codec_dbg(codec, ··· 839 853 } 840 854 841 855 if (subtag == 0) 842 - hdmi_intrinsic_event(codec, res); 856 + hdmi_intrinsic_event(codec, res, jack); 843 857 else 844 858 hdmi_non_intrinsic_event(codec, res); 845 859 } ··· 1466 1480 per_pin->channels = 0; 1467 1481 } 1468 1482 1483 + static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec, 1484 + struct hdmi_spec_per_pin *per_pin) 1485 + { 1486 + struct hdmi_spec *spec = codec->spec; 1487 + 1488 + if (per_pin->pcm_idx >= 0) 1489 + return spec->pcm_rec[per_pin->pcm_idx].jack; 1490 + else 1491 + return NULL; 1492 + } 1493 + 1469 1494 /* update per_pin ELD from the given new ELD; 1470 1495 * setup info frame and notification accordingly 1496 + * also notify ELD kctl and report jack status changes 1471 1497 */ 1472 - static bool update_eld(struct hda_codec *codec, 1498 + static void update_eld(struct hda_codec *codec, 1473 1499 struct hdmi_spec_per_pin *per_pin, 1474 - struct hdmi_eld *eld) 1500 + struct hdmi_eld *eld, 1501 + int repoll) 1475 1502 { 1476 1503 struct hdmi_eld *pin_eld = &per_pin->sink_eld; 1477 1504 struct hdmi_spec *spec = codec->spec; 1505 + struct snd_jack *pcm_jack; 1478 1506 bool old_eld_valid = pin_eld->eld_valid; 1479 1507 bool eld_changed; 1480 1508 int pcm_idx; 1481 1509 1510 + if (eld->eld_valid) { 1511 + if (eld->eld_size <= 0 || 1512 + snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, 1513 + eld->eld_size) < 0) { 1514 + eld->eld_valid = false; 1515 + if (repoll) { 1516 + schedule_delayed_work(&per_pin->work, 1517 + msecs_to_jiffies(300)); 1518 + return; 1519 + } 1520 + } 1521 + } 1522 + 1523 + if (!eld->eld_valid || eld->eld_size <= 0) { 1524 + eld->eld_valid = false; 1525 + eld->eld_size = 0; 1526 + } 1527 + 1482 1528 /* for monitor disconnection, save pcm_idx firstly */ 1483 1529 pcm_idx = per_pin->pcm_idx; 1530 + 1531 + /* 1532 + * pcm_idx >=0 before update_eld() means it is in monitor 1533 + * disconnected event. Jack must be fetched before update_eld(). 1534 + */ 1535 + pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1536 + 1484 1537 if (spec->dyn_pcm_assign) { 1485 1538 if (eld->eld_valid) { 1486 1539 hdmi_attach_hda_pcm(spec, per_pin); ··· 1534 1509 */ 1535 1510 if (pcm_idx == -1) 1536 1511 pcm_idx = per_pin->pcm_idx; 1512 + if (!pcm_jack) 1513 + pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1537 1514 1538 1515 if (eld->eld_valid) 1539 1516 snd_hdmi_show_eld(codec, &eld->info); ··· 1574 1547 SNDRV_CTL_EVENT_MASK_VALUE | 1575 1548 SNDRV_CTL_EVENT_MASK_INFO, 1576 1549 &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id); 1577 - return eld_changed; 1550 + 1551 + if (eld_changed && pcm_jack) 1552 + snd_jack_report(pcm_jack, 1553 + (eld->monitor_present && eld->eld_valid) ? 1554 + SND_JACK_AVOUT : 0); 1578 1555 } 1579 1556 1580 - static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec, 1581 - struct hdmi_spec_per_pin *per_pin) 1582 - { 1583 - struct hdmi_spec *spec = codec->spec; 1584 - struct snd_jack *jack = NULL; 1585 - struct hda_jack_tbl *jack_tbl; 1586 - 1587 - /* if !dyn_pcm_assign, get jack from hda_jack_tbl 1588 - * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not 1589 - * NULL even after snd_hda_jack_tbl_clear() is called to 1590 - * free snd_jack. This may cause access invalid memory 1591 - * when calling snd_jack_report 1592 - */ 1593 - if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) { 1594 - jack = spec->pcm_rec[per_pin->pcm_idx].jack; 1595 - } else if (!spec->dyn_pcm_assign) { 1596 - /* 1597 - * jack tbl doesn't support DP MST 1598 - * DP MST will use dyn_pcm_assign, 1599 - * so DP MST will never come here 1600 - */ 1601 - jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, 1602 - per_pin->dev_id); 1603 - if (jack_tbl) 1604 - jack = jack_tbl->jack; 1605 - } 1606 - return jack; 1607 - } 1608 1557 /* update ELD and jack state via HD-audio verbs */ 1609 - static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, 1558 + static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, 1610 1559 int repoll) 1611 1560 { 1612 - struct hda_jack_tbl *jack; 1613 1561 struct hda_codec *codec = per_pin->codec; 1614 1562 struct hdmi_spec *spec = codec->spec; 1615 1563 struct hdmi_eld *eld = &spec->temp_eld; ··· 1599 1597 * the unsolicited response to avoid custom WARs. 1600 1598 */ 1601 1599 int present; 1602 - bool ret; 1603 - bool do_repoll = false; 1604 - struct snd_jack *pcm_jack = NULL; 1600 + int ret; 1601 + 1602 + ret = snd_hda_power_up_pm(codec); 1603 + if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec))) 1604 + goto out; 1605 1605 1606 1606 present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id); 1607 1607 ··· 1622 1618 if (spec->ops.pin_get_eld(codec, pin_nid, dev_id, 1623 1619 eld->eld_buffer, &eld->eld_size) < 0) 1624 1620 eld->eld_valid = false; 1625 - else { 1626 - if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, 1627 - eld->eld_size) < 0) 1628 - eld->eld_valid = false; 1629 - } 1630 - if (!eld->eld_valid && repoll) 1631 - do_repoll = true; 1632 1621 } 1633 1622 1634 - if (do_repoll) { 1635 - schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300)); 1636 - } else { 1637 - /* 1638 - * pcm_idx >=0 before update_eld() means it is in monitor 1639 - * disconnected event. Jack must be fetched before 1640 - * update_eld(). 1641 - */ 1642 - pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1643 - update_eld(codec, per_pin, eld); 1644 - if (!pcm_jack) 1645 - pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1646 - } 1647 - 1648 - ret = !repoll || !eld->monitor_present || eld->eld_valid; 1649 - 1650 - jack = snd_hda_jack_tbl_get_mst(codec, pin_nid, per_pin->dev_id); 1651 - if (jack) { 1652 - jack->block_report = !ret; 1653 - jack->pin_sense = (eld->monitor_present && eld->eld_valid) ? 1654 - AC_PINSENSE_PRESENCE : 0; 1655 - 1656 - if (spec->dyn_pcm_assign && pcm_jack && !do_repoll) { 1657 - int state = 0; 1658 - 1659 - if (jack->pin_sense & AC_PINSENSE_PRESENCE) 1660 - state = SND_JACK_AVOUT; 1661 - snd_jack_report(pcm_jack, state); 1662 - } 1663 - 1664 - /* 1665 - * snd_hda_jack_pin_sense() call at the beginning of this 1666 - * function, updates jack->pins_sense and clears 1667 - * jack->jack_dirty, therefore snd_hda_jack_report_sync() will 1668 - * not override the jack->pin_sense. 1669 - * 1670 - * snd_hda_jack_report_sync() is superfluous for dyn_pcm_assign 1671 - * case. The jack->pin_sense update was already performed, and 1672 - * hda_jack->jack is NULL for dyn_pcm_assign. 1673 - * 1674 - * Don't call snd_hda_jack_report_sync() for 1675 - * dyn_pcm_assign. 1676 - */ 1677 - ret = ret && !spec->dyn_pcm_assign; 1678 - } 1623 + update_eld(codec, per_pin, eld, repoll); 1679 1624 mutex_unlock(&per_pin->lock); 1680 - return ret; 1625 + out: 1626 + snd_hda_power_down_pm(codec); 1681 1627 } 1682 1628 1683 1629 /* update ELD and jack state via audio component */ ··· 1636 1682 { 1637 1683 struct hdmi_spec *spec = codec->spec; 1638 1684 struct hdmi_eld *eld = &spec->temp_eld; 1639 - struct snd_jack *jack = NULL; 1640 - bool changed; 1641 - int size; 1642 1685 1643 1686 mutex_lock(&per_pin->lock); 1644 1687 eld->monitor_present = false; 1645 - size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, 1688 + eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, 1646 1689 per_pin->dev_id, &eld->monitor_present, 1647 1690 eld->eld_buffer, ELD_MAX_SIZE); 1648 - if (size > 0) { 1649 - size = min(size, ELD_MAX_SIZE); 1650 - if (snd_hdmi_parse_eld(codec, &eld->info, 1651 - eld->eld_buffer, size) < 0) 1652 - size = -EINVAL; 1653 - } 1654 - 1655 - if (size > 0) { 1656 - eld->eld_valid = true; 1657 - eld->eld_size = size; 1658 - } else { 1659 - eld->eld_valid = false; 1660 - eld->eld_size = 0; 1661 - } 1662 - 1663 - /* pcm_idx >=0 before update_eld() means it is in monitor 1664 - * disconnected event. Jack must be fetched before update_eld() 1665 - */ 1666 - jack = pin_idx_to_pcm_jack(codec, per_pin); 1667 - changed = update_eld(codec, per_pin, eld); 1668 - if (jack == NULL) 1669 - jack = pin_idx_to_pcm_jack(codec, per_pin); 1670 - if (changed && jack) 1671 - snd_jack_report(jack, 1672 - (eld->monitor_present && eld->eld_valid) ? 1673 - SND_JACK_AVOUT : 0); 1691 + eld->eld_valid = (eld->eld_size > 0); 1692 + update_eld(codec, per_pin, eld, 0); 1674 1693 mutex_unlock(&per_pin->lock); 1675 1694 } 1676 1695 1677 - static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) 1696 + static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) 1678 1697 { 1679 1698 struct hda_codec *codec = per_pin->codec; 1680 - int ret; 1681 1699 1682 - /* no temporary power up/down needed for component notifier */ 1683 - if (!codec_has_acomp(codec)) { 1684 - ret = snd_hda_power_up_pm(codec); 1685 - if (ret < 0 && pm_runtime_suspended(hda_codec_dev(codec))) { 1686 - snd_hda_power_down_pm(codec); 1687 - return false; 1688 - } 1689 - ret = hdmi_present_sense_via_verbs(per_pin, repoll); 1690 - snd_hda_power_down_pm(codec); 1691 - } else { 1700 + if (!codec_has_acomp(codec)) 1701 + hdmi_present_sense_via_verbs(per_pin, repoll); 1702 + else 1692 1703 sync_eld_via_acomp(codec, per_pin); 1693 - ret = false; /* don't call snd_hda_jack_report_sync() */ 1694 - } 1695 - 1696 - return ret; 1697 1704 } 1698 1705 1699 1706 static void hdmi_repoll_eld(struct work_struct *work) ··· 1674 1759 per_pin->repoll_count = 0; 1675 1760 1676 1761 mutex_lock(&spec->pcm_lock); 1677 - if (hdmi_present_sense(per_pin, per_pin->repoll_count)) 1678 - snd_hda_jack_report_sync(per_pin->codec); 1762 + hdmi_present_sense(per_pin, per_pin->repoll_count); 1679 1763 mutex_unlock(&spec->pcm_lock); 1680 1764 } 1681 1765 ··· 2120 2206 pcm->jack = NULL; 2121 2207 } 2122 2208 2123 - static int add_hdmi_jack_kctl(struct hda_codec *codec, 2124 - struct hdmi_spec *spec, 2125 - int pcm_idx, 2126 - const char *name) 2209 + static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx) 2127 2210 { 2211 + char hdmi_str[32] = "HDMI/DP"; 2212 + struct hdmi_spec *spec = codec->spec; 2213 + struct hdmi_spec_per_pin *per_pin = get_pin(spec, pcm_idx); 2128 2214 struct snd_jack *jack; 2215 + int pcmdev = get_pcm_rec(spec, pcm_idx)->device; 2129 2216 int err; 2130 2217 2131 - err = snd_jack_new(codec->card, name, SND_JACK_AVOUT, &jack, 2218 + if (pcmdev > 0) 2219 + sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); 2220 + if (!spec->dyn_pcm_assign && 2221 + !is_jack_detectable(codec, per_pin->pin_nid)) 2222 + strncat(hdmi_str, " Phantom", 2223 + sizeof(hdmi_str) - strlen(hdmi_str) - 1); 2224 + 2225 + err = snd_jack_new(codec->card, hdmi_str, SND_JACK_AVOUT, &jack, 2132 2226 true, false); 2133 2227 if (err < 0) 2134 2228 return err; ··· 2144 2222 spec->pcm_rec[pcm_idx].jack = jack; 2145 2223 jack->private_data = &spec->pcm_rec[pcm_idx]; 2146 2224 jack->private_free = free_hdmi_jack_priv; 2147 - return 0; 2148 - } 2149 - 2150 - static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx) 2151 - { 2152 - char hdmi_str[32] = "HDMI/DP"; 2153 - struct hdmi_spec *spec = codec->spec; 2154 - struct hdmi_spec_per_pin *per_pin; 2155 - struct hda_jack_tbl *jack; 2156 - int pcmdev = get_pcm_rec(spec, pcm_idx)->device; 2157 - bool phantom_jack; 2158 - int ret; 2159 - 2160 - if (pcmdev > 0) 2161 - sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); 2162 - 2163 - if (spec->dyn_pcm_assign) 2164 - return add_hdmi_jack_kctl(codec, spec, pcm_idx, hdmi_str); 2165 - 2166 - /* for !dyn_pcm_assign, we still use hda_jack for compatibility */ 2167 - /* if !dyn_pcm_assign, it must be non-MST mode. 2168 - * This means pcms and pins are statically mapped. 2169 - * And pcm_idx is pin_idx. 2170 - */ 2171 - per_pin = get_pin(spec, pcm_idx); 2172 - phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid); 2173 - if (phantom_jack) 2174 - strncat(hdmi_str, " Phantom", 2175 - sizeof(hdmi_str) - strlen(hdmi_str) - 1); 2176 - ret = snd_hda_jack_add_kctl_mst(codec, per_pin->pin_nid, 2177 - per_pin->dev_id, hdmi_str, phantom_jack, 2178 - 0, NULL); 2179 - if (ret < 0) 2180 - return ret; 2181 - jack = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, 2182 - per_pin->dev_id); 2183 - if (jack == NULL) 2184 - return 0; 2185 - /* assign jack->jack to pcm_rec[].jack to 2186 - * align with dyn_pcm_assign mode 2187 - */ 2188 - spec->pcm_rec[pcm_idx].jack = jack->jack; 2189 2225 return 0; 2190 2226 } 2191 2227 ··· 2235 2355 int pin_idx; 2236 2356 2237 2357 mutex_lock(&spec->bind_lock); 2238 - spec->use_jack_detect = !codec->jackpoll_interval; 2239 2358 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 2240 2359 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 2241 2360 hda_nid_t pin_nid = per_pin->pin_nid; ··· 2244 2365 hdmi_init_pin(codec, pin_nid); 2245 2366 if (codec_has_acomp(codec)) 2246 2367 continue; 2247 - if (spec->use_jack_detect) 2248 - snd_hda_jack_detect_enable(codec, pin_nid, dev_id); 2249 - else 2250 - snd_hda_jack_detect_enable_callback_mst(codec, pin_nid, 2251 - dev_id, 2252 - jack_callback); 2368 + snd_hda_jack_detect_enable_callback_mst(codec, pin_nid, dev_id, 2369 + jack_callback); 2253 2370 } 2254 2371 mutex_unlock(&spec->bind_lock); 2255 2372 return 0; ··· 2407 2532 unsigned int val = use_acomp ? 0 : (AC_USRSP_EN | tbl->tag); 2408 2533 snd_hda_codec_write_cache(codec, nid, 0, 2409 2534 AC_VERB_SET_UNSOLICITED_ENABLE, val); 2410 - } else { 2411 - /* if no jack entry was defined beforehand, create a new one 2412 - * at need (i.e. only when notifier is cleared) 2413 - */ 2414 - if (!use_acomp) 2415 - snd_hda_jack_detect_enable(codec, nid, dev_id); 2416 2535 } 2417 2536 } 2418 2537 ··· 2422 2553 spec->use_acomp_notifier = use_acomp; 2423 2554 spec->codec->relaxed_resume = use_acomp; 2424 2555 /* reprogram each jack detection logic depending on the notifier */ 2425 - if (spec->use_jack_detect) { 2426 - for (i = 0; i < spec->num_pins; i++) 2427 - reprogram_jack_detect(spec->codec, 2428 - get_pin(spec, i)->pin_nid, 2429 - get_pin(spec, i)->dev_id, 2430 - use_acomp); 2431 - } 2556 + for (i = 0; i < spec->num_pins; i++) 2557 + reprogram_jack_detect(spec->codec, 2558 + get_pin(spec, i)->pin_nid, 2559 + get_pin(spec, i)->dev_id, 2560 + use_acomp); 2432 2561 mutex_unlock(&spec->bind_lock); 2433 2562 } 2434 2563
+128 -103
sound/pci/hda/patch_realtek.c
··· 107 107 unsigned int done_hp_init:1; 108 108 unsigned int no_shutup_pins:1; 109 109 unsigned int ultra_low_power:1; 110 + unsigned int has_hs_key:1; 110 111 111 112 /* for PLL fix */ 112 113 hda_nid_t pll_nid; ··· 368 367 case 0x10ec0215: 369 368 case 0x10ec0233: 370 369 case 0x10ec0235: 370 + case 0x10ec0236: 371 371 case 0x10ec0255: 372 + case 0x10ec0256: 372 373 case 0x10ec0257: 373 374 case 0x10ec0282: 374 375 case 0x10ec0283: ··· 380 377 case 0x10ec0298: 381 378 case 0x10ec0289: 382 379 case 0x10ec0300: 383 - alc_update_coef_idx(codec, 0x10, 1<<9, 0); 384 - break; 385 - case 0x10ec0236: 386 - case 0x10ec0256: 387 - alc_write_coef_idx(codec, 0x36, 0x5757); 388 380 alc_update_coef_idx(codec, 0x10, 1<<9, 0); 389 381 break; 390 382 case 0x10ec0275: ··· 2980 2982 return alc_parse_auto_config(codec, alc269_ignore, ssids); 2981 2983 } 2982 2984 2985 + static const struct hda_jack_keymap alc_headset_btn_keymap[] = { 2986 + { SND_JACK_BTN_0, KEY_PLAYPAUSE }, 2987 + { SND_JACK_BTN_1, KEY_VOICECOMMAND }, 2988 + { SND_JACK_BTN_2, KEY_VOLUMEUP }, 2989 + { SND_JACK_BTN_3, KEY_VOLUMEDOWN }, 2990 + {} 2991 + }; 2992 + 2993 + static void alc_headset_btn_callback(struct hda_codec *codec, 2994 + struct hda_jack_callback *jack) 2995 + { 2996 + int report = 0; 2997 + 2998 + if (jack->unsol_res & (7 << 13)) 2999 + report |= SND_JACK_BTN_0; 3000 + 3001 + if (jack->unsol_res & (1 << 16 | 3 << 8)) 3002 + report |= SND_JACK_BTN_1; 3003 + 3004 + /* Volume up key */ 3005 + if (jack->unsol_res & (7 << 23)) 3006 + report |= SND_JACK_BTN_2; 3007 + 3008 + /* Volume down key */ 3009 + if (jack->unsol_res & (7 << 10)) 3010 + report |= SND_JACK_BTN_3; 3011 + 3012 + jack->jack->button_state = report; 3013 + } 3014 + 3015 + static void alc_disable_headset_jack_key(struct hda_codec *codec) 3016 + { 3017 + struct alc_spec *spec = codec->spec; 3018 + 3019 + if (!spec->has_hs_key) 3020 + return; 3021 + 3022 + switch (codec->core.vendor_id) { 3023 + case 0x10ec0215: 3024 + case 0x10ec0225: 3025 + case 0x10ec0285: 3026 + case 0x10ec0295: 3027 + case 0x10ec0289: 3028 + case 0x10ec0299: 3029 + alc_write_coef_idx(codec, 0x48, 0x0); 3030 + alc_update_coef_idx(codec, 0x49, 0x0045, 0x0); 3031 + alc_update_coef_idx(codec, 0x44, 0x0045 << 8, 0x0); 3032 + break; 3033 + case 0x10ec0236: 3034 + case 0x10ec0256: 3035 + alc_write_coef_idx(codec, 0x48, 0x0); 3036 + alc_update_coef_idx(codec, 0x49, 0x0045, 0x0); 3037 + break; 3038 + } 3039 + } 3040 + 3041 + static void alc_enable_headset_jack_key(struct hda_codec *codec) 3042 + { 3043 + struct alc_spec *spec = codec->spec; 3044 + 3045 + if (!spec->has_hs_key) 3046 + return; 3047 + 3048 + switch (codec->core.vendor_id) { 3049 + case 0x10ec0215: 3050 + case 0x10ec0225: 3051 + case 0x10ec0285: 3052 + case 0x10ec0295: 3053 + case 0x10ec0289: 3054 + case 0x10ec0299: 3055 + alc_write_coef_idx(codec, 0x48, 0xd011); 3056 + alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045); 3057 + alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8); 3058 + break; 3059 + case 0x10ec0236: 3060 + case 0x10ec0256: 3061 + alc_write_coef_idx(codec, 0x48, 0xd011); 3062 + alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045); 3063 + break; 3064 + } 3065 + } 3066 + 3067 + static void alc_fixup_headset_jack(struct hda_codec *codec, 3068 + const struct hda_fixup *fix, int action) 3069 + { 3070 + struct alc_spec *spec = codec->spec; 3071 + 3072 + switch (action) { 3073 + case HDA_FIXUP_ACT_PRE_PROBE: 3074 + spec->has_hs_key = 1; 3075 + snd_hda_jack_detect_enable_callback(codec, 0x55, 3076 + alc_headset_btn_callback); 3077 + snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, 3078 + SND_JACK_HEADSET, alc_headset_btn_keymap); 3079 + break; 3080 + case HDA_FIXUP_ACT_INIT: 3081 + alc_enable_headset_jack_key(codec); 3082 + break; 3083 + } 3084 + } 3085 + 2983 3086 static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) 2984 3087 { 2985 3088 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0); ··· 3368 3269 alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ 3369 3270 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */ 3370 3271 alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15); 3371 - alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ 3272 + /* 3273 + * Expose headphone mic (or possibly Line In on some machines) instead 3274 + * of PC Beep on 1Ah, and disable 1Ah loopback for all outputs. See 3275 + * Documentation/sound/hd-audio/realtek-pc-beep.rst for details of 3276 + * this register. 3277 + */ 3278 + alc_write_coef_idx(codec, 0x36, 0x5757); 3372 3279 } 3373 3280 3374 3281 static void alc256_shutup(struct hda_codec *codec) ··· 3477 3372 3478 3373 if (!hp_pin) 3479 3374 hp_pin = 0x21; 3375 + 3376 + alc_disable_headset_jack_key(codec); 3480 3377 /* 3k pull low control for Headset jack. */ 3481 3378 alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); 3482 3379 ··· 3518 3411 alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4); 3519 3412 msleep(30); 3520 3413 } 3414 + 3415 + alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); 3416 + alc_enable_headset_jack_key(codec); 3521 3417 } 3522 3418 3523 3419 static void alc_default_init(struct hda_codec *codec) ··· 4116 4006 const struct hda_fixup *fix, int action) 4117 4007 { 4118 4008 alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10); 4009 + } 4010 + 4011 + static void alc285_fixup_hp_gpio_led(struct hda_codec *codec, 4012 + const struct hda_fixup *fix, int action) 4013 + { 4014 + alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00); 4119 4015 } 4120 4016 4121 4017 static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, ··· 5491 5375 } 5492 5376 } 5493 5377 5494 - static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec, 5495 - const struct hda_fixup *fix, 5496 - int action) 5497 - { 5498 - if (action != HDA_FIXUP_ACT_PRE_PROBE) 5499 - return; 5500 - 5501 - snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1); 5502 - snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP); 5503 - } 5504 - 5505 5378 static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, 5506 5379 const struct hda_fixup *fix, 5507 5380 int action) ··· 5767 5662 snd_hda_override_wcaps(codec, 0x03, 0); 5768 5663 } 5769 5664 5770 - static const struct hda_jack_keymap alc_headset_btn_keymap[] = { 5771 - { SND_JACK_BTN_0, KEY_PLAYPAUSE }, 5772 - { SND_JACK_BTN_1, KEY_VOICECOMMAND }, 5773 - { SND_JACK_BTN_2, KEY_VOLUMEUP }, 5774 - { SND_JACK_BTN_3, KEY_VOLUMEDOWN }, 5775 - {} 5776 - }; 5777 - 5778 - static void alc_headset_btn_callback(struct hda_codec *codec, 5779 - struct hda_jack_callback *jack) 5780 - { 5781 - int report = 0; 5782 - 5783 - if (jack->unsol_res & (7 << 13)) 5784 - report |= SND_JACK_BTN_0; 5785 - 5786 - if (jack->unsol_res & (1 << 16 | 3 << 8)) 5787 - report |= SND_JACK_BTN_1; 5788 - 5789 - /* Volume up key */ 5790 - if (jack->unsol_res & (7 << 23)) 5791 - report |= SND_JACK_BTN_2; 5792 - 5793 - /* Volume down key */ 5794 - if (jack->unsol_res & (7 << 10)) 5795 - report |= SND_JACK_BTN_3; 5796 - 5797 - jack->jack->button_state = report; 5798 - } 5799 - 5800 - static void alc_fixup_headset_jack(struct hda_codec *codec, 5801 - const struct hda_fixup *fix, int action) 5802 - { 5803 - 5804 - switch (action) { 5805 - case HDA_FIXUP_ACT_PRE_PROBE: 5806 - snd_hda_jack_detect_enable_callback(codec, 0x55, 5807 - alc_headset_btn_callback); 5808 - snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, 5809 - SND_JACK_HEADSET, alc_headset_btn_keymap); 5810 - break; 5811 - case HDA_FIXUP_ACT_INIT: 5812 - switch (codec->core.vendor_id) { 5813 - case 0x10ec0215: 5814 - case 0x10ec0225: 5815 - case 0x10ec0285: 5816 - case 0x10ec0295: 5817 - case 0x10ec0289: 5818 - case 0x10ec0299: 5819 - alc_write_coef_idx(codec, 0x48, 0xd011); 5820 - alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045); 5821 - alc_update_coef_idx(codec, 0x44, 0x007f << 8, 0x0045 << 8); 5822 - break; 5823 - case 0x10ec0236: 5824 - case 0x10ec0256: 5825 - alc_write_coef_idx(codec, 0x48, 0xd011); 5826 - alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045); 5827 - break; 5828 - } 5829 - break; 5830 - } 5831 - } 5832 - 5833 5665 static void alc295_fixup_chromebook(struct hda_codec *codec, 5834 5666 const struct hda_fixup *fix, int action) 5835 5667 { ··· 5905 5863 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, 5906 5864 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, 5907 5865 ALC275_FIXUP_DELL_XPS, 5908 - ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, 5909 - ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2, 5910 5866 ALC293_FIXUP_LENOVO_SPK_NOISE, 5911 5867 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, 5912 5868 ALC255_FIXUP_DELL_SPK_NOISE, ··· 5963 5923 ALC294_FIXUP_ASUS_DUAL_SPK, 5964 5924 ALC285_FIXUP_THINKPAD_HEADSET_JACK, 5965 5925 ALC294_FIXUP_ASUS_HPE, 5926 + ALC285_FIXUP_HP_GPIO_LED, 5966 5927 }; 5967 5928 5968 5929 static const struct hda_fixup alc269_fixups[] = { ··· 6645 6604 {} 6646 6605 } 6647 6606 }, 6648 - [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = { 6649 - .type = HDA_FIXUP_VERBS, 6650 - .v.verbs = (const struct hda_verb[]) { 6651 - /* Disable pass-through path for FRONT 14h */ 6652 - {0x20, AC_VERB_SET_COEF_INDEX, 0x36}, 6653 - {0x20, AC_VERB_SET_PROC_COEF, 0x1737}, 6654 - {} 6655 - }, 6656 - .chained = true, 6657 - .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE 6658 - }, 6659 - [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2] = { 6660 - .type = HDA_FIXUP_FUNC, 6661 - .v.func = alc256_fixup_dell_xps_13_headphone_noise2, 6662 - .chained = true, 6663 - .chain_id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE 6664 - }, 6665 6607 [ALC293_FIXUP_LENOVO_SPK_NOISE] = { 6666 6608 .type = HDA_FIXUP_FUNC, 6667 6609 .v.func = alc_fixup_disable_aamix, ··· 7085 7061 .chained = true, 7086 7062 .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC 7087 7063 }, 7064 + [ALC285_FIXUP_HP_GPIO_LED] = { 7065 + .type = HDA_FIXUP_FUNC, 7066 + .v.func = alc285_fixup_hp_gpio_led, 7067 + }, 7088 7068 }; 7089 7069 7090 7070 static const struct snd_pci_quirk alc269_fixup_tbl[] = { ··· 7142 7114 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 7143 7115 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 7144 7116 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), 7145 - SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), 7146 7117 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), 7147 7118 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), 7148 7119 SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP), 7149 - SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), 7150 7120 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME), 7151 7121 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), 7152 7122 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3), 7153 7123 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), 7154 7124 SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE), 7155 - SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), 7156 7125 SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), 7157 7126 SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), 7158 7127 SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), ··· 7233 7208 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), 7234 7209 SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), 7235 7210 SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), 7211 + SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED), 7236 7212 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), 7237 7213 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 7238 7214 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ··· 7503 7477 {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"}, 7504 7478 {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"}, 7505 7479 {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"}, 7506 - {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"}, 7507 7480 {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"}, 7508 7481 {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"}, 7509 7482 {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
+1 -1
sound/pci/korg1212/korg1212.c
··· 30 30 #if K1212_DEBUG_LEVEL > 0 31 31 #define K1212_DEBUG_PRINTK(fmt,args...) printk(KERN_DEBUG fmt,##args) 32 32 #else 33 - #define K1212_DEBUG_PRINTK(fmt,...) 33 + #define K1212_DEBUG_PRINTK(fmt,...) do { } while (0) 34 34 #endif 35 35 #if K1212_DEBUG_LEVEL > 1 36 36 #define K1212_DEBUG_PRINTK_VERBOSE(fmt,args...) printk(KERN_DEBUG fmt,##args)
+2 -1
sound/pci/rme9652/hdsp.c
··· 3353 3353 return; 3354 3354 } 3355 3355 } else { 3356 - int err = -EINVAL; 3356 + int err; 3357 + 3357 3358 err = hdsp_request_fw_loader(hdsp); 3358 3359 if (err < 0) { 3359 3360 snd_iprintf(buffer,
+4 -2
sound/pci/via82xx.c
··· 414 414 { 415 415 unsigned int i, idx, ofs, rest; 416 416 struct via82xx *chip = snd_pcm_substream_chip(substream); 417 + __le32 *pgtbl; 417 418 418 419 if (dev->table.area == NULL) { 419 420 /* the start of each lists must be aligned to 8 bytes, ··· 436 435 /* fill the entries */ 437 436 idx = 0; 438 437 ofs = 0; 438 + pgtbl = (__le32 *)dev->table.area; 439 439 for (i = 0; i < periods; i++) { 440 440 rest = fragsize; 441 441 /* fill descriptors for a period. ··· 453 451 return -EINVAL; 454 452 } 455 453 addr = snd_pcm_sgbuf_get_addr(substream, ofs); 456 - ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr); 454 + pgtbl[idx << 1] = cpu_to_le32(addr); 457 455 r = snd_pcm_sgbuf_get_chunk_size(substream, ofs, rest); 458 456 rest -= r; 459 457 if (! rest) { ··· 468 466 "tbl %d: at %d size %d (rest %d)\n", 469 467 idx, ofs, r, rest); 470 468 */ 471 - ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag); 469 + pgtbl[(idx<<1) + 1] = cpu_to_le32(r | flag); 472 470 dev->idx_table[idx].offset = ofs; 473 471 dev->idx_table[idx].size = r; 474 472 ofs += r;
+4 -2
sound/pci/via82xx_modem.c
··· 267 267 { 268 268 unsigned int i, idx, ofs, rest; 269 269 struct via82xx_modem *chip = snd_pcm_substream_chip(substream); 270 + __le32 *pgtbl; 270 271 271 272 if (dev->table.area == NULL) { 272 273 /* the start of each lists must be aligned to 8 bytes, ··· 289 288 /* fill the entries */ 290 289 idx = 0; 291 290 ofs = 0; 291 + pgtbl = (__le32 *)dev->table.area; 292 292 for (i = 0; i < periods; i++) { 293 293 rest = fragsize; 294 294 /* fill descriptors for a period. ··· 306 304 return -EINVAL; 307 305 } 308 306 addr = snd_pcm_sgbuf_get_addr(substream, ofs); 309 - ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr); 307 + pgtbl[idx << 1] = cpu_to_le32(addr); 310 308 r = PAGE_SIZE - (ofs % PAGE_SIZE); 311 309 if (rest < r) 312 310 r = rest; ··· 323 321 "tbl %d: at %d size %d (rest %d)\n", 324 322 idx, ofs, r, rest); 325 323 */ 326 - ((u32 *)dev->table.area)[(idx<<1) + 1] = cpu_to_le32(r | flag); 324 + pgtbl[(idx<<1) + 1] = cpu_to_le32(r | flag); 327 325 dev->idx_table[idx].offset = ofs; 328 326 dev->idx_table[idx].size = r; 329 327 ofs += r;
+6 -3
sound/ppc/keywest.c
··· 40 40 static int keywest_attach_adapter(struct i2c_adapter *adapter) 41 41 { 42 42 struct i2c_board_info info; 43 + struct i2c_client *client; 43 44 44 45 if (! keywest_ctx) 45 46 return -EINVAL; ··· 51 50 memset(&info, 0, sizeof(struct i2c_board_info)); 52 51 strlcpy(info.type, "keywest", I2C_NAME_SIZE); 53 52 info.addr = keywest_ctx->addr; 54 - keywest_ctx->client = i2c_new_device(adapter, &info); 55 - if (!keywest_ctx->client) 56 - return -ENODEV; 53 + client = i2c_new_client_device(adapter, &info); 54 + if (IS_ERR(client)) 55 + return PTR_ERR(client); 56 + keywest_ctx->client = client; 57 + 57 58 /* 58 59 * We know the driver is already loaded, so the device should be 59 60 * already bound. If not it means binding failed, and then there
+10
sound/soc/amd/Kconfig
··· 26 26 depends on X86 && PCI 27 27 help 28 28 This option enables ACP v3.x I2S support on AMD platform 29 + 30 + config SND_SOC_AMD_RV_RT5682_MACH 31 + tristate "AMD RV support for RT5682" 32 + select SND_SOC_RT5682 33 + select SND_SOC_MAX98357A 34 + select SND_SOC_CROS_EC_CODEC 35 + select I2C_CROS_EC_TUNNEL 36 + depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC 37 + help 38 + This option enables machine driver for RT5682 and MAX9835.
+2
sound/soc/amd/Makefile
··· 2 2 acp_audio_dma-objs := acp-pcm-dma.o 3 3 snd-soc-acp-da7219mx98357-mach-objs := acp-da7219-max98357a.o 4 4 snd-soc-acp-rt5645-mach-objs := acp-rt5645.o 5 + snd-soc-acp-rt5682-mach-objs := acp3x-rt5682-max9836.o 5 6 6 7 obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o 7 8 obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o 8 9 obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o 9 10 obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/ 11 + obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
+1 -1
sound/soc/amd/acp-da7219-max98357a.c
··· 54 54 { 55 55 int ret; 56 56 struct snd_soc_card *card = rtd->card; 57 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 57 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 58 58 struct snd_soc_component *component = codec_dai->component; 59 59 60 60 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+2 -2
sound/soc/amd/acp-rt5645.c
··· 48 48 { 49 49 int ret = 0; 50 50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 51 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 51 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 52 52 53 53 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK, 54 54 CZ_PLAT_CLK, params_rate(params) * 512); ··· 73 73 struct snd_soc_card *card; 74 74 struct snd_soc_component *codec; 75 75 76 - codec = rtd->codec_dai->component; 76 + codec = asoc_rtd_to_codec(rtd, 0)->component; 77 77 card = rtd->card; 78 78 79 79 ret = snd_soc_card_jack_new(card, "Headset Jack",
+376
sound/soc/amd/acp3x-rt5682-max9836.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // 3 + // Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec. 4 + // 5 + //Copyright 2016 Advanced Micro Devices, Inc. 6 + 7 + #include <sound/core.h> 8 + #include <sound/soc.h> 9 + #include <sound/pcm.h> 10 + #include <sound/pcm_params.h> 11 + #include <sound/soc-dapm.h> 12 + #include <sound/jack.h> 13 + #include <linux/clk.h> 14 + #include <linux/gpio.h> 15 + #include <linux/gpio/consumer.h> 16 + #include <linux/module.h> 17 + #include <linux/i2c.h> 18 + #include <linux/input.h> 19 + #include <linux/io.h> 20 + #include <linux/acpi.h> 21 + 22 + #include "raven/acp3x.h" 23 + #include "../codecs/rt5682.h" 24 + 25 + #define PCO_PLAT_CLK 48000000 26 + #define RT5682_PLL_FREQ (48000 * 512) 27 + #define DUAL_CHANNEL 2 28 + 29 + static struct snd_soc_jack pco_jack; 30 + static struct clk *rt5682_dai_wclk; 31 + static struct clk *rt5682_dai_bclk; 32 + static struct gpio_desc *dmic_sel; 33 + 34 + static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd) 35 + { 36 + int ret; 37 + struct snd_soc_card *card = rtd->card; 38 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 39 + struct snd_soc_component *component = codec_dai->component; 40 + 41 + dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); 42 + 43 + /* set rt5682 dai fmt */ 44 + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S 45 + | SND_SOC_DAIFMT_NB_NF 46 + | SND_SOC_DAIFMT_CBM_CFM); 47 + if (ret < 0) { 48 + dev_err(rtd->card->dev, 49 + "Failed to set rt5682 dai fmt: %d\n", ret); 50 + return ret; 51 + } 52 + 53 + /* set codec PLL */ 54 + ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK, 55 + PCO_PLAT_CLK, RT5682_PLL_FREQ); 56 + if (ret < 0) { 57 + dev_err(rtd->dev, "can't set rt5682 PLL: %d\n", ret); 58 + return ret; 59 + } 60 + 61 + /* Set codec sysclk */ 62 + ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2, 63 + RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); 64 + if (ret < 0) { 65 + dev_err(rtd->dev, 66 + "Failed to set rt5682 SYSCLK: %d\n", ret); 67 + return ret; 68 + } 69 + 70 + /* Set tdm/i2s1 master bclk ratio */ 71 + ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); 72 + if (ret < 0) { 73 + dev_err(rtd->dev, 74 + "Failed to set rt5682 tdm bclk ratio: %d\n", ret); 75 + return ret; 76 + } 77 + 78 + rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk"); 79 + rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk"); 80 + 81 + ret = snd_soc_card_jack_new(card, "Headset Jack", 82 + SND_JACK_HEADSET | SND_JACK_LINEOUT | 83 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 84 + SND_JACK_BTN_2 | SND_JACK_BTN_3, 85 + &pco_jack, NULL, 0); 86 + if (ret) { 87 + dev_err(card->dev, "HP jack creation failed %d\n", ret); 88 + return ret; 89 + } 90 + 91 + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 92 + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); 93 + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 94 + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 95 + 96 + ret = snd_soc_component_set_jack(component, &pco_jack, NULL); 97 + if (ret) { 98 + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); 99 + return ret; 100 + } 101 + 102 + return ret; 103 + } 104 + 105 + static int rt5682_clk_enable(struct snd_pcm_substream *substream) 106 + { 107 + int ret = 0; 108 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 + 110 + /* RT5682 will support only 48K output with 48M mclk */ 111 + clk_set_rate(rt5682_dai_wclk, 48000); 112 + clk_set_rate(rt5682_dai_bclk, 48000 * 64); 113 + ret = clk_prepare_enable(rt5682_dai_wclk); 114 + if (ret < 0) { 115 + dev_err(rtd->dev, "can't enable wclk %d\n", ret); 116 + return ret; 117 + } 118 + 119 + return ret; 120 + } 121 + 122 + static void rt5682_clk_disable(void) 123 + { 124 + clk_disable_unprepare(rt5682_dai_wclk); 125 + } 126 + 127 + static const unsigned int channels[] = { 128 + DUAL_CHANNEL, 129 + }; 130 + 131 + static const unsigned int rates[] = { 132 + 48000, 133 + }; 134 + 135 + static const struct snd_pcm_hw_constraint_list constraints_rates = { 136 + .count = ARRAY_SIZE(rates), 137 + .list = rates, 138 + .mask = 0, 139 + }; 140 + 141 + static const struct snd_pcm_hw_constraint_list constraints_channels = { 142 + .count = ARRAY_SIZE(channels), 143 + .list = channels, 144 + .mask = 0, 145 + }; 146 + 147 + static int acp3x_5682_startup(struct snd_pcm_substream *substream) 148 + { 149 + struct snd_pcm_runtime *runtime = substream->runtime; 150 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 151 + struct snd_soc_card *card = rtd->card; 152 + struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card); 153 + 154 + machine->play_i2s_instance = I2S_SP_INSTANCE; 155 + machine->cap_i2s_instance = I2S_SP_INSTANCE; 156 + 157 + runtime->hw.channels_max = DUAL_CHANNEL; 158 + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 159 + &constraints_channels); 160 + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 161 + &constraints_rates); 162 + return rt5682_clk_enable(substream); 163 + } 164 + 165 + static int acp3x_max_startup(struct snd_pcm_substream *substream) 166 + { 167 + struct snd_pcm_runtime *runtime = substream->runtime; 168 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 169 + struct snd_soc_card *card = rtd->card; 170 + struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card); 171 + 172 + machine->play_i2s_instance = I2S_BT_INSTANCE; 173 + 174 + runtime->hw.channels_max = DUAL_CHANNEL; 175 + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 176 + &constraints_channels); 177 + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 178 + &constraints_rates); 179 + return rt5682_clk_enable(substream); 180 + } 181 + 182 + static int acp3x_ec_dmic0_startup(struct snd_pcm_substream *substream) 183 + { 184 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 185 + struct snd_soc_card *card = rtd->card; 186 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 187 + struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card); 188 + 189 + machine->cap_i2s_instance = I2S_BT_INSTANCE; 190 + snd_soc_dai_set_bclk_ratio(codec_dai, 64); 191 + if (dmic_sel) 192 + gpiod_set_value(dmic_sel, 0); 193 + 194 + return rt5682_clk_enable(substream); 195 + } 196 + 197 + static int acp3x_ec_dmic1_startup(struct snd_pcm_substream *substream) 198 + { 199 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 200 + struct snd_soc_card *card = rtd->card; 201 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 202 + struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card); 203 + 204 + machine->cap_i2s_instance = I2S_BT_INSTANCE; 205 + snd_soc_dai_set_bclk_ratio(codec_dai, 64); 206 + if (dmic_sel) 207 + gpiod_set_value(dmic_sel, 1); 208 + 209 + return rt5682_clk_enable(substream); 210 + } 211 + 212 + static void rt5682_shutdown(struct snd_pcm_substream *substream) 213 + { 214 + rt5682_clk_disable(); 215 + } 216 + 217 + static const struct snd_soc_ops acp3x_5682_ops = { 218 + .startup = acp3x_5682_startup, 219 + .shutdown = rt5682_shutdown, 220 + }; 221 + 222 + static const struct snd_soc_ops acp3x_max_play_ops = { 223 + .startup = acp3x_max_startup, 224 + .shutdown = rt5682_shutdown, 225 + }; 226 + 227 + static const struct snd_soc_ops acp3x_ec_cap0_ops = { 228 + .startup = acp3x_ec_dmic0_startup, 229 + .shutdown = rt5682_shutdown, 230 + }; 231 + 232 + static const struct snd_soc_ops acp3x_ec_cap1_ops = { 233 + .startup = acp3x_ec_dmic1_startup, 234 + .shutdown = rt5682_shutdown, 235 + }; 236 + 237 + SND_SOC_DAILINK_DEF(acp3x_i2s, 238 + DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0"))); 239 + SND_SOC_DAILINK_DEF(acp3x_bt, 240 + DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.2"))); 241 + 242 + SND_SOC_DAILINK_DEF(rt5682, 243 + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1"))); 244 + SND_SOC_DAILINK_DEF(max, 245 + DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi"))); 246 + SND_SOC_DAILINK_DEF(cros_ec, 247 + DAILINK_COMP_ARRAY(COMP_CODEC("GOOG0013:00", "EC Codec I2S RX"))); 248 + 249 + SND_SOC_DAILINK_DEF(platform, 250 + DAILINK_COMP_ARRAY(COMP_PLATFORM("acp3x_rv_i2s_dma.0"))); 251 + 252 + static struct snd_soc_dai_link acp3x_dai_5682_98357[] = { 253 + { 254 + .name = "acp3x-5682-play", 255 + .stream_name = "Playback", 256 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 257 + | SND_SOC_DAIFMT_CBM_CFM, 258 + .init = acp3x_5682_init, 259 + .dpcm_playback = 1, 260 + .dpcm_capture = 1, 261 + .ops = &acp3x_5682_ops, 262 + SND_SOC_DAILINK_REG(acp3x_i2s, rt5682, platform), 263 + }, 264 + { 265 + .name = "acp3x-max98357-play", 266 + .stream_name = "HiFi Playback", 267 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 268 + | SND_SOC_DAIFMT_CBM_CFM, 269 + .dpcm_playback = 1, 270 + .ops = &acp3x_max_play_ops, 271 + SND_SOC_DAILINK_REG(acp3x_bt, max, platform), 272 + }, 273 + { 274 + .name = "acp3x-ec-dmic0-capture", 275 + .stream_name = "Capture DMIC0", 276 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 277 + | SND_SOC_DAIFMT_CBS_CFS, 278 + .dpcm_capture = 1, 279 + .ops = &acp3x_ec_cap0_ops, 280 + SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform), 281 + }, 282 + { 283 + .name = "acp3x-ec-dmic1-capture", 284 + .stream_name = "Capture DMIC1", 285 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 286 + | SND_SOC_DAIFMT_CBS_CFS, 287 + .dpcm_capture = 1, 288 + .ops = &acp3x_ec_cap1_ops, 289 + SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform), 290 + }, 291 + }; 292 + 293 + static const struct snd_soc_dapm_widget acp3x_widgets[] = { 294 + SND_SOC_DAPM_HP("Headphone Jack", NULL), 295 + SND_SOC_DAPM_SPK("Spk", NULL), 296 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 297 + }; 298 + 299 + static const struct snd_soc_dapm_route acp3x_audio_route[] = { 300 + {"Headphone Jack", NULL, "HPOL"}, 301 + {"Headphone Jack", NULL, "HPOR"}, 302 + {"IN1P", NULL, "Headset Mic"}, 303 + {"Spk", NULL, "Speaker"}, 304 + }; 305 + 306 + static const struct snd_kcontrol_new acp3x_mc_controls[] = { 307 + SOC_DAPM_PIN_SWITCH("Headphone Jack"), 308 + SOC_DAPM_PIN_SWITCH("Spk"), 309 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 310 + }; 311 + 312 + static struct snd_soc_card acp3x_card = { 313 + .name = "acp3xalc5682m98357", 314 + .owner = THIS_MODULE, 315 + .dai_link = acp3x_dai_5682_98357, 316 + .num_links = ARRAY_SIZE(acp3x_dai_5682_98357), 317 + .dapm_widgets = acp3x_widgets, 318 + .num_dapm_widgets = ARRAY_SIZE(acp3x_widgets), 319 + .dapm_routes = acp3x_audio_route, 320 + .num_dapm_routes = ARRAY_SIZE(acp3x_audio_route), 321 + .controls = acp3x_mc_controls, 322 + .num_controls = ARRAY_SIZE(acp3x_mc_controls), 323 + }; 324 + 325 + static int acp3x_probe(struct platform_device *pdev) 326 + { 327 + int ret; 328 + struct snd_soc_card *card; 329 + struct acp3x_platform_info *machine; 330 + 331 + machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL); 332 + if (!machine) 333 + return -ENOMEM; 334 + 335 + card = &acp3x_card; 336 + acp3x_card.dev = &pdev->dev; 337 + platform_set_drvdata(pdev, card); 338 + snd_soc_card_set_drvdata(card, machine); 339 + 340 + dmic_sel = devm_gpiod_get(&pdev->dev, "dmic", GPIOD_OUT_LOW); 341 + if (IS_ERR(dmic_sel)) { 342 + dev_err(&pdev->dev, "DMIC gpio failed err=%ld\n", 343 + PTR_ERR(dmic_sel)); 344 + return PTR_ERR(dmic_sel); 345 + } 346 + 347 + ret = devm_snd_soc_register_card(&pdev->dev, &acp3x_card); 348 + if (ret) { 349 + dev_err(&pdev->dev, 350 + "devm_snd_soc_register_card(%s) failed: %d\n", 351 + acp3x_card.name, ret); 352 + return ret; 353 + } 354 + return 0; 355 + } 356 + 357 + static const struct acpi_device_id acp3x_audio_acpi_match[] = { 358 + { "AMDI5682", 0 }, 359 + {}, 360 + }; 361 + MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match); 362 + 363 + static struct platform_driver acp3x_audio = { 364 + .driver = { 365 + .name = "acp3x-alc5682-max98357", 366 + .acpi_match_table = ACPI_PTR(acp3x_audio_acpi_match), 367 + .pm = &snd_soc_pm_ops, 368 + }, 369 + .probe = acp3x_probe, 370 + }; 371 + 372 + module_platform_driver(acp3x_audio); 373 + 374 + MODULE_AUTHOR("akshu.agrawal@amd.com"); 375 + MODULE_DESCRIPTION("ALC5682 & MAX98357 audio support"); 376 + MODULE_LICENSE("GPL v2");
+13 -31
sound/soc/amd/raven/acp3x-i2s.c
··· 42 42 u32 tx_mask, u32 rx_mask, int slots, int slot_width) 43 43 { 44 44 struct i2s_dev_data *adata; 45 - u32 val, reg_val, frmt_reg, frm_len; 45 + u32 frm_len; 46 46 u16 slot_len; 47 47 48 48 adata = snd_soc_dai_get_drvdata(cpu_dai); ··· 64 64 default: 65 65 return -EINVAL; 66 66 } 67 - 68 - /* Enable I2S/BT channels TDM, respective TX/RX frame lengths.*/ 69 - 70 67 frm_len = FRM_LEN | (slots << 15) | (slot_len << 18); 71 - if (adata->substream_type == SNDRV_PCM_STREAM_PLAYBACK) { 72 - switch (adata->i2s_instance) { 73 - case I2S_BT_INSTANCE: 74 - reg_val = mmACP_BTTDM_ITER; 75 - frmt_reg = mmACP_BTTDM_TXFRMT; 76 - break; 77 - case I2S_SP_INSTANCE: 78 - default: 79 - reg_val = mmACP_I2STDM_ITER; 80 - frmt_reg = mmACP_I2STDM_TXFRMT; 81 - } 82 - } else { 83 - switch (adata->i2s_instance) { 84 - case I2S_BT_INSTANCE: 85 - reg_val = mmACP_BTTDM_IRER; 86 - frmt_reg = mmACP_BTTDM_RXFRMT; 87 - break; 88 - case I2S_SP_INSTANCE: 89 - default: 90 - reg_val = mmACP_I2STDM_IRER; 91 - frmt_reg = mmACP_I2STDM_RXFRMT; 92 - } 93 - } 94 - val = rv_readl(adata->acp3x_base + reg_val); 95 - rv_writel(val | 0x2, adata->acp3x_base + reg_val); 96 - rv_writel(frm_len, adata->acp3x_base + frmt_reg); 97 68 adata->tdm_fmt = frm_len; 98 69 return 0; 99 70 } ··· 76 105 struct snd_soc_pcm_runtime *prtd; 77 106 struct snd_soc_card *card; 78 107 struct acp3x_platform_info *pinfo; 108 + struct i2s_dev_data *adata; 79 109 u32 val; 80 - u32 reg_val; 110 + u32 reg_val, frmt_reg; 81 111 82 112 prtd = substream->private_data; 83 113 rtd = substream->runtime->private_data; 84 114 card = prtd->card; 115 + adata = snd_soc_dai_get_drvdata(dai); 85 116 pinfo = snd_soc_card_get_drvdata(card); 86 117 if (pinfo) { 87 118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ··· 114 141 switch (rtd->i2s_instance) { 115 142 case I2S_BT_INSTANCE: 116 143 reg_val = mmACP_BTTDM_ITER; 144 + frmt_reg = mmACP_BTTDM_TXFRMT; 117 145 break; 118 146 case I2S_SP_INSTANCE: 119 147 default: 120 148 reg_val = mmACP_I2STDM_ITER; 149 + frmt_reg = mmACP_I2STDM_TXFRMT; 121 150 } 122 151 } else { 123 152 switch (rtd->i2s_instance) { 124 153 case I2S_BT_INSTANCE: 125 154 reg_val = mmACP_BTTDM_IRER; 155 + frmt_reg = mmACP_BTTDM_RXFRMT; 126 156 break; 127 157 case I2S_SP_INSTANCE: 128 158 default: 129 159 reg_val = mmACP_I2STDM_IRER; 160 + frmt_reg = mmACP_I2STDM_RXFRMT; 130 161 } 162 + } 163 + if (adata->tdm_mode) { 164 + val = rv_readl(rtd->acp3x_base + reg_val); 165 + rv_writel(val | 0x2, rtd->acp3x_base + reg_val); 166 + rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg); 131 167 } 132 168 val = rv_readl(rtd->acp3x_base + reg_val); 133 169 val = val | (rtd->xfer_resolution << 3);
+4 -2
sound/soc/amd/raven/acp3x-pcm-dma.c
··· 458 458 reg_val = mmACP_I2STDM_ITER; 459 459 frmt_val = mmACP_I2STDM_TXFRMT; 460 460 } 461 - rv_writel((rtd->xfer_resolution << 3), rtd->acp3x_base + reg_val); 461 + rv_writel((rtd->xfer_resolution << 3), 462 + rtd->acp3x_base + reg_val); 462 463 } 463 464 if (adata->capture_stream && adata->capture_stream->runtime) { 464 465 struct i2s_stream_instance *rtd = ··· 475 474 reg_val = mmACP_I2STDM_IRER; 476 475 frmt_val = mmACP_I2STDM_RXFRMT; 477 476 } 478 - rv_writel((rtd->xfer_resolution << 3), rtd->acp3x_base + reg_val); 477 + rv_writel((rtd->xfer_resolution << 3), 478 + rtd->acp3x_base + reg_val); 479 479 } 480 480 if (adata->tdm_mode == TDM_ENABLE) { 481 481 rv_writel(adata->tdm_fmt, adata->acp3x_base + frmt_val);
+6 -1
sound/soc/amd/raven/pci-acp3x.c
··· 38 38 timeout = 0; 39 39 while (++timeout < 500) { 40 40 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); 41 - if (!val) 41 + if (!val) { 42 + /* Set PME_EN as after ACP power On, 43 + * PME_EN gets cleared 44 + */ 45 + rv_writel(0x1, acp3x_base + mmACP_PME_EN); 42 46 return 0; 47 + } 43 48 udelay(1); 44 49 } 45 50 return -ETIMEDOUT;
+2 -2
sound/soc/atmel/atmel-pcm-dma.c
··· 56 56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 57 57 struct atmel_pcm_dma_params *prtd; 58 58 59 - prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 59 + prtd = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 60 60 61 61 if (ssc_sr & prtd->mask->ssc_error) { 62 62 if (snd_pcm_running(substream)) ··· 83 83 struct ssc_device *ssc; 84 84 int ret; 85 85 86 - prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 86 + prtd = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 87 87 ssc = prtd->ssc; 88 88 89 89 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
+1 -1
sound/soc/atmel/atmel-pcm-pdc.c
··· 213 213 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 214 214 runtime->dma_bytes = params_buffer_bytes(params); 215 215 216 - prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 216 + prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 217 217 prtd->params->dma_intr_handler = atmel_pcm_dma_irq; 218 218 219 219 prtd->dma_buffer = runtime->dma_addr;
+1 -1
sound/soc/atmel/atmel_wm8904.c
··· 27 27 struct snd_pcm_hw_params *params) 28 28 { 29 29 struct snd_soc_pcm_runtime *rtd = substream->private_data; 30 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 30 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 31 31 int ret; 32 32 33 33 ret = snd_soc_dai_set_pll(codec_dai, WM8904_FLL_MCLK, WM8904_FLL_MCLK,
+4 -4
sound/soc/atmel/mchp-i2s-mcc.c
··· 239 239 unsigned int frame_length; 240 240 int tdm_slots; 241 241 int channels; 242 - int gclk_use:1; 243 - int gclk_running:1; 244 - int tx_rdy:1; 245 - int rx_rdy:1; 242 + unsigned int gclk_use:1; 243 + unsigned int gclk_running:1; 244 + unsigned int tx_rdy:1; 245 + unsigned int rx_rdy:1; 246 246 }; 247 247 248 248 static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
+1 -1
sound/soc/atmel/mikroe-proto.c
··· 21 21 static int snd_proto_init(struct snd_soc_pcm_runtime *rtd) 22 22 { 23 23 struct snd_soc_card *card = rtd->card; 24 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 24 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 25 25 26 26 /* Set proto sysclk */ 27 27 int ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
+1 -1
sound/soc/atmel/sam9g20_wm8731.c
··· 96 96 */ 97 97 static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) 98 98 { 99 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 99 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 100 100 struct device *dev = rtd->dev; 101 101 int ret; 102 102
+1 -1
sound/soc/atmel/sam9x5_wm8731.c
··· 40 40 */ 41 41 static int sam9x5_wm8731_init(struct snd_soc_pcm_runtime *rtd) 42 42 { 43 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 43 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 44 44 struct device *dev = rtd->dev; 45 45 int ret; 46 46
+1 -1
sound/soc/au1x/db1200.c
··· 95 95 static int db1200_i2s_startup(struct snd_pcm_substream *substream) 96 96 { 97 97 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 98 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 99 99 100 100 /* WM8731 has its own 12MHz crystal */ 101 101 snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
+1 -1
sound/soc/au1x/dbdma2.c
··· 281 281 struct snd_soc_pcm_runtime *rtd = substream->private_data; 282 282 int stype = substream->stream, *dmaids; 283 283 284 - dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 284 + dmaids = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 285 285 if (!dmaids) 286 286 return -ENODEV; /* whoa, has ordering changed? */ 287 287
+1 -1
sound/soc/au1x/dma.c
··· 195 195 int *dmaids, s = substream->stream; 196 196 char *name; 197 197 198 - dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 198 + dmaids = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 199 199 if (!dmaids) 200 200 return -ENODEV; /* whoa, has ordering changed? */ 201 201
+1 -1
sound/soc/au1x/psc-ac97.c
··· 58 58 static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x) 59 59 { 60 60 struct snd_soc_card *c = x->bus->card->private_data; 61 - return snd_soc_dai_get_drvdata(c->rtd->cpu_dai); 61 + return snd_soc_dai_get_drvdata(c->asoc_rtd_to_cpu(rtd, 0)); 62 62 } 63 63 64 64 #else
+9
sound/soc/bcm/Kconfig
··· 17 17 Cygnus chips (bcm958300, bcm958305, bcm911360) 18 18 19 19 If you don't know what to do here, say N. 20 + 21 + config SND_BCM63XX_I2S_WHISTLER 22 + tristate "SoC Audio support for the Broadcom BCM63XX I2S module" 23 + select REGMAP_MMIO 24 + help 25 + Say Y if you want to add support for ASoC audio on Broadcom 26 + DSL/PON chips (bcm63158, bcm63178) 27 + 28 + If you don't know what to do here, say N
+4
sound/soc/bcm/Makefile
··· 9 9 10 10 obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-cygnus.o 11 11 12 + # BCM63XX Platform Support 13 + snd-soc-63xx-objs := bcm63xx-i2s-whistler.o bcm63xx-pcm-whistler.o 14 + 15 + obj-$(CONFIG_SND_BCM63XX_I2S_WHISTLER) += snd-soc-63xx.o
+317
sound/soc/bcm/bcm63xx-i2s-whistler.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // linux/sound/bcm/bcm63xx-i2s-whistler.c 3 + // BCM63xx whistler i2s driver 4 + // Copyright (c) 2020 Broadcom Corporation 5 + // Author: Kevin-Ke Li <kevin-ke.li@broadcom.com> 6 + 7 + #include <linux/clk.h> 8 + #include <linux/dma-mapping.h> 9 + #include <linux/io.h> 10 + #include <linux/module.h> 11 + #include <linux/regmap.h> 12 + #include <sound/pcm_params.h> 13 + #include <sound/soc.h> 14 + #include "bcm63xx-i2s.h" 15 + 16 + #define DRV_NAME "brcm-i2s" 17 + 18 + static bool brcm_i2s_wr_reg(struct device *dev, unsigned int reg) 19 + { 20 + switch (reg) { 21 + case I2S_TX_CFG ... I2S_TX_DESC_IFF_LEN: 22 + case I2S_TX_CFG_2 ... I2S_RX_DESC_IFF_LEN: 23 + case I2S_RX_CFG_2 ... I2S_REG_MAX: 24 + return true; 25 + default: 26 + return false; 27 + } 28 + } 29 + 30 + static bool brcm_i2s_rd_reg(struct device *dev, unsigned int reg) 31 + { 32 + switch (reg) { 33 + case I2S_TX_CFG ... I2S_REG_MAX: 34 + return true; 35 + default: 36 + return false; 37 + } 38 + } 39 + 40 + static bool brcm_i2s_volatile_reg(struct device *dev, unsigned int reg) 41 + { 42 + switch (reg) { 43 + case I2S_TX_CFG: 44 + case I2S_TX_IRQ_CTL: 45 + case I2S_TX_DESC_IFF_ADDR: 46 + case I2S_TX_DESC_IFF_LEN: 47 + case I2S_TX_DESC_OFF_ADDR: 48 + case I2S_TX_DESC_OFF_LEN: 49 + case I2S_TX_CFG_2: 50 + case I2S_RX_CFG: 51 + case I2S_RX_IRQ_CTL: 52 + case I2S_RX_DESC_OFF_ADDR: 53 + case I2S_RX_DESC_OFF_LEN: 54 + case I2S_RX_DESC_IFF_LEN: 55 + case I2S_RX_DESC_IFF_ADDR: 56 + case I2S_RX_CFG_2: 57 + return true; 58 + default: 59 + return false; 60 + } 61 + } 62 + 63 + static const struct regmap_config brcm_i2s_regmap_config = { 64 + .reg_bits = 32, 65 + .reg_stride = 4, 66 + .val_bits = 32, 67 + .max_register = I2S_REG_MAX, 68 + .writeable_reg = brcm_i2s_wr_reg, 69 + .readable_reg = brcm_i2s_rd_reg, 70 + .volatile_reg = brcm_i2s_volatile_reg, 71 + .cache_type = REGCACHE_FLAT, 72 + }; 73 + 74 + static int bcm63xx_i2s_hw_params(struct snd_pcm_substream *substream, 75 + struct snd_pcm_hw_params *params, 76 + struct snd_soc_dai *dai) 77 + { 78 + int ret = 0; 79 + struct bcm_i2s_priv *i2s_priv = snd_soc_dai_get_drvdata(dai); 80 + 81 + ret = clk_set_rate(i2s_priv->i2s_clk, params_rate(params)); 82 + if (ret < 0) 83 + dev_err(i2s_priv->dev, 84 + "Can't set sample rate, err: %d\n", ret); 85 + 86 + return ret; 87 + } 88 + 89 + static int bcm63xx_i2s_startup(struct snd_pcm_substream *substream, 90 + struct snd_soc_dai *dai) 91 + { 92 + unsigned int slavemode; 93 + struct bcm_i2s_priv *i2s_priv = snd_soc_dai_get_drvdata(dai); 94 + struct regmap *regmap_i2s = i2s_priv->regmap_i2s; 95 + 96 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 97 + regmap_update_bits(regmap_i2s, I2S_TX_CFG, 98 + I2S_TX_OUT_R | I2S_TX_DATA_ALIGNMENT | 99 + I2S_TX_DATA_ENABLE | I2S_TX_CLOCK_ENABLE, 100 + I2S_TX_OUT_R | I2S_TX_DATA_ALIGNMENT | 101 + I2S_TX_DATA_ENABLE | I2S_TX_CLOCK_ENABLE); 102 + regmap_write(regmap_i2s, I2S_TX_IRQ_CTL, 0); 103 + regmap_write(regmap_i2s, I2S_TX_IRQ_IFF_THLD, 0); 104 + regmap_write(regmap_i2s, I2S_TX_IRQ_OFF_THLD, 1); 105 + 106 + /* TX and RX block each have an independent bit to indicate 107 + * if it is generating the clock for the I2S bus. The bus 108 + * clocks need to be generated from either the TX or RX block, 109 + * but not both 110 + */ 111 + regmap_read(regmap_i2s, I2S_RX_CFG_2, &slavemode); 112 + if (slavemode & I2S_RX_SLAVE_MODE_MASK) 113 + regmap_update_bits(regmap_i2s, I2S_TX_CFG_2, 114 + I2S_TX_SLAVE_MODE_MASK, 115 + I2S_TX_MASTER_MODE); 116 + else 117 + regmap_update_bits(regmap_i2s, I2S_TX_CFG_2, 118 + I2S_TX_SLAVE_MODE_MASK, 119 + I2S_TX_SLAVE_MODE); 120 + } else { 121 + regmap_update_bits(regmap_i2s, I2S_RX_CFG, 122 + I2S_RX_IN_R | I2S_RX_DATA_ALIGNMENT | 123 + I2S_RX_CLOCK_ENABLE, 124 + I2S_RX_IN_R | I2S_RX_DATA_ALIGNMENT | 125 + I2S_RX_CLOCK_ENABLE); 126 + regmap_write(regmap_i2s, I2S_RX_IRQ_CTL, 0); 127 + regmap_write(regmap_i2s, I2S_RX_IRQ_IFF_THLD, 0); 128 + regmap_write(regmap_i2s, I2S_RX_IRQ_OFF_THLD, 1); 129 + 130 + regmap_read(regmap_i2s, I2S_TX_CFG_2, &slavemode); 131 + if (slavemode & I2S_TX_SLAVE_MODE_MASK) 132 + regmap_update_bits(regmap_i2s, I2S_RX_CFG_2, 133 + I2S_RX_SLAVE_MODE_MASK, 0); 134 + else 135 + regmap_update_bits(regmap_i2s, I2S_RX_CFG_2, 136 + I2S_RX_SLAVE_MODE_MASK, 137 + I2S_RX_SLAVE_MODE); 138 + } 139 + return 0; 140 + } 141 + 142 + static void bcm63xx_i2s_shutdown(struct snd_pcm_substream *substream, 143 + struct snd_soc_dai *dai) 144 + { 145 + unsigned int enabled, slavemode; 146 + struct bcm_i2s_priv *i2s_priv = snd_soc_dai_get_drvdata(dai); 147 + struct regmap *regmap_i2s = i2s_priv->regmap_i2s; 148 + 149 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 150 + regmap_update_bits(regmap_i2s, I2S_TX_CFG, 151 + I2S_TX_OUT_R | I2S_TX_DATA_ALIGNMENT | 152 + I2S_TX_DATA_ENABLE | I2S_TX_CLOCK_ENABLE, 0); 153 + regmap_write(regmap_i2s, I2S_TX_IRQ_CTL, 1); 154 + regmap_write(regmap_i2s, I2S_TX_IRQ_IFF_THLD, 4); 155 + regmap_write(regmap_i2s, I2S_TX_IRQ_OFF_THLD, 4); 156 + 157 + regmap_read(regmap_i2s, I2S_TX_CFG_2, &slavemode); 158 + slavemode = slavemode & I2S_TX_SLAVE_MODE_MASK; 159 + if (!slavemode) { 160 + regmap_read(regmap_i2s, I2S_RX_CFG, &enabled); 161 + enabled = enabled & I2S_RX_ENABLE_MASK; 162 + if (enabled) 163 + regmap_update_bits(regmap_i2s, I2S_RX_CFG_2, 164 + I2S_RX_SLAVE_MODE_MASK, 165 + I2S_RX_MASTER_MODE); 166 + } 167 + regmap_update_bits(regmap_i2s, I2S_TX_CFG_2, 168 + I2S_TX_SLAVE_MODE_MASK, 169 + I2S_TX_SLAVE_MODE); 170 + } else { 171 + regmap_update_bits(regmap_i2s, I2S_RX_CFG, 172 + I2S_RX_IN_R | I2S_RX_DATA_ALIGNMENT | 173 + I2S_RX_CLOCK_ENABLE, 0); 174 + regmap_write(regmap_i2s, I2S_RX_IRQ_CTL, 1); 175 + regmap_write(regmap_i2s, I2S_RX_IRQ_IFF_THLD, 4); 176 + regmap_write(regmap_i2s, I2S_RX_IRQ_OFF_THLD, 4); 177 + 178 + regmap_read(regmap_i2s, I2S_RX_CFG_2, &slavemode); 179 + slavemode = slavemode & I2S_RX_SLAVE_MODE_MASK; 180 + if (!slavemode) { 181 + regmap_read(regmap_i2s, I2S_TX_CFG, &enabled); 182 + enabled = enabled & I2S_TX_ENABLE_MASK; 183 + if (enabled) 184 + regmap_update_bits(regmap_i2s, I2S_TX_CFG_2, 185 + I2S_TX_SLAVE_MODE_MASK, 186 + I2S_TX_MASTER_MODE); 187 + } 188 + 189 + regmap_update_bits(regmap_i2s, I2S_RX_CFG_2, 190 + I2S_RX_SLAVE_MODE_MASK, I2S_RX_SLAVE_MODE); 191 + } 192 + } 193 + 194 + static const struct snd_soc_dai_ops bcm63xx_i2s_dai_ops = { 195 + .startup = bcm63xx_i2s_startup, 196 + .shutdown = bcm63xx_i2s_shutdown, 197 + .hw_params = bcm63xx_i2s_hw_params, 198 + }; 199 + 200 + static struct snd_soc_dai_driver bcm63xx_i2s_dai = { 201 + .name = DRV_NAME, 202 + .playback = { 203 + .channels_min = 2, 204 + .channels_max = 2, 205 + .rates = SNDRV_PCM_RATE_8000_192000, 206 + .formats = SNDRV_PCM_FMTBIT_S32_LE, 207 + }, 208 + .capture = { 209 + .channels_min = 2, 210 + .channels_max = 2, 211 + .rates = SNDRV_PCM_RATE_8000_192000, 212 + .formats = SNDRV_PCM_FMTBIT_S32_LE, 213 + }, 214 + .ops = &bcm63xx_i2s_dai_ops, 215 + .symmetric_rates = 1, 216 + .symmetric_channels = 1, 217 + }; 218 + 219 + static const struct snd_soc_component_driver bcm63xx_i2s_component = { 220 + .name = "bcm63xx", 221 + }; 222 + 223 + static int bcm63xx_i2s_dev_probe(struct platform_device *pdev) 224 + { 225 + int ret = 0; 226 + void __iomem *regs; 227 + struct resource *r_mem, *region; 228 + struct bcm_i2s_priv *i2s_priv; 229 + struct regmap *regmap_i2s; 230 + struct clk *i2s_clk; 231 + 232 + i2s_priv = devm_kzalloc(&pdev->dev, sizeof(*i2s_priv), GFP_KERNEL); 233 + if (!i2s_priv) 234 + return -ENOMEM; 235 + 236 + i2s_clk = devm_clk_get(&pdev->dev, "i2sclk"); 237 + if (IS_ERR(i2s_clk)) { 238 + dev_err(&pdev->dev, "%s: cannot get a brcm clock: %ld\n", 239 + __func__, PTR_ERR(i2s_clk)); 240 + return PTR_ERR(i2s_clk); 241 + } 242 + 243 + r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 244 + if (!r_mem) { 245 + dev_err(&pdev->dev, "Unable to get register resource.\n"); 246 + return -ENODEV; 247 + } 248 + 249 + region = devm_request_mem_region(&pdev->dev, r_mem->start, 250 + resource_size(r_mem), DRV_NAME); 251 + if (!region) { 252 + dev_err(&pdev->dev, "Memory region already claimed\n"); 253 + return -EBUSY; 254 + } 255 + 256 + regs = devm_ioremap_resource(&pdev->dev, r_mem); 257 + if (IS_ERR(regs)) { 258 + ret = PTR_ERR(regs); 259 + return ret; 260 + } 261 + 262 + regmap_i2s = devm_regmap_init_mmio(&pdev->dev, 263 + regs, &brcm_i2s_regmap_config); 264 + if (IS_ERR(regmap_i2s)) 265 + return PTR_ERR(regmap_i2s); 266 + 267 + regmap_update_bits(regmap_i2s, I2S_MISC_CFG, 268 + I2S_PAD_LVL_LOOP_DIS_MASK, 269 + I2S_PAD_LVL_LOOP_DIS_ENABLE); 270 + 271 + ret = devm_snd_soc_register_component(&pdev->dev, 272 + &bcm63xx_i2s_component, 273 + &bcm63xx_i2s_dai, 1); 274 + if (ret) { 275 + dev_err(&pdev->dev, "failed to register the dai\n"); 276 + return ret; 277 + } 278 + 279 + i2s_priv->dev = &pdev->dev; 280 + i2s_priv->i2s_clk = i2s_clk; 281 + i2s_priv->regmap_i2s = regmap_i2s; 282 + dev_set_drvdata(&pdev->dev, i2s_priv); 283 + 284 + ret = bcm63xx_soc_platform_probe(pdev, i2s_priv); 285 + if (ret) 286 + dev_err(&pdev->dev, "failed to register the pcm\n"); 287 + 288 + return ret; 289 + } 290 + 291 + static int bcm63xx_i2s_dev_remove(struct platform_device *pdev) 292 + { 293 + bcm63xx_soc_platform_remove(pdev); 294 + return 0; 295 + } 296 + 297 + #ifdef CONFIG_OF 298 + static const struct of_device_id snd_soc_bcm_audio_match[] = { 299 + {.compatible = "brcm,bcm63xx-i2s"}, 300 + { } 301 + }; 302 + #endif 303 + 304 + static struct platform_driver bcm63xx_i2s_driver = { 305 + .driver = { 306 + .name = DRV_NAME, 307 + .of_match_table = of_match_ptr(snd_soc_bcm_audio_match), 308 + }, 309 + .probe = bcm63xx_i2s_dev_probe, 310 + .remove = bcm63xx_i2s_dev_remove, 311 + }; 312 + 313 + module_platform_driver(bcm63xx_i2s_driver); 314 + 315 + MODULE_AUTHOR("Kevin,Li <kevin-ke.li@broadcom.com>"); 316 + MODULE_DESCRIPTION("Broadcom DSL XPON ASOC I2S Interface"); 317 + MODULE_LICENSE("GPL v2");
+90
sound/soc/bcm/bcm63xx-i2s.h
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // linux/sound/soc/bcm/bcm63xx-i2s.h 3 + // Copyright (c) 2020 Broadcom Corporation 4 + // Author: Kevin-Ke Li <kevin-ke.li@broadcom.com> 5 + 6 + #ifndef __BCM63XX_I2S_H 7 + #define __BCM63XX_I2S_H 8 + 9 + #define I2S_DESC_FIFO_DEPTH 8 10 + #define I2S_MISC_CFG (0x003C) 11 + #define I2S_PAD_LVL_LOOP_DIS_MASK (1 << 2) 12 + #define I2S_PAD_LVL_LOOP_DIS_ENABLE I2S_PAD_LVL_LOOP_DIS_MASK 13 + 14 + #define I2S_TX_ENABLE_MASK (1 << 31) 15 + #define I2S_TX_ENABLE I2S_TX_ENABLE_MASK 16 + #define I2S_TX_OUT_R (1 << 19) 17 + #define I2S_TX_DATA_ALIGNMENT (1 << 2) 18 + #define I2S_TX_DATA_ENABLE (1 << 1) 19 + #define I2S_TX_CLOCK_ENABLE (1 << 0) 20 + 21 + #define I2S_TX_DESC_OFF_LEVEL_SHIFT 12 22 + #define I2S_TX_DESC_OFF_LEVEL_MASK (0x0F << I2S_TX_DESC_OFF_LEVEL_SHIFT) 23 + #define I2S_TX_DESC_IFF_LEVEL_SHIFT 8 24 + #define I2S_TX_DESC_IFF_LEVEL_MASK (0x0F << I2S_TX_DESC_IFF_LEVEL_SHIFT) 25 + #define I2S_TX_DESC_OFF_INTR_EN_MSK (1 << 1) 26 + #define I2S_TX_DESC_OFF_INTR_EN I2S_TX_DESC_OFF_INTR_EN_MSK 27 + 28 + #define I2S_TX_CFG (0x0000) 29 + #define I2S_TX_IRQ_CTL (0x0004) 30 + #define I2S_TX_IRQ_EN (0x0008) 31 + #define I2S_TX_IRQ_IFF_THLD (0x000c) 32 + #define I2S_TX_IRQ_OFF_THLD (0x0010) 33 + #define I2S_TX_DESC_IFF_ADDR (0x0014) 34 + #define I2S_TX_DESC_IFF_LEN (0x0018) 35 + #define I2S_TX_DESC_OFF_ADDR (0x001C) 36 + #define I2S_TX_DESC_OFF_LEN (0x0020) 37 + #define I2S_TX_CFG_2 (0x0024) 38 + #define I2S_TX_SLAVE_MODE_SHIFT 13 39 + #define I2S_TX_SLAVE_MODE_MASK (1 << I2S_TX_SLAVE_MODE_SHIFT) 40 + #define I2S_TX_SLAVE_MODE I2S_TX_SLAVE_MODE_MASK 41 + #define I2S_TX_MASTER_MODE 0 42 + #define I2S_TX_INTR_MASK 0x0F 43 + 44 + #define I2S_RX_ENABLE_MASK (1 << 31) 45 + #define I2S_RX_ENABLE I2S_RX_ENABLE_MASK 46 + #define I2S_RX_IN_R (1 << 19) 47 + #define I2S_RX_DATA_ALIGNMENT (1 << 2) 48 + #define I2S_RX_CLOCK_ENABLE (1 << 0) 49 + 50 + #define I2S_RX_DESC_OFF_LEVEL_SHIFT 12 51 + #define I2S_RX_DESC_OFF_LEVEL_MASK (0x0F << I2S_RX_DESC_OFF_LEVEL_SHIFT) 52 + #define I2S_RX_DESC_IFF_LEVEL_SHIFT 8 53 + #define I2S_RX_DESC_IFF_LEVEL_MASK (0x0F << I2S_RX_DESC_IFF_LEVEL_SHIFT) 54 + #define I2S_RX_DESC_OFF_INTR_EN_MSK (1 << 1) 55 + #define I2S_RX_DESC_OFF_INTR_EN I2S_RX_DESC_OFF_INTR_EN_MSK 56 + 57 + #define I2S_RX_CFG (0x0040) /* 20c0 */ 58 + #define I2S_RX_IRQ_CTL (0x0044) 59 + #define I2S_RX_IRQ_EN (0x0048) 60 + #define I2S_RX_IRQ_IFF_THLD (0x004C) 61 + #define I2S_RX_IRQ_OFF_THLD (0x0050) 62 + #define I2S_RX_DESC_IFF_ADDR (0x0054) 63 + #define I2S_RX_DESC_IFF_LEN (0x0058) 64 + #define I2S_RX_DESC_OFF_ADDR (0x005C) 65 + #define I2S_RX_DESC_OFF_LEN (0x0060) 66 + #define I2S_RX_CFG_2 (0x0064) 67 + #define I2S_RX_SLAVE_MODE_SHIFT 13 68 + #define I2S_RX_SLAVE_MODE_MASK (1 << I2S_RX_SLAVE_MODE_SHIFT) 69 + #define I2S_RX_SLAVE_MODE I2S_RX_SLAVE_MODE_MASK 70 + #define I2S_RX_MASTER_MODE 0 71 + #define I2S_RX_INTR_MASK 0x0F 72 + 73 + #define I2S_REG_MAX 0x007C 74 + 75 + struct bcm_i2s_priv { 76 + struct device *dev; 77 + struct resource *r_irq; 78 + struct regmap *regmap_i2s; 79 + struct clk *i2s_clk; 80 + struct snd_pcm_substream *play_substream; 81 + struct snd_pcm_substream *capture_substream; 82 + struct i2s_dma_desc *play_dma_desc; 83 + struct i2s_dma_desc *capture_dma_desc; 84 + }; 85 + 86 + extern int bcm63xx_soc_platform_probe(struct platform_device *pdev, 87 + struct bcm_i2s_priv *i2s_priv); 88 + extern int bcm63xx_soc_platform_remove(struct platform_device *pdev); 89 + 90 + #endif
+485
sound/soc/bcm/bcm63xx-pcm-whistler.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // linux/sound/bcm/bcm63xx-pcm-whistler.c 3 + // BCM63xx whistler pcm interface 4 + // Copyright (c) 2020 Broadcom Corporation 5 + // Author: Kevin-Ke Li <kevin-ke.li@broadcom.com> 6 + 7 + #include <linux/dma-mapping.h> 8 + #include <linux/io.h> 9 + #include <linux/module.h> 10 + #include <sound/pcm_params.h> 11 + #include <linux/regmap.h> 12 + #include <linux/of_device.h> 13 + #include <sound/soc.h> 14 + #include "bcm63xx-i2s.h" 15 + 16 + 17 + struct i2s_dma_desc { 18 + unsigned char *dma_area; 19 + dma_addr_t dma_addr; 20 + unsigned int dma_len; 21 + }; 22 + 23 + struct bcm63xx_runtime_data { 24 + int dma_len; 25 + dma_addr_t dma_addr; 26 + dma_addr_t dma_addr_next; 27 + }; 28 + 29 + static const struct snd_pcm_hardware bcm63xx_pcm_hardware = { 30 + .info = SNDRV_PCM_INFO_MMAP | 31 + SNDRV_PCM_INFO_MMAP_VALID | 32 + SNDRV_PCM_INFO_INTERLEAVED | 33 + SNDRV_PCM_INFO_PAUSE | 34 + SNDRV_PCM_INFO_RESUME, 35 + .formats = SNDRV_PCM_FMTBIT_S32_LE, /* support S32 only */ 36 + .period_bytes_max = 8192 - 32, 37 + .periods_min = 1, 38 + .periods_max = PAGE_SIZE/sizeof(struct i2s_dma_desc), 39 + .buffer_bytes_max = 128 * 1024, 40 + .fifo_size = 32, 41 + }; 42 + 43 + static int bcm63xx_pcm_hw_params(struct snd_soc_component *component, 44 + struct snd_pcm_substream *substream, 45 + struct snd_pcm_hw_params *params) 46 + { 47 + struct i2s_dma_desc *dma_desc; 48 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 + struct snd_pcm_runtime *runtime = substream->runtime; 50 + 51 + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 52 + runtime->dma_bytes = params_buffer_bytes(params); 53 + 54 + dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT); 55 + if (!dma_desc) 56 + return -ENOMEM; 57 + 58 + snd_soc_dai_set_dma_data(asoc_rtd_to_cpu(rtd, 0), substream, dma_desc); 59 + 60 + return 0; 61 + } 62 + 63 + static int bcm63xx_pcm_hw_free(struct snd_soc_component *component, 64 + struct snd_pcm_substream *substream) 65 + { 66 + struct i2s_dma_desc *dma_desc; 67 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 + 69 + dma_desc = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 70 + kfree(dma_desc); 71 + snd_pcm_set_runtime_buffer(substream, NULL); 72 + 73 + return 0; 74 + } 75 + 76 + static int bcm63xx_pcm_trigger(struct snd_soc_component *component, 77 + struct snd_pcm_substream *substream, int cmd) 78 + { 79 + int ret = 0; 80 + struct snd_soc_pcm_runtime *rtd; 81 + struct bcm_i2s_priv *i2s_priv; 82 + struct regmap *regmap_i2s; 83 + 84 + rtd = substream->private_data; 85 + i2s_priv = dev_get_drvdata(asoc_rtd_to_cpu(rtd, 0)->dev); 86 + regmap_i2s = i2s_priv->regmap_i2s; 87 + 88 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 89 + switch (cmd) { 90 + case SNDRV_PCM_TRIGGER_START: 91 + regmap_update_bits(regmap_i2s, 92 + I2S_TX_IRQ_EN, 93 + I2S_TX_DESC_OFF_INTR_EN, 94 + I2S_TX_DESC_OFF_INTR_EN); 95 + regmap_update_bits(regmap_i2s, 96 + I2S_TX_CFG, 97 + I2S_TX_ENABLE_MASK, 98 + I2S_TX_ENABLE); 99 + break; 100 + case SNDRV_PCM_TRIGGER_STOP: 101 + case SNDRV_PCM_TRIGGER_SUSPEND: 102 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 103 + regmap_write(regmap_i2s, 104 + I2S_TX_IRQ_EN, 105 + 0); 106 + regmap_update_bits(regmap_i2s, 107 + I2S_TX_CFG, 108 + I2S_TX_ENABLE_MASK, 109 + 0); 110 + break; 111 + default: 112 + ret = -EINVAL; 113 + } 114 + } else { 115 + switch (cmd) { 116 + case SNDRV_PCM_TRIGGER_START: 117 + regmap_update_bits(regmap_i2s, 118 + I2S_RX_IRQ_EN, 119 + I2S_RX_DESC_OFF_INTR_EN_MSK, 120 + I2S_RX_DESC_OFF_INTR_EN); 121 + regmap_update_bits(regmap_i2s, 122 + I2S_RX_CFG, 123 + I2S_RX_ENABLE_MASK, 124 + I2S_RX_ENABLE); 125 + break; 126 + case SNDRV_PCM_TRIGGER_STOP: 127 + case SNDRV_PCM_TRIGGER_SUSPEND: 128 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 129 + regmap_update_bits(regmap_i2s, 130 + I2S_RX_IRQ_EN, 131 + I2S_RX_DESC_OFF_INTR_EN_MSK, 132 + 0); 133 + regmap_update_bits(regmap_i2s, 134 + I2S_RX_CFG, 135 + I2S_RX_ENABLE_MASK, 136 + 0); 137 + break; 138 + default: 139 + ret = -EINVAL; 140 + } 141 + } 142 + return ret; 143 + } 144 + 145 + static int bcm63xx_pcm_prepare(struct snd_soc_component *component, 146 + struct snd_pcm_substream *substream) 147 + { 148 + struct i2s_dma_desc *dma_desc; 149 + struct regmap *regmap_i2s; 150 + struct bcm_i2s_priv *i2s_priv; 151 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 152 + struct snd_pcm_runtime *runtime = substream->runtime; 153 + uint32_t regaddr_desclen, regaddr_descaddr; 154 + 155 + dma_desc = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 156 + dma_desc->dma_len = snd_pcm_lib_period_bytes(substream); 157 + dma_desc->dma_addr = runtime->dma_addr; 158 + dma_desc->dma_area = runtime->dma_area; 159 + 160 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 161 + regaddr_desclen = I2S_TX_DESC_IFF_LEN; 162 + regaddr_descaddr = I2S_TX_DESC_IFF_ADDR; 163 + } else { 164 + regaddr_desclen = I2S_RX_DESC_IFF_LEN; 165 + regaddr_descaddr = I2S_RX_DESC_IFF_ADDR; 166 + } 167 + 168 + i2s_priv = dev_get_drvdata(asoc_rtd_to_cpu(rtd, 0)->dev); 169 + regmap_i2s = i2s_priv->regmap_i2s; 170 + 171 + regmap_write(regmap_i2s, regaddr_desclen, dma_desc->dma_len); 172 + regmap_write(regmap_i2s, regaddr_descaddr, dma_desc->dma_addr); 173 + 174 + return 0; 175 + } 176 + 177 + static snd_pcm_uframes_t 178 + bcm63xx_pcm_pointer(struct snd_soc_component *component, 179 + struct snd_pcm_substream *substream) 180 + { 181 + snd_pcm_uframes_t x; 182 + struct bcm63xx_runtime_data *prtd = substream->runtime->private_data; 183 + 184 + if ((void *)prtd->dma_addr_next == NULL) 185 + prtd->dma_addr_next = substream->runtime->dma_addr; 186 + 187 + x = bytes_to_frames(substream->runtime, 188 + prtd->dma_addr_next - substream->runtime->dma_addr); 189 + 190 + return x == substream->runtime->buffer_size ? 0 : x; 191 + } 192 + 193 + static int bcm63xx_pcm_mmap(struct snd_soc_component *component, 194 + struct snd_pcm_substream *substream, 195 + struct vm_area_struct *vma) 196 + { 197 + struct snd_pcm_runtime *runtime = substream->runtime; 198 + 199 + return dma_mmap_wc(substream->pcm->card->dev, vma, 200 + runtime->dma_area, 201 + runtime->dma_addr, 202 + runtime->dma_bytes); 203 + 204 + } 205 + 206 + static int bcm63xx_pcm_open(struct snd_soc_component *component, 207 + struct snd_pcm_substream *substream) 208 + { 209 + int ret = 0; 210 + struct snd_pcm_runtime *runtime = substream->runtime; 211 + struct bcm63xx_runtime_data *prtd; 212 + 213 + runtime->hw = bcm63xx_pcm_hardware; 214 + ret = snd_pcm_hw_constraint_step(runtime, 0, 215 + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 216 + if (ret) 217 + goto out; 218 + 219 + ret = snd_pcm_hw_constraint_step(runtime, 0, 220 + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 221 + if (ret) 222 + goto out; 223 + 224 + ret = snd_pcm_hw_constraint_integer(runtime, 225 + SNDRV_PCM_HW_PARAM_PERIODS); 226 + if (ret < 0) 227 + goto out; 228 + 229 + ret = -ENOMEM; 230 + prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 231 + if (!prtd) 232 + goto out; 233 + 234 + runtime->private_data = prtd; 235 + return 0; 236 + out: 237 + return ret; 238 + } 239 + 240 + static int bcm63xx_pcm_close(struct snd_soc_component *component, 241 + struct snd_pcm_substream *substream) 242 + { 243 + struct snd_pcm_runtime *runtime = substream->runtime; 244 + struct bcm63xx_runtime_data *prtd = runtime->private_data; 245 + 246 + kfree(prtd); 247 + return 0; 248 + } 249 + 250 + static irqreturn_t i2s_dma_isr(int irq, void *bcm_i2s_priv) 251 + { 252 + unsigned int availdepth, ifflevel, offlevel, int_status, val_1, val_2; 253 + struct bcm63xx_runtime_data *prtd; 254 + struct snd_pcm_substream *substream; 255 + struct snd_pcm_runtime *runtime; 256 + struct regmap *regmap_i2s; 257 + struct i2s_dma_desc *dma_desc; 258 + struct snd_soc_pcm_runtime *rtd; 259 + struct bcm_i2s_priv *i2s_priv; 260 + 261 + i2s_priv = (struct bcm_i2s_priv *)bcm_i2s_priv; 262 + regmap_i2s = i2s_priv->regmap_i2s; 263 + 264 + /* rx */ 265 + regmap_read(regmap_i2s, I2S_RX_IRQ_CTL, &int_status); 266 + 267 + if (int_status & I2S_RX_DESC_OFF_INTR_EN_MSK) { 268 + substream = i2s_priv->capture_substream; 269 + runtime = substream->runtime; 270 + rtd = substream->private_data; 271 + prtd = runtime->private_data; 272 + dma_desc = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 273 + 274 + offlevel = (int_status & I2S_RX_DESC_OFF_LEVEL_MASK) >> 275 + I2S_RX_DESC_OFF_LEVEL_SHIFT; 276 + while (offlevel) { 277 + regmap_read(regmap_i2s, I2S_RX_DESC_OFF_ADDR, &val_1); 278 + regmap_read(regmap_i2s, I2S_RX_DESC_OFF_LEN, &val_2); 279 + offlevel--; 280 + } 281 + prtd->dma_addr_next = val_1 + val_2; 282 + ifflevel = (int_status & I2S_RX_DESC_IFF_LEVEL_MASK) >> 283 + I2S_RX_DESC_IFF_LEVEL_SHIFT; 284 + 285 + availdepth = I2S_DESC_FIFO_DEPTH - ifflevel; 286 + while (availdepth) { 287 + dma_desc->dma_addr += 288 + snd_pcm_lib_period_bytes(substream); 289 + dma_desc->dma_area += 290 + snd_pcm_lib_period_bytes(substream); 291 + if (dma_desc->dma_addr - runtime->dma_addr >= 292 + runtime->dma_bytes) { 293 + dma_desc->dma_addr = runtime->dma_addr; 294 + dma_desc->dma_area = runtime->dma_area; 295 + } 296 + 297 + prtd->dma_addr = dma_desc->dma_addr; 298 + regmap_write(regmap_i2s, I2S_RX_DESC_IFF_LEN, 299 + snd_pcm_lib_period_bytes(substream)); 300 + regmap_write(regmap_i2s, I2S_RX_DESC_IFF_ADDR, 301 + dma_desc->dma_addr); 302 + availdepth--; 303 + } 304 + 305 + snd_pcm_period_elapsed(substream); 306 + 307 + /* Clear interrupt by writing 0 */ 308 + regmap_update_bits(regmap_i2s, I2S_RX_IRQ_CTL, 309 + I2S_RX_INTR_MASK, 0); 310 + } 311 + 312 + /* tx */ 313 + regmap_read(regmap_i2s, I2S_TX_IRQ_CTL, &int_status); 314 + 315 + if (int_status & I2S_TX_DESC_OFF_INTR_EN_MSK) { 316 + substream = i2s_priv->play_substream; 317 + runtime = substream->runtime; 318 + rtd = substream->private_data; 319 + prtd = runtime->private_data; 320 + dma_desc = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 321 + 322 + offlevel = (int_status & I2S_TX_DESC_OFF_LEVEL_MASK) >> 323 + I2S_TX_DESC_OFF_LEVEL_SHIFT; 324 + while (offlevel) { 325 + regmap_read(regmap_i2s, I2S_TX_DESC_OFF_ADDR, &val_1); 326 + regmap_read(regmap_i2s, I2S_TX_DESC_OFF_LEN, &val_2); 327 + prtd->dma_addr_next = val_1 + val_2; 328 + offlevel--; 329 + } 330 + 331 + ifflevel = (int_status & I2S_TX_DESC_IFF_LEVEL_MASK) >> 332 + I2S_TX_DESC_IFF_LEVEL_SHIFT; 333 + availdepth = I2S_DESC_FIFO_DEPTH - ifflevel; 334 + 335 + while (availdepth) { 336 + dma_desc->dma_addr += 337 + snd_pcm_lib_period_bytes(substream); 338 + dma_desc->dma_area += 339 + snd_pcm_lib_period_bytes(substream); 340 + 341 + if (dma_desc->dma_addr - runtime->dma_addr >= 342 + runtime->dma_bytes) { 343 + dma_desc->dma_addr = runtime->dma_addr; 344 + dma_desc->dma_area = runtime->dma_area; 345 + } 346 + 347 + prtd->dma_addr = dma_desc->dma_addr; 348 + regmap_write(regmap_i2s, I2S_TX_DESC_IFF_LEN, 349 + snd_pcm_lib_period_bytes(substream)); 350 + regmap_write(regmap_i2s, I2S_TX_DESC_IFF_ADDR, 351 + dma_desc->dma_addr); 352 + availdepth--; 353 + } 354 + 355 + snd_pcm_period_elapsed(substream); 356 + 357 + /* Clear interrupt by writing 0 */ 358 + regmap_update_bits(regmap_i2s, I2S_TX_IRQ_CTL, 359 + I2S_TX_INTR_MASK, 0); 360 + } 361 + 362 + return IRQ_HANDLED; 363 + } 364 + 365 + static int bcm63xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 366 + { 367 + struct snd_pcm_substream *substream = pcm->streams[stream].substream; 368 + struct snd_dma_buffer *buf = &substream->dma_buffer; 369 + size_t size = bcm63xx_pcm_hardware.buffer_bytes_max; 370 + 371 + buf->dev.type = SNDRV_DMA_TYPE_DEV; 372 + buf->dev.dev = pcm->card->dev; 373 + buf->private_data = NULL; 374 + 375 + buf->area = dma_alloc_wc(pcm->card->dev, 376 + size, &buf->addr, 377 + GFP_KERNEL); 378 + if (!buf->area) 379 + return -ENOMEM; 380 + buf->bytes = size; 381 + return 0; 382 + } 383 + 384 + static int bcm63xx_soc_pcm_new(struct snd_soc_component *component, 385 + struct snd_soc_pcm_runtime *rtd) 386 + { 387 + struct snd_pcm *pcm = rtd->pcm; 388 + struct bcm_i2s_priv *i2s_priv; 389 + int ret; 390 + 391 + i2s_priv = dev_get_drvdata(asoc_rtd_to_cpu(rtd, 0)->dev); 392 + 393 + of_dma_configure(pcm->card->dev, pcm->card->dev->of_node, 1); 394 + 395 + ret = dma_coerce_mask_and_coherent(pcm->card->dev, DMA_BIT_MASK(32)); 396 + if (ret) 397 + goto out; 398 + 399 + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 400 + ret = bcm63xx_pcm_preallocate_dma_buffer(pcm, 401 + SNDRV_PCM_STREAM_PLAYBACK); 402 + if (ret) 403 + goto out; 404 + 405 + i2s_priv->play_substream = 406 + pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 407 + } 408 + 409 + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { 410 + ret = bcm63xx_pcm_preallocate_dma_buffer(pcm, 411 + SNDRV_PCM_STREAM_CAPTURE); 412 + if (ret) 413 + goto out; 414 + i2s_priv->capture_substream = 415 + pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 416 + } 417 + 418 + out: 419 + return ret; 420 + } 421 + 422 + static void bcm63xx_pcm_free_dma_buffers(struct snd_soc_component *component, 423 + struct snd_pcm *pcm) 424 + { 425 + int stream; 426 + struct snd_dma_buffer *buf; 427 + struct snd_pcm_substream *substream; 428 + 429 + for (stream = 0; stream < 2; stream++) { 430 + substream = pcm->streams[stream].substream; 431 + if (!substream) 432 + continue; 433 + buf = &substream->dma_buffer; 434 + if (!buf->area) 435 + continue; 436 + dma_free_wc(pcm->card->dev, buf->bytes, 437 + buf->area, buf->addr); 438 + buf->area = NULL; 439 + } 440 + } 441 + 442 + static const struct snd_soc_component_driver bcm63xx_soc_platform = { 443 + .open = bcm63xx_pcm_open, 444 + .close = bcm63xx_pcm_close, 445 + .hw_params = bcm63xx_pcm_hw_params, 446 + .hw_free = bcm63xx_pcm_hw_free, 447 + .prepare = bcm63xx_pcm_prepare, 448 + .trigger = bcm63xx_pcm_trigger, 449 + .pointer = bcm63xx_pcm_pointer, 450 + .mmap = bcm63xx_pcm_mmap, 451 + .pcm_construct = bcm63xx_soc_pcm_new, 452 + .pcm_destruct = bcm63xx_pcm_free_dma_buffers, 453 + }; 454 + 455 + int bcm63xx_soc_platform_probe(struct platform_device *pdev, 456 + struct bcm_i2s_priv *i2s_priv) 457 + { 458 + int ret; 459 + 460 + i2s_priv->r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 461 + if (!i2s_priv->r_irq) { 462 + dev_err(&pdev->dev, "Unable to get register irq resource.\n"); 463 + return -ENODEV; 464 + } 465 + 466 + ret = devm_request_irq(&pdev->dev, i2s_priv->r_irq->start, i2s_dma_isr, 467 + i2s_priv->r_irq->flags, "i2s_dma", (void *)i2s_priv); 468 + if (ret) { 469 + dev_err(&pdev->dev, 470 + "i2s_init: failed to request interrupt.ret=%d\n", ret); 471 + return ret; 472 + } 473 + 474 + return devm_snd_soc_register_component(&pdev->dev, 475 + &bcm63xx_soc_platform, NULL, 0); 476 + } 477 + 478 + int bcm63xx_soc_platform_remove(struct platform_device *pdev) 479 + { 480 + return 0; 481 + } 482 + 483 + MODULE_AUTHOR("Kevin,Li <kevin-ke.li@broadcom.com>"); 484 + MODULE_DESCRIPTION("Broadcom DSL XPON ASOC PCM Interface"); 485 + MODULE_LICENSE("GPL v2");
+11 -11
sound/soc/bcm/cygnus-pcm.c
··· 209 209 { 210 210 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 211 211 212 - return snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream); 212 + return snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(soc_runtime, 0), substream); 213 213 } 214 214 215 215 static void ringbuf_set_initial(void __iomem *audio_io, ··· 359 359 360 360 aio = cygnus_dai_get_dma_data(substream); 361 361 362 - dev_dbg(rtd->cpu_dai->dev, "%s on port %d\n", __func__, aio->portnum); 362 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s on port %d\n", __func__, aio->portnum); 363 363 364 364 /* The port number maps to the bit position to be set */ 365 365 set_mask = BIT(aio->portnum); ··· 590 590 if (!aio) 591 591 return -ENODEV; 592 592 593 - dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 593 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); 594 594 595 595 snd_soc_set_runtime_hwparams(substream, &cygnus_pcm_hw); 596 596 ··· 623 623 624 624 aio = cygnus_dai_get_dma_data(substream); 625 625 626 - dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 626 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); 627 627 628 628 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 629 629 aio->play_stream = NULL; ··· 631 631 aio->capture_stream = NULL; 632 632 633 633 if (!aio->play_stream && !aio->capture_stream) 634 - dev_dbg(rtd->cpu_dai->dev, "freed port %d\n", aio->portnum); 634 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "freed port %d\n", aio->portnum); 635 635 636 636 return 0; 637 637 } ··· 645 645 struct cygnus_aio_port *aio; 646 646 647 647 aio = cygnus_dai_get_dma_data(substream); 648 - dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 648 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); 649 649 650 650 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 651 651 runtime->dma_bytes = params_buffer_bytes(params); ··· 660 660 struct cygnus_aio_port *aio; 661 661 662 662 aio = cygnus_dai_get_dma_data(substream); 663 - dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 663 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); 664 664 665 665 snd_pcm_set_runtime_buffer(substream, NULL); 666 666 return 0; ··· 678 678 struct ringbuf_regs *p_rbuf = NULL; 679 679 680 680 aio = cygnus_dai_get_dma_data(substream); 681 - dev_dbg(rtd->cpu_dai->dev, "%s port %d\n", __func__, aio->portnum); 681 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum); 682 682 683 683 bufsize = snd_pcm_lib_buffer_bytes(substream); 684 684 periodsize = snd_pcm_lib_period_bytes(substream); 685 685 686 - dev_dbg(rtd->cpu_dai->dev, "%s (buf_size %lu) (period_size %lu)\n", 686 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s (buf_size %lu) (period_size %lu)\n", 687 687 __func__, bufsize, periodsize); 688 688 689 689 configure_ringbuf_regs(substream); ··· 745 745 buf->area = dma_alloc_coherent(pcm->card->dev, size, 746 746 &buf->addr, GFP_KERNEL); 747 747 748 - dev_dbg(rtd->cpu_dai->dev, "%s: size 0x%zx @ %pK\n", 748 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: size 0x%zx @ %pK\n", 749 749 __func__, size, buf->area); 750 750 751 751 if (!buf->area) { 752 - dev_err(rtd->cpu_dai->dev, "%s: dma_alloc failed\n", __func__); 752 + dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: dma_alloc failed\n", __func__); 753 753 return -ENOMEM; 754 754 } 755 755 buf->bytes = size;
+2 -2
sound/soc/cirrus/edb93xx.c
··· 23 23 struct snd_pcm_hw_params *params) 24 24 { 25 25 struct snd_soc_pcm_runtime *rtd = substream->private_data; 26 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 27 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 26 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 27 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 28 28 int err; 29 29 unsigned int mclk_rate; 30 30 unsigned int rate = params_rate(params);
+2 -2
sound/soc/cirrus/snappercl15.c
··· 23 23 struct snd_pcm_hw_params *params) 24 24 { 25 25 struct snd_soc_pcm_runtime *rtd = substream->private_data; 26 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 27 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 26 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 27 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 28 28 int err; 29 29 30 30 err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK,
+364 -263
sound/soc/codecs/Kconfig
··· 14 14 config SND_SOC_ALL_CODECS 15 15 tristate "Build all ASoC CODEC drivers" 16 16 depends on COMPILE_TEST 17 - select SND_SOC_88PM860X if MFD_88PM860X 18 - select SND_SOC_L3 19 - select SND_SOC_AB8500_CODEC if ABX500_CORE 20 - select SND_SOC_AC97_CODEC 21 - select SND_SOC_AD1836 if SPI_MASTER 22 - select SND_SOC_AD193X_SPI if SPI_MASTER 23 - select SND_SOC_AD193X_I2C if I2C 24 - select SND_SOC_AD1980 if SND_SOC_AC97_BUS 25 - select SND_SOC_AD73311 26 - select SND_SOC_ADAU1373 if I2C 27 - select SND_SOC_ADAU1761_I2C if I2C 28 - select SND_SOC_ADAU1761_SPI if SPI 29 - select SND_SOC_ADAU1781_I2C if I2C 30 - select SND_SOC_ADAU1781_SPI if SPI 31 - select SND_SOC_ADAV801 if SPI_MASTER 32 - select SND_SOC_ADAV803 if I2C 33 - select SND_SOC_ADAU1977_SPI if SPI_MASTER 34 - select SND_SOC_ADAU1977_I2C if I2C 35 - select SND_SOC_ADAU1701 if I2C 36 - select SND_SOC_ADAU7002 37 - select SND_SOC_ADAU7118_I2C if I2C 38 - select SND_SOC_ADAU7118_HW 39 - select SND_SOC_ADS117X 40 - select SND_SOC_AK4104 if SPI_MASTER 41 - select SND_SOC_AK4118 if I2C 42 - select SND_SOC_AK4458 if I2C 43 - select SND_SOC_AK4535 if I2C 44 - select SND_SOC_AK4554 45 - select SND_SOC_AK4613 if I2C 46 - select SND_SOC_AK4641 if I2C 47 - select SND_SOC_AK4642 if I2C 48 - select SND_SOC_AK4671 if I2C 49 - select SND_SOC_AK5386 50 - select SND_SOC_AK5558 if I2C 51 - select SND_SOC_ALC5623 if I2C 52 - select SND_SOC_ALC5632 if I2C 53 - select SND_SOC_BT_SCO 54 - select SND_SOC_BD28623 55 - select SND_SOC_CQ0093VC 56 - select SND_SOC_CROS_EC_CODEC if CROS_EC 57 - select SND_SOC_CS35L32 if I2C 58 - select SND_SOC_CS35L33 if I2C 59 - select SND_SOC_CS35L34 if I2C 60 - select SND_SOC_CS35L35 if I2C 61 - select SND_SOC_CS35L36 if I2C 62 - select SND_SOC_CS42L42 if I2C 63 - select SND_SOC_CS42L51_I2C if I2C 64 - select SND_SOC_CS42L52 if I2C && INPUT 65 - select SND_SOC_CS42L56 if I2C && INPUT 66 - select SND_SOC_CS42L73 if I2C 67 - select SND_SOC_CS4265 if I2C 68 - select SND_SOC_CS4270 if I2C 69 - select SND_SOC_CS4271_I2C if I2C 70 - select SND_SOC_CS4271_SPI if SPI_MASTER 71 - select SND_SOC_CS42XX8_I2C if I2C 72 - select SND_SOC_CS43130 if I2C 73 - select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI 74 - select SND_SOC_CS4349 if I2C 75 - select SND_SOC_CS47L15 if MFD_CS47L15 76 - select SND_SOC_CS47L24 if MFD_CS47L24 77 - select SND_SOC_CS47L35 if MFD_CS47L35 78 - select SND_SOC_CS47L85 if MFD_CS47L85 79 - select SND_SOC_CS47L90 if MFD_CS47L90 80 - select SND_SOC_CS47L92 if MFD_CS47L92 81 - select SND_SOC_CS53L30 if I2C 82 - select SND_SOC_CX20442 if TTY 83 - select SND_SOC_CX2072X if I2C 84 - select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 85 - select SND_SOC_DA7213 if I2C 86 - select SND_SOC_DA7218 if I2C 87 - select SND_SOC_DA7219 if I2C 88 - select SND_SOC_DA732X if I2C 89 - select SND_SOC_DA9055 if I2C 90 - select SND_SOC_DMIC if GPIOLIB 91 - select SND_SOC_ES8316 if I2C 92 - select SND_SOC_ES8328_SPI if SPI_MASTER 93 - select SND_SOC_ES8328_I2C if I2C 94 - select SND_SOC_ES7134 95 - select SND_SOC_ES7241 96 - select SND_SOC_GTM601 97 - select SND_SOC_HDAC_HDMI 98 - select SND_SOC_HDAC_HDA 99 - select SND_SOC_ICS43432 100 - select SND_SOC_INNO_RK3036 101 - select SND_SOC_ISABELLE if I2C 102 - select SND_SOC_JZ4740_CODEC 103 - select SND_SOC_JZ4725B_CODEC 104 - select SND_SOC_JZ4770_CODEC 105 - select SND_SOC_LM4857 if I2C 106 - select SND_SOC_LM49453 if I2C 107 - select SND_SOC_LOCHNAGAR_SC if MFD_LOCHNAGAR 108 - select SND_SOC_MAX98088 if I2C 109 - select SND_SOC_MAX98090 if I2C 110 - select SND_SOC_MAX98095 if I2C 111 - select SND_SOC_MAX98357A if GPIOLIB 112 - select SND_SOC_MAX98371 if I2C 113 - select SND_SOC_MAX98504 if I2C 114 - select SND_SOC_MAX9867 if I2C 115 - select SND_SOC_MAX98925 if I2C 116 - select SND_SOC_MAX98926 if I2C 117 - select SND_SOC_MAX98927 if I2C 118 - select SND_SOC_MAX98373 if I2C 119 - select SND_SOC_MAX9850 if I2C 120 - select SND_SOC_MAX9860 if I2C 121 - select SND_SOC_MAX9759 122 - select SND_SOC_MAX9768 if I2C 123 - select SND_SOC_MAX9877 if I2C 124 - select SND_SOC_MC13783 if MFD_MC13XXX 125 - select SND_SOC_ML26124 if I2C 126 - select SND_SOC_MT6351 if MTK_PMIC_WRAP 127 - select SND_SOC_MT6358 if MTK_PMIC_WRAP 128 - select SND_SOC_MT6660 if I2C 129 - select SND_SOC_NAU8540 if I2C 130 - select SND_SOC_NAU8810 if I2C 131 - select SND_SOC_NAU8822 if I2C 132 - select SND_SOC_NAU8824 if I2C 133 - select SND_SOC_NAU8825 if I2C 134 - select SND_SOC_HDMI_CODEC 135 - select SND_SOC_PCM1681 if I2C 136 - select SND_SOC_PCM1789_I2C if I2C 137 - select SND_SOC_PCM179X_I2C if I2C 138 - select SND_SOC_PCM179X_SPI if SPI_MASTER 139 - select SND_SOC_PCM186X_I2C if I2C 140 - select SND_SOC_PCM186X_SPI if SPI_MASTER 141 - select SND_SOC_PCM3008 142 - select SND_SOC_PCM3060_I2C if I2C 143 - select SND_SOC_PCM3060_SPI if SPI_MASTER 144 - select SND_SOC_PCM3168A_I2C if I2C 145 - select SND_SOC_PCM3168A_SPI if SPI_MASTER 146 - select SND_SOC_PCM5102A 147 - select SND_SOC_PCM512x_I2C if I2C 148 - select SND_SOC_PCM512x_SPI if SPI_MASTER 149 - select SND_SOC_RK3328 150 - select SND_SOC_RT274 if I2C 151 - select SND_SOC_RT286 if I2C 152 - select SND_SOC_RT298 if I2C 153 - select SND_SOC_RT1011 if I2C 154 - select SND_SOC_RT1015 if I2C 155 - select SND_SOC_RT1305 if I2C 156 - select SND_SOC_RT1308 if I2C 157 - select SND_SOC_RT5514 if I2C 158 - select SND_SOC_RT5616 if I2C 159 - select SND_SOC_RT5631 if I2C 160 - select SND_SOC_RT5640 if I2C 161 - select SND_SOC_RT5645 if I2C 162 - select SND_SOC_RT5651 if I2C 163 - select SND_SOC_RT5659 if I2C 164 - select SND_SOC_RT5660 if I2C 165 - select SND_SOC_RT5663 if I2C 166 - select SND_SOC_RT5665 if I2C 167 - select SND_SOC_RT5668 if I2C 168 - select SND_SOC_RT5670 if I2C 169 - select SND_SOC_RT5677 if I2C && SPI_MASTER 170 - select SND_SOC_RT5682 if I2C 171 - select SND_SOC_RT700_SDW if SOUNDWIRE 172 - select SND_SOC_RT711_SDW if SOUNDWIRE 173 - select SND_SOC_RT715_SDW if SOUNDWIRE 174 - select SND_SOC_RT1308_SDW if SOUNDWIRE 175 - select SND_SOC_SGTL5000 if I2C 176 - select SND_SOC_SI476X if MFD_SI476X_CORE 177 - select SND_SOC_SIMPLE_AMPLIFIER 178 - select SND_SOC_SIRF_AUDIO_CODEC 179 - select SND_SOC_SPDIF 180 - select SND_SOC_SSM2305 181 - select SND_SOC_SSM2518 if I2C 182 - select SND_SOC_SSM2602_SPI if SPI_MASTER 183 - select SND_SOC_SSM2602_I2C if I2C 184 - select SND_SOC_SSM4567 if I2C 185 - select SND_SOC_STA32X if I2C 186 - select SND_SOC_STA350 if I2C 187 - select SND_SOC_STA529 if I2C 188 - select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 189 - select SND_SOC_STI_SAS 190 - select SND_SOC_TAS2552 if I2C 191 - select SND_SOC_TAS2562 if I2C 192 - select SND_SOC_TAS2770 if I2C 193 - select SND_SOC_TAS5086 if I2C 194 - select SND_SOC_TAS571X if I2C 195 - select SND_SOC_TAS5720 if I2C 196 - select SND_SOC_TAS6424 if I2C 197 - select SND_SOC_TDA7419 if I2C 198 - select SND_SOC_TFA9879 if I2C 199 - select SND_SOC_TLV320AIC23_I2C if I2C 200 - select SND_SOC_TLV320AIC23_SPI if SPI_MASTER 201 - select SND_SOC_TLV320AIC26 if SPI_MASTER 202 - select SND_SOC_TLV320AIC31XX if I2C 203 - select SND_SOC_TLV320AIC32X4_I2C if I2C && COMMON_CLK 204 - select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER && COMMON_CLK 205 - select SND_SOC_TLV320AIC3X if I2C 206 - select SND_SOC_TPA6130A2 if I2C 207 - select SND_SOC_TLV320DAC33 if I2C 208 - select SND_SOC_TSCS42XX if I2C 209 - select SND_SOC_TSCS454 if I2C 210 - select SND_SOC_TS3A227E if I2C 211 - select SND_SOC_TWL4030 if TWL4030_CORE 212 - select SND_SOC_TWL6040 if TWL6040_CORE 213 - select SND_SOC_UDA1334 if GPIOLIB 214 - select SND_SOC_UDA134X 215 - select SND_SOC_UDA1380 if I2C 216 - select SND_SOC_WCD9335 if SLIMBUS 217 - select SND_SOC_WCD934X if MFD_WCD934X && COMMON_CLK 218 - select SND_SOC_WL1273 if MFD_WL1273_CORE 219 - select SND_SOC_WM0010 if SPI_MASTER 220 - select SND_SOC_WM1250_EV1 if I2C 221 - select SND_SOC_WM2000 if I2C 222 - select SND_SOC_WM2200 if I2C 223 - select SND_SOC_WM5100 if I2C 224 - select SND_SOC_WM5102 if MFD_WM5102 225 - select SND_SOC_WM5110 if MFD_WM5110 226 - select SND_SOC_WM8350 if MFD_WM8350 227 - select SND_SOC_WM8400 if MFD_WM8400 228 - select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 229 - select SND_SOC_WM8523 if I2C 230 - select SND_SOC_WM8524 if GPIOLIB 231 - select SND_SOC_WM8580 if I2C 232 - select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI 233 - select SND_SOC_WM8727 234 - select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 235 - select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 236 - select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI 237 - select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI 238 - select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 239 - select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 240 - select SND_SOC_WM8770 if SPI_MASTER 241 - select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 242 - select SND_SOC_WM8782 243 - select SND_SOC_WM8804_I2C if I2C 244 - select SND_SOC_WM8804_SPI if SPI_MASTER 245 - select SND_SOC_WM8900 if I2C 246 - select SND_SOC_WM8903 if I2C 247 - select SND_SOC_WM8904 if I2C 248 - select SND_SOC_WM8940 if I2C 249 - select SND_SOC_WM8955 if I2C 250 - select SND_SOC_WM8960 if I2C 251 - select SND_SOC_WM8961 if I2C 252 - select SND_SOC_WM8962 if I2C && INPUT 253 - select SND_SOC_WM8971 if I2C 254 - select SND_SOC_WM8974 if I2C 255 - select SND_SOC_WM8978 if I2C 256 - select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI 257 - select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 258 - select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 259 - select SND_SOC_WM8990 if I2C 260 - select SND_SOC_WM8991 if I2C 261 - select SND_SOC_WM8993 if I2C 262 - select SND_SOC_WM8994 if MFD_WM8994 263 - select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 264 - select SND_SOC_WM8996 if I2C 265 - select SND_SOC_WM8997 if MFD_WM8997 266 - select SND_SOC_WM8998 if MFD_WM8998 267 - select SND_SOC_WM9081 if I2C 268 - select SND_SOC_WM9090 if I2C 269 - select SND_SOC_WM9705 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW) 270 - select SND_SOC_WM9712 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW) 271 - select SND_SOC_WM9713 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW) 272 - select SND_SOC_WSA881X if SOUNDWIRE 17 + imply SND_SOC_88PM860X 18 + imply SND_SOC_L3 19 + imply SND_SOC_AB8500_CODEC 20 + imply SND_SOC_AC97_CODEC 21 + imply SND_SOC_AD1836 22 + imply SND_SOC_AD193X_SPI 23 + imply SND_SOC_AD193X_I2C 24 + imply SND_SOC_AD1980 25 + imply SND_SOC_AD73311 26 + imply SND_SOC_ADAU1373 27 + imply SND_SOC_ADAU1761_I2C 28 + imply SND_SOC_ADAU1761_SPI 29 + imply SND_SOC_ADAU1781_I2C 30 + imply SND_SOC_ADAU1781_SPI 31 + imply SND_SOC_ADAV801 32 + imply SND_SOC_ADAV803 33 + imply SND_SOC_ADAU1977_SPI 34 + imply SND_SOC_ADAU1977_I2C 35 + imply SND_SOC_ADAU1701 36 + imply SND_SOC_ADAU7002 37 + imply SND_SOC_ADAU7118_I2C 38 + imply SND_SOC_ADAU7118_HW 39 + imply SND_SOC_ADS117X 40 + imply SND_SOC_AK4104 41 + imply SND_SOC_AK4118 42 + imply SND_SOC_AK4458 43 + imply SND_SOC_AK4535 44 + imply SND_SOC_AK4554 45 + imply SND_SOC_AK4613 46 + imply SND_SOC_AK4641 47 + imply SND_SOC_AK4642 48 + imply SND_SOC_AK4671 49 + imply SND_SOC_AK5386 50 + imply SND_SOC_AK5558 51 + imply SND_SOC_ALC5623 52 + imply SND_SOC_ALC5632 53 + imply SND_SOC_BT_SCO 54 + imply SND_SOC_BD28623 55 + imply SND_SOC_CQ0093VC 56 + imply SND_SOC_CROS_EC_CODEC 57 + imply SND_SOC_CS35L32 58 + imply SND_SOC_CS35L33 59 + imply SND_SOC_CS35L34 60 + imply SND_SOC_CS35L35 61 + imply SND_SOC_CS35L36 62 + imply SND_SOC_CS42L42 63 + imply SND_SOC_CS42L51_I2C 64 + imply SND_SOC_CS42L52 65 + imply SND_SOC_CS42L56 66 + imply SND_SOC_CS42L73 67 + imply SND_SOC_CS4265 68 + imply SND_SOC_CS4270 69 + imply SND_SOC_CS4271_I2C 70 + imply SND_SOC_CS4271_SPI 71 + imply SND_SOC_CS42XX8_I2C 72 + imply SND_SOC_CS43130 73 + imply SND_SOC_CS4341 74 + imply SND_SOC_CS4349 75 + imply SND_SOC_CS47L15 76 + imply SND_SOC_CS47L24 77 + imply SND_SOC_CS47L35 78 + imply SND_SOC_CS47L85 79 + imply SND_SOC_CS47L90 80 + imply SND_SOC_CS47L92 81 + imply SND_SOC_CS53L30 82 + imply SND_SOC_CX20442 83 + imply SND_SOC_CX2072X 84 + imply SND_SOC_DA7210 85 + imply SND_SOC_DA7213 86 + imply SND_SOC_DA7218 87 + imply SND_SOC_DA7219 88 + imply SND_SOC_DA732X 89 + imply SND_SOC_DA9055 90 + imply SND_SOC_DMIC 91 + imply SND_SOC_ES8316 92 + imply SND_SOC_ES8328_SPI 93 + imply SND_SOC_ES8328_I2C 94 + imply SND_SOC_ES7134 95 + imply SND_SOC_ES7241 96 + imply SND_SOC_GTM601 97 + imply SND_SOC_HDAC_HDMI 98 + imply SND_SOC_HDAC_HDA 99 + imply SND_SOC_ICS43432 100 + imply SND_SOC_INNO_RK3036 101 + imply SND_SOC_ISABELLE 102 + imply SND_SOC_JZ4740_CODEC 103 + imply SND_SOC_JZ4725B_CODEC 104 + imply SND_SOC_JZ4770_CODEC 105 + imply SND_SOC_LM4857 106 + imply SND_SOC_LM49453 107 + imply SND_SOC_LOCHNAGAR_SC 108 + imply SND_SOC_MAX98088 109 + imply SND_SOC_MAX98090 110 + imply SND_SOC_MAX98095 111 + imply SND_SOC_MAX98357A 112 + imply SND_SOC_MAX98371 113 + imply SND_SOC_MAX98504 114 + imply SND_SOC_MAX9867 115 + imply SND_SOC_MAX98925 116 + imply SND_SOC_MAX98926 117 + imply SND_SOC_MAX98927 118 + imply SND_SOC_MAX98373 119 + imply SND_SOC_MAX9850 120 + imply SND_SOC_MAX9860 121 + imply SND_SOC_MAX9759 122 + imply SND_SOC_MAX9768 123 + imply SND_SOC_MAX9877 124 + imply SND_SOC_MC13783 125 + imply SND_SOC_ML26124 126 + imply SND_SOC_MT6351 127 + imply SND_SOC_MT6358 128 + imply SND_SOC_MT6660 129 + imply SND_SOC_NAU8540 130 + imply SND_SOC_NAU8810 131 + imply SND_SOC_NAU8822 132 + imply SND_SOC_NAU8824 133 + imply SND_SOC_NAU8825 134 + imply SND_SOC_HDMI_CODEC 135 + imply SND_SOC_PCM1681 136 + imply SND_SOC_PCM1789_I2C 137 + imply SND_SOC_PCM179X_I2C 138 + imply SND_SOC_PCM179X_SPI 139 + imply SND_SOC_PCM186X_I2C 140 + imply SND_SOC_PCM186X_SPI 141 + imply SND_SOC_PCM3008 142 + imply SND_SOC_PCM3060_I2C 143 + imply SND_SOC_PCM3060_SPI 144 + imply SND_SOC_PCM3168A_I2C 145 + imply SND_SOC_PCM3168A_SPI 146 + imply SND_SOC_PCM5102A 147 + imply SND_SOC_PCM512x_I2C 148 + imply SND_SOC_PCM512x_SPI 149 + imply SND_SOC_RK3328 150 + imply SND_SOC_RT274 151 + imply SND_SOC_RT286 152 + imply SND_SOC_RT298 153 + imply SND_SOC_RT1011 154 + imply SND_SOC_RT1015 155 + imply SND_SOC_RT1305 156 + imply SND_SOC_RT1308 157 + imply SND_SOC_RT5514 158 + imply SND_SOC_RT5616 159 + imply SND_SOC_RT5631 160 + imply SND_SOC_RT5640 161 + imply SND_SOC_RT5645 162 + imply SND_SOC_RT5651 163 + imply SND_SOC_RT5659 164 + imply SND_SOC_RT5660 165 + imply SND_SOC_RT5663 166 + imply SND_SOC_RT5665 167 + imply SND_SOC_RT5668 168 + imply SND_SOC_RT5670 169 + imply SND_SOC_RT5677 170 + imply SND_SOC_RT5682 171 + imply SND_SOC_RT5682_SDW 172 + imply SND_SOC_RT700_SDW 173 + imply SND_SOC_RT711_SDW 174 + imply SND_SOC_RT715_SDW 175 + imply SND_SOC_RT1308_SDW 176 + imply SND_SOC_SGTL5000 177 + imply SND_SOC_SI476X 178 + imply SND_SOC_SIMPLE_AMPLIFIER 179 + imply SND_SOC_SIRF_AUDIO_CODEC 180 + imply SND_SOC_SPDIF 181 + imply SND_SOC_SSM2305 182 + imply SND_SOC_SSM2518 183 + imply SND_SOC_SSM2602_SPI 184 + imply SND_SOC_SSM2602_I2C 185 + imply SND_SOC_SSM4567 186 + imply SND_SOC_STA32X 187 + imply SND_SOC_STA350 188 + imply SND_SOC_STA529 189 + imply SND_SOC_STAC9766 190 + imply SND_SOC_STI_SAS 191 + imply SND_SOC_TAS2552 192 + imply SND_SOC_TAS2562 193 + imply SND_SOC_TAS2770 194 + imply SND_SOC_TAS5086 195 + imply SND_SOC_TAS571X 196 + imply SND_SOC_TAS5720 197 + imply SND_SOC_TAS6424 198 + imply SND_SOC_TDA7419 199 + imply SND_SOC_TFA9879 200 + imply SND_SOC_TLV320ADCX140 201 + imply SND_SOC_TLV320AIC23_I2C 202 + imply SND_SOC_TLV320AIC23_SPI 203 + imply SND_SOC_TLV320AIC26 204 + imply SND_SOC_TLV320AIC31XX 205 + imply SND_SOC_TLV320AIC32X4_I2C 206 + imply SND_SOC_TLV320AIC32X4_SPI 207 + imply SND_SOC_TLV320AIC3X 208 + imply SND_SOC_TPA6130A2 209 + imply SND_SOC_TLV320DAC33 210 + imply SND_SOC_TSCS42XX 211 + imply SND_SOC_TSCS454 212 + imply SND_SOC_TS3A227E 213 + imply SND_SOC_TWL4030 214 + imply SND_SOC_TWL6040 215 + imply SND_SOC_UDA1334 216 + imply SND_SOC_UDA134X 217 + imply SND_SOC_UDA1380 218 + imply SND_SOC_WCD9335 219 + imply SND_SOC_WCD934X 220 + imply SND_SOC_WL1273 221 + imply SND_SOC_WM0010 222 + imply SND_SOC_WM1250_EV1 223 + imply SND_SOC_WM2000 224 + imply SND_SOC_WM2200 225 + imply SND_SOC_WM5100 226 + imply SND_SOC_WM5102 227 + imply SND_SOC_WM5110 228 + imply SND_SOC_WM8350 229 + imply SND_SOC_WM8400 230 + imply SND_SOC_WM8510 231 + imply SND_SOC_WM8523 232 + imply SND_SOC_WM8524 233 + imply SND_SOC_WM8580 234 + imply SND_SOC_WM8711 235 + imply SND_SOC_WM8727 236 + imply SND_SOC_WM8728 237 + imply SND_SOC_WM8731 238 + imply SND_SOC_WM8737 239 + imply SND_SOC_WM8741 240 + imply SND_SOC_WM8750 241 + imply SND_SOC_WM8753 242 + imply SND_SOC_WM8770 243 + imply SND_SOC_WM8776 244 + imply SND_SOC_WM8782 245 + imply SND_SOC_WM8804_I2C 246 + imply SND_SOC_WM8804_SPI 247 + imply SND_SOC_WM8900 248 + imply SND_SOC_WM8903 249 + imply SND_SOC_WM8904 250 + imply SND_SOC_WM8940 251 + imply SND_SOC_WM8955 252 + imply SND_SOC_WM8960 253 + imply SND_SOC_WM8961 254 + imply SND_SOC_WM8962 255 + imply SND_SOC_WM8971 256 + imply SND_SOC_WM8974 257 + imply SND_SOC_WM8978 258 + imply SND_SOC_WM8983 259 + imply SND_SOC_WM8985 260 + imply SND_SOC_WM8988 261 + imply SND_SOC_WM8990 262 + imply SND_SOC_WM8991 263 + imply SND_SOC_WM8993 264 + imply SND_SOC_WM8994 265 + imply SND_SOC_WM8995 266 + imply SND_SOC_WM8996 267 + imply SND_SOC_WM8997 268 + imply SND_SOC_WM8998 269 + imply SND_SOC_WM9081 270 + imply SND_SOC_WM9090 271 + imply SND_SOC_WM9705 272 + imply SND_SOC_WM9712 273 + imply SND_SOC_WM9713 274 + imply SND_SOC_WSA881X 273 275 help 274 276 Normally ASoC codec drivers are only built if a machine driver which 275 277 uses them is also built since they are only usable with a machine ··· 285 283 286 284 config SND_SOC_88PM860X 287 285 tristate 286 + depends on MFD_88PM860X 288 287 289 288 config SND_SOC_ARIZONA 290 289 tristate ··· 321 318 322 319 config SND_SOC_AB8500_CODEC 323 320 tristate 321 + depends on ABX500_CORE 324 322 325 323 config SND_SOC_AC97_CODEC 326 324 tristate "Build generic ASoC AC97 CODEC driver" ··· 330 326 331 327 config SND_SOC_AD1836 332 328 tristate 329 + depends on SPI_MASTER 333 330 334 331 config SND_SOC_AD193X 335 332 tristate 336 333 337 334 config SND_SOC_AD193X_SPI 338 335 tristate 336 + depends on SPI_MASTER 339 337 select SND_SOC_AD193X 340 338 341 339 config SND_SOC_AD193X_I2C 342 340 tristate 341 + depends on I2C 343 342 select SND_SOC_AD193X 344 343 345 344 config SND_SOC_AD1980 346 - select REGMAP_AC97 347 345 tristate 346 + depends on SND_SOC_AC97_BUS 347 + select REGMAP_AC97 348 348 349 349 config SND_SOC_AD73311 350 350 tristate ··· 358 350 359 351 config SND_SOC_ADAU1373 360 352 tristate 353 + depends on I2C 361 354 select SND_SOC_ADAU_UTILS 362 355 363 356 config SND_SOC_ADAU1701 ··· 393 384 394 385 config SND_SOC_ADAU1781_I2C 395 386 tristate 387 + depends on I2C 396 388 select SND_SOC_ADAU1781 397 389 select REGMAP_I2C 398 390 399 391 config SND_SOC_ADAU1781_SPI 400 392 tristate 393 + depends on SPI_MASTER 401 394 select SND_SOC_ADAU1781 402 395 select REGMAP_SPI 403 396 ··· 408 397 409 398 config SND_SOC_ADAU1977_SPI 410 399 tristate 400 + depends on SPI_MASTER 411 401 select SND_SOC_ADAU1977 412 402 select REGMAP_SPI 413 403 414 404 config SND_SOC_ADAU1977_I2C 415 405 tristate 406 + depends on I2C 416 407 select SND_SOC_ADAU1977 417 408 select REGMAP_I2C 418 409 ··· 453 440 454 441 config SND_SOC_ADAV801 455 442 tristate 443 + depends on SPI_MASTER 456 444 select SND_SOC_ADAV80X 457 445 458 446 config SND_SOC_ADAV803 459 447 tristate 448 + depends on I2C 460 449 select SND_SOC_ADAV80X 461 450 462 451 config SND_SOC_ADS117X ··· 480 465 481 466 config SND_SOC_AK4535 482 467 tristate 468 + depends on I2C 483 469 484 470 config SND_SOC_AK4554 485 471 tristate "AKM AK4554 CODEC" ··· 491 475 492 476 config SND_SOC_AK4641 493 477 tristate 478 + depends on I2C 494 479 495 480 config SND_SOC_AK4642 496 481 tristate "AKM AK4642 CODEC" ··· 499 482 500 483 config SND_SOC_AK4671 501 484 tristate 485 + depends on I2C 502 486 503 487 config SND_SOC_AK5386 504 488 tristate "AKM AK5638 CODEC" ··· 515 497 516 498 config SND_SOC_ALC5632 517 499 tristate 500 + depends on I2C 518 501 519 502 config SND_SOC_BD28623 520 503 tristate "ROHM BD28623 CODEC" ··· 650 631 651 632 config SND_SOC_CS47L24 652 633 tristate 634 + depends on MFD_CS47L24 653 635 654 636 config SND_SOC_CS47L35 655 637 tristate ··· 717 697 718 698 config SND_SOC_DA7210 719 699 tristate 700 + depends on I2C 720 701 721 702 config SND_SOC_DA7213 722 703 tristate "Dialog DA7213 CODEC" ··· 725 704 726 705 config SND_SOC_DA7218 727 706 tristate 707 + depends on I2C 728 708 729 709 config SND_SOC_DA7219 730 710 tristate 711 + depends on I2C 731 712 732 713 config SND_SOC_DA732X 733 714 tristate 715 + depends on I2C 734 716 735 717 config SND_SOC_DA9055 736 718 tristate 719 + depends on I2C 737 720 738 721 config SND_SOC_DMIC 739 722 tristate "Generic Digital Microphone CODEC" ··· 797 772 798 773 config SND_SOC_ISABELLE 799 774 tristate 775 + depends on I2C 800 776 801 777 config SND_SOC_LM49453 802 778 tristate 779 + depends on I2C 803 780 804 781 config SND_SOC_LOCHNAGAR_SC 805 782 tristate "Lochnagar Sound Card" ··· 828 801 depends on I2C 829 802 830 803 config SND_SOC_MAX98090 831 - tristate 804 + tristate 805 + depends on I2C 832 806 833 807 config SND_SOC_MAX98095 834 - tristate 808 + tristate 809 + depends on I2C 835 810 836 811 config SND_SOC_MAX98357A 837 812 tristate "Maxim MAX98357A CODEC" 838 813 depends on GPIOLIB 839 814 840 815 config SND_SOC_MAX98371 841 - tristate 816 + tristate 817 + depends on I2C 842 818 843 819 config SND_SOC_MAX98504 844 820 tristate "Maxim MAX98504 speaker amplifier" ··· 852 822 depends on I2C 853 823 854 824 config SND_SOC_MAX98925 855 - tristate 825 + tristate 826 + depends on I2C 856 827 857 828 config SND_SOC_MAX98926 858 829 tristate 830 + depends on I2C 859 831 860 832 config SND_SOC_MAX98927 861 833 tristate "Maxim Integrated MAX98927 Speaker Amplifier" ··· 869 837 870 838 config SND_SOC_MAX9850 871 839 tristate 840 + depends on I2C 872 841 873 842 config SND_SOC_MAX9860 874 843 tristate "Maxim MAX9860 Mono Audio Voice Codec" ··· 1048 1015 1049 1016 config SND_SOC_RT1011 1050 1017 tristate 1018 + depends on I2C 1051 1019 1052 1020 config SND_SOC_RT1015 1053 1021 tristate 1022 + depends on I2C 1054 1023 1055 1024 config SND_SOC_RT1305 1056 1025 tristate 1026 + depends on I2C 1057 1027 1058 1028 config SND_SOC_RT1308 1059 1029 tristate 1030 + depends on I2C 1060 1031 1061 1032 config SND_SOC_RT1308_SDW 1062 1033 tristate "Realtek RT1308 Codec - SDW" 1063 - depends on SOUNDWIRE 1034 + depends on I2C && SOUNDWIRE 1064 1035 select REGMAP_SOUNDWIRE 1065 1036 1066 1037 config SND_SOC_RT5514 1067 1038 tristate 1039 + depends on I2C 1068 1040 1069 1041 config SND_SOC_RT5514_SPI 1070 1042 tristate 1043 + depends on SPI_MASTER 1071 1044 1072 1045 config SND_SOC_RT5514_SPI_BUILTIN 1073 1046 bool # force RT5514_SPI to be built-in to avoid link errors ··· 1089 1050 1090 1051 config SND_SOC_RT5640 1091 1052 tristate 1053 + depends on I2C 1092 1054 1093 1055 config SND_SOC_RT5645 1094 1056 tristate 1057 + depends on I2C 1095 1058 1096 1059 config SND_SOC_RT5651 1097 1060 tristate 1061 + depends on I2C 1098 1062 1099 1063 config SND_SOC_RT5659 1100 1064 tristate 1065 + depends on I2C 1101 1066 1102 1067 config SND_SOC_RT5660 1103 1068 tristate 1069 + depends on I2C 1104 1070 1105 1071 config SND_SOC_RT5663 1106 1072 tristate 1073 + depends on I2C 1107 1074 1108 1075 config SND_SOC_RT5665 1109 1076 tristate 1077 + depends on I2C 1110 1078 1111 1079 config SND_SOC_RT5668 1112 1080 tristate 1081 + depends on I2C 1113 1082 1114 1083 config SND_SOC_RT5670 1115 1084 tristate 1085 + depends on I2C 1116 1086 1117 1087 config SND_SOC_RT5677 1118 1088 tristate 1089 + depends on I2C 1119 1090 select REGMAP_I2C 1120 1091 select REGMAP_IRQ 1121 1092 ··· 1135 1086 1136 1087 config SND_SOC_RT5682 1137 1088 tristate 1089 + depends on I2C || SOUNDWIRE 1090 + 1091 + config SND_SOC_RT5682_SDW 1092 + tristate "Realtek RT5682 Codec - SDW" 1093 + depends on SOUNDWIRE 1094 + select SND_SOC_RT5682 1095 + select REGMAP_SOUNDWIRE 1138 1096 1139 1097 config SND_SOC_RT700 1140 1098 tristate ··· 1209 1153 1210 1154 config SND_SOC_SSM2518 1211 1155 tristate 1156 + depends on I2C 1212 1157 1213 1158 config SND_SOC_SSM2602 1214 1159 tristate ··· 1241 1184 1242 1185 config SND_SOC_STA529 1243 1186 tristate 1187 + depends on I2C 1244 1188 1245 1189 config SND_SOC_STAC9766 1246 1190 tristate 1191 + depends on SND_SOC_AC97_BUS 1247 1192 1248 1193 config SND_SOC_STI_SAS 1249 1194 tristate "codec Audio support for STI SAS codec" ··· 1340 1281 1341 1282 config SND_SOC_TLV320DAC33 1342 1283 tristate 1284 + depends on I2C 1285 + 1286 + config SND_SOC_TLV320ADCX140 1287 + tristate "Texas Instruments TLV320ADCX140 CODEC family" 1288 + depends on I2C 1289 + select REGMAP_I2C 1290 + help 1291 + Add support for Texas Instruments tlv320adc3140, tlv320adc5140 and 1292 + tlv320adc6140 quad channel ADCs. 1343 1293 1344 1294 config SND_SOC_TS3A227E 1345 1295 tristate "TI Headset/Mic detect and keypress chip" ··· 1369 1301 Add support for Tempo Semiconductor's TSCS454 audio CODEC. 1370 1302 1371 1303 config SND_SOC_TWL4030 1372 - select MFD_TWL4030_AUDIO 1373 1304 tristate 1305 + depends on TWL4030_CORE 1306 + select MFD_TWL4030_AUDIO 1374 1307 1375 1308 config SND_SOC_TWL6040 1376 1309 tristate 1310 + depends on TWL6040_CORE 1377 1311 1378 1312 config SND_SOC_UDA1334 1379 1313 tristate "NXP UDA1334 DAC" ··· 1415 1345 1416 1346 config SND_SOC_WM0010 1417 1347 tristate 1348 + depends on SPI_MASTER 1418 1349 1419 1350 config SND_SOC_WM1250_EV1 1420 1351 tristate 1352 + depends on I2C 1421 1353 1422 1354 config SND_SOC_WM2000 1423 1355 tristate 1356 + depends on I2C 1424 1357 1425 1358 config SND_SOC_WM2200 1426 1359 tristate 1360 + depends on I2C 1427 1361 1428 1362 config SND_SOC_WM5100 1429 1363 tristate 1364 + depends on I2C 1430 1365 1431 1366 config SND_SOC_WM5102 1432 1367 tristate 1368 + depends on MFD_WM5102 1433 1369 1434 1370 config SND_SOC_WM5110 1435 1371 tristate 1372 + depends on MFD_WM5110 1436 1373 1437 1374 config SND_SOC_WM8350 1438 1375 tristate 1376 + depends on MFD_WM8350 1439 1377 1440 1378 config SND_SOC_WM8400 1441 1379 tristate 1380 + # FIXME nothing selects SND_SOC_WM8400?? 1381 + depends on MFD_WM8400 1442 1382 1443 1383 config SND_SOC_WM8510 1444 1384 tristate "Wolfson Microelectronics WM8510 CODEC" ··· 1536 1456 1537 1457 config SND_SOC_WM8940 1538 1458 tristate 1459 + depends on I2C 1539 1460 1540 1461 config SND_SOC_WM8955 1541 1462 tristate 1463 + depends on I2C 1542 1464 1543 1465 config SND_SOC_WM8960 1544 1466 tristate "Wolfson Microelectronics WM8960 CODEC" ··· 1548 1466 1549 1467 config SND_SOC_WM8961 1550 1468 tristate 1469 + depends on I2C 1551 1470 1552 1471 config SND_SOC_WM8962 1553 1472 tristate "Wolfson Microelectronics WM8962 CODEC" ··· 1556 1473 1557 1474 config SND_SOC_WM8971 1558 1475 tristate 1476 + depends on I2C 1559 1477 1560 1478 config SND_SOC_WM8974 1561 1479 tristate "Wolfson Microelectronics WM8974 codec" ··· 1568 1484 1569 1485 config SND_SOC_WM8983 1570 1486 tristate 1487 + depends on I2C 1571 1488 1572 1489 config SND_SOC_WM8985 1573 1490 tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver" ··· 1579 1494 1580 1495 config SND_SOC_WM8990 1581 1496 tristate 1497 + depends on I2C 1582 1498 1583 1499 config SND_SOC_WM8991 1584 1500 tristate 1501 + depends on I2C 1585 1502 1586 1503 config SND_SOC_WM8993 1587 1504 tristate 1505 + depends on I2C 1588 1506 1589 1507 config SND_SOC_WM8994 1590 1508 tristate ··· 1597 1509 1598 1510 config SND_SOC_WM8996 1599 1511 tristate 1512 + depends on I2C 1600 1513 1601 1514 config SND_SOC_WM8997 1602 1515 tristate 1516 + depends on MFD_WM8997 1603 1517 1604 1518 config SND_SOC_WM8998 1605 1519 tristate 1520 + depends on MFD_WM8998 1606 1521 1607 1522 config SND_SOC_WM9081 1608 1523 tristate ··· 1613 1522 1614 1523 config SND_SOC_WM9090 1615 1524 tristate 1525 + depends on I2C 1616 1526 1617 1527 config SND_SOC_WM9705 1618 1528 tristate 1529 + depends on SND_SOC_AC97_BUS 1619 1530 select REGMAP_AC97 1620 1531 select AC97_BUS_COMPAT if AC97_BUS_NEW 1621 1532 1622 1533 config SND_SOC_WM9712 1623 1534 tristate 1535 + depends on SND_SOC_AC97_BUS 1624 1536 select REGMAP_AC97 1625 1537 select AC97_BUS_COMPAT if AC97_BUS_NEW 1626 1538 1627 1539 config SND_SOC_WM9713 1628 1540 tristate 1541 + depends on SND_SOC_AC97_BUS 1629 1542 select REGMAP_AC97 1630 1543 select AC97_BUS_COMPAT if AC97_BUS_NEW 1631 1544 ··· 1650 1555 # Amp 1651 1556 config SND_SOC_LM4857 1652 1557 tristate 1558 + depends on I2C 1653 1559 1654 1560 config SND_SOC_MAX9759 1655 1561 tristate "Maxim MAX9759 speaker Amplifier" ··· 1658 1562 1659 1563 config SND_SOC_MAX9768 1660 1564 tristate 1565 + depends on I2C 1661 1566 1662 1567 config SND_SOC_MAX9877 1663 1568 tristate 1569 + depends on I2C 1664 1570 1665 1571 config SND_SOC_MC13783 1666 1572 tristate 1573 + depends on MFD_MC13XXX 1667 1574 1668 1575 config SND_SOC_ML26124 1669 1576 tristate 1577 + depends on I2C 1670 1578 1671 1579 config SND_SOC_MT6351 1672 1580 tristate "MediaTek MT6351 Codec" ··· 1708 1608 1709 1609 config SND_SOC_NAU8825 1710 1610 tristate 1611 + depends on I2C 1711 1612 1712 1613 config SND_SOC_TPA6130A2 1713 1614 tristate "Texas Instruments TPA6130A2 headphone amplifier"
+4
sound/soc/codecs/Makefile
··· 177 177 snd-soc-rt5677-objs := rt5677.o 178 178 snd-soc-rt5677-spi-objs := rt5677-spi.o 179 179 snd-soc-rt5682-objs := rt5682.o 180 + snd-soc-rt5682-sdw-objs := rt5682-sdw.o 180 181 snd-soc-rt700-objs := rt700.o rt700-sdw.o 181 182 snd-soc-rt711-objs := rt711.o rt711-sdw.o 182 183 snd-soc-rt715-objs := rt715.o rt715-sdw.o ··· 219 218 snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o 220 219 snd-soc-tlv320aic3x-objs := tlv320aic3x.o 221 220 snd-soc-tlv320dac33-objs := tlv320dac33.o 221 + snd-soc-tlv320adcx140-objs := tlv320adcx140.o 222 222 snd-soc-tscs42xx-objs := tscs42xx.o 223 223 snd-soc-tscs454-objs := tscs454.o 224 224 snd-soc-ts3a227e-objs := ts3a227e.o ··· 478 476 obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o 479 477 obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o 480 478 obj-$(CONFIG_SND_SOC_RT5682) += snd-soc-rt5682.o 479 + obj-$(CONFIG_SND_SOC_RT5682_SDW) += snd-soc-rt5682-sdw.o 481 480 obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o 482 481 obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o 483 482 obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o ··· 519 516 obj-$(CONFIG_SND_SOC_TLV320AIC32X4_SPI) += snd-soc-tlv320aic32x4-spi.o 520 517 obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 521 518 obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 519 + obj-$(CONFIG_SND_SOC_TLV320ADCX140) += snd-soc-tlv320adcx140.o 522 520 obj-$(CONFIG_SND_SOC_TSCS42XX) += snd-soc-tscs42xx.o 523 521 obj-$(CONFIG_SND_SOC_TSCS454) += snd-soc-tscs454.o 524 522 obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o
+22 -3
sound/soc/codecs/cros_ec_codec.c
··· 45 45 /* DMIC */ 46 46 atomic_t dmic_probed; 47 47 48 + /* I2S_RX */ 49 + uint32_t i2s_rx_bclk_ratio; 50 + 48 51 /* WoV */ 49 52 bool wov_enabled; 50 53 uint8_t *wov_audio_shm_p; ··· 262 259 snd_soc_component_get_drvdata(component); 263 260 struct ec_param_ec_codec_i2s_rx p; 264 261 enum ec_codec_i2s_rx_sample_depth depth; 262 + uint32_t bclk; 265 263 int ret; 266 264 267 265 if (params_rate(params) != 48000) ··· 288 284 if (ret < 0) 289 285 return ret; 290 286 291 - dev_dbg(component->dev, "set bclk to %u\n", 292 - snd_soc_params_to_bclk(params)); 287 + if (priv->i2s_rx_bclk_ratio) 288 + bclk = params_rate(params) * priv->i2s_rx_bclk_ratio; 289 + else 290 + bclk = snd_soc_params_to_bclk(params); 291 + 292 + dev_dbg(component->dev, "set bclk to %u\n", bclk); 293 293 294 294 p.cmd = EC_CODEC_I2S_RX_SET_BCLK; 295 - p.set_bclk_param.bclk = snd_soc_params_to_bclk(params); 295 + p.set_bclk_param.bclk = bclk; 296 296 return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, 297 297 (uint8_t *)&p, sizeof(p), NULL, 0); 298 + } 299 + 300 + static int i2s_rx_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) 301 + { 302 + struct snd_soc_component *component = dai->component; 303 + struct cros_ec_codec_priv *priv = 304 + snd_soc_component_get_drvdata(component); 305 + 306 + priv->i2s_rx_bclk_ratio = ratio; 307 + return 0; 298 308 } 299 309 300 310 static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ··· 358 340 static const struct snd_soc_dai_ops i2s_rx_dai_ops = { 359 341 .hw_params = i2s_rx_hw_params, 360 342 .set_fmt = i2s_rx_set_fmt, 343 + .set_bclk_ratio = i2s_rx_set_bclk_ratio, 361 344 }; 362 345 363 346 static int i2s_rx_event(struct snd_soc_dapm_widget *w,
+2 -2
sound/soc/codecs/cs4271.c
··· 356 356 */ 357 357 358 358 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 359 - !dai->capture_active) || 359 + !dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]) || 360 360 (substream->stream == SNDRV_PCM_STREAM_CAPTURE && 361 - !dai->playback_active)) { 361 + !dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])) { 362 362 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, 363 363 CS4271_MODE2_PDN, 364 364 CS4271_MODE2_PDN);
+2 -2
sound/soc/codecs/cs47l15.c
··· 1239 1239 struct madera *madera = priv->madera; 1240 1240 int n_adsp; 1241 1241 1242 - if (strcmp(rtd->codec_dai->name, "cs47l15-dsp-trace") == 0) { 1242 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l15-dsp-trace") == 0) { 1243 1243 n_adsp = 0; 1244 1244 } else { 1245 1245 dev_err(madera->dev, 1246 1246 "No suitable compressed stream for DAI '%s'\n", 1247 - rtd->codec_dai->name); 1247 + asoc_rtd_to_codec(rtd, 0)->name); 1248 1248 return -EINVAL; 1249 1249 } 1250 1250
+3 -3
sound/soc/codecs/cs47l24.c
··· 1076 1076 struct arizona *arizona = priv->core.arizona; 1077 1077 int n_adsp; 1078 1078 1079 - if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-voicectrl") == 0) { 1079 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l24-dsp-voicectrl") == 0) { 1080 1080 n_adsp = 2; 1081 - } else if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-trace") == 0) { 1081 + } else if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l24-dsp-trace") == 0) { 1082 1082 n_adsp = 1; 1083 1083 } else { 1084 1084 dev_err(arizona->dev, 1085 1085 "No suitable compressed stream for DAI '%s'\n", 1086 - rtd->codec_dai->name); 1086 + asoc_rtd_to_codec(rtd, 0)->name); 1087 1087 return -EINVAL; 1088 1088 } 1089 1089
+3 -3
sound/soc/codecs/cs47l35.c
··· 1514 1514 struct madera *madera = priv->madera; 1515 1515 int n_adsp; 1516 1516 1517 - if (strcmp(rtd->codec_dai->name, "cs47l35-dsp-voicectrl") == 0) { 1517 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l35-dsp-voicectrl") == 0) { 1518 1518 n_adsp = 2; 1519 - } else if (strcmp(rtd->codec_dai->name, "cs47l35-dsp-trace") == 0) { 1519 + } else if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l35-dsp-trace") == 0) { 1520 1520 n_adsp = 0; 1521 1521 } else { 1522 1522 dev_err(madera->dev, 1523 1523 "No suitable compressed stream for DAI '%s'\n", 1524 - rtd->codec_dai->name); 1524 + asoc_rtd_to_codec(rtd, 0)->name); 1525 1525 return -EINVAL; 1526 1526 } 1527 1527
+3 -3
sound/soc/codecs/cs47l85.c
··· 2457 2457 struct madera *madera = priv->madera; 2458 2458 int n_adsp; 2459 2459 2460 - if (strcmp(rtd->codec_dai->name, "cs47l85-dsp-voicectrl") == 0) { 2460 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l85-dsp-voicectrl") == 0) { 2461 2461 n_adsp = 5; 2462 - } else if (strcmp(rtd->codec_dai->name, "cs47l85-dsp-trace") == 0) { 2462 + } else if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l85-dsp-trace") == 0) { 2463 2463 n_adsp = 0; 2464 2464 } else { 2465 2465 dev_err(madera->dev, 2466 2466 "No suitable compressed stream for DAI '%s'\n", 2467 - rtd->codec_dai->name); 2467 + asoc_rtd_to_codec(rtd, 0)->name); 2468 2468 return -EINVAL; 2469 2469 } 2470 2470
+3 -3
sound/soc/codecs/cs47l90.c
··· 2368 2368 struct madera *madera = priv->madera; 2369 2369 int n_adsp; 2370 2370 2371 - if (strcmp(rtd->codec_dai->name, "cs47l90-dsp-voicectrl") == 0) { 2371 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l90-dsp-voicectrl") == 0) { 2372 2372 n_adsp = 5; 2373 - } else if (strcmp(rtd->codec_dai->name, "cs47l90-dsp-trace") == 0) { 2373 + } else if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l90-dsp-trace") == 0) { 2374 2374 n_adsp = 0; 2375 2375 } else { 2376 2376 dev_err(madera->dev, 2377 2377 "No suitable compressed stream for DAI '%s'\n", 2378 - rtd->codec_dai->name); 2378 + asoc_rtd_to_codec(rtd, 0)->name); 2379 2379 return -EINVAL; 2380 2380 } 2381 2381
+2 -2
sound/soc/codecs/cs47l92.c
··· 1840 1840 struct madera *madera = priv->madera; 1841 1841 int n_adsp; 1842 1842 1843 - if (strcmp(rtd->codec_dai->name, "cs47l92-dsp-trace") == 0) { 1843 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "cs47l92-dsp-trace") == 0) { 1844 1844 n_adsp = 0; 1845 1845 } else { 1846 1846 dev_err(madera->dev, 1847 1847 "No suitable compressed stream for DAI '%s'\n", 1848 - rtd->codec_dai->name); 1848 + asoc_rtd_to_codec(rtd, 0)->name); 1849 1849 return -EINVAL; 1850 1850 } 1851 1851
+3 -3
sound/soc/codecs/hdac_hdmi.c
··· 1998 1998 1999 1999 static int hdac_hdmi_dev_probe(struct hdac_device *hdev) 2000 2000 { 2001 - struct hdac_hdmi_priv *hdmi_priv = NULL; 2001 + struct hdac_hdmi_priv *hdmi_priv; 2002 2002 struct snd_soc_dai_driver *hdmi_dais = NULL; 2003 - struct hdac_ext_link *hlink = NULL; 2003 + struct hdac_ext_link *hlink; 2004 2004 int num_dais = 0; 2005 - int ret = 0; 2005 + int ret; 2006 2006 struct hdac_driver *hdrv = drv_to_hdac_driver(hdev->dev.driver); 2007 2007 const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv); 2008 2008
+18 -19
sound/soc/codecs/max98357a.c
··· 5 5 */ 6 6 7 7 #include <linux/acpi.h> 8 + #include <linux/delay.h> 8 9 #include <linux/device.h> 9 10 #include <linux/err.h> 10 11 #include <linux/gpio.h> ··· 25 24 unsigned int sdmode_delay; 26 25 }; 27 26 28 - static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, 29 - int cmd, struct snd_soc_dai *dai) 27 + static int max98357a_sdmode_event(struct snd_soc_dapm_widget *w, 28 + struct snd_kcontrol *kcontrol, int event) 30 29 { 31 - struct max98357a_priv *max98357a = snd_soc_dai_get_drvdata(dai); 30 + struct snd_soc_component *component = 31 + snd_soc_dapm_to_component(w->dapm); 32 + struct max98357a_priv *max98357a = 33 + snd_soc_component_get_drvdata(component); 32 34 33 35 if (!max98357a->sdmode) 34 36 return 0; 35 37 36 - switch (cmd) { 37 - case SNDRV_PCM_TRIGGER_START: 38 - case SNDRV_PCM_TRIGGER_RESUME: 39 - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 40 - mdelay(max98357a->sdmode_delay); 38 + if (event & SND_SOC_DAPM_POST_PMU) { 39 + msleep(max98357a->sdmode_delay); 41 40 gpiod_set_value(max98357a->sdmode, 1); 42 - break; 43 - case SNDRV_PCM_TRIGGER_STOP: 44 - case SNDRV_PCM_TRIGGER_SUSPEND: 45 - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 41 + dev_dbg(component->dev, "set sdmode to 1"); 42 + } else if (event & SND_SOC_DAPM_PRE_PMD) { 46 43 gpiod_set_value(max98357a->sdmode, 0); 47 - break; 44 + dev_dbg(component->dev, "set sdmode to 0"); 48 45 } 49 46 50 47 return 0; ··· 50 51 51 52 static const struct snd_soc_dapm_widget max98357a_dapm_widgets[] = { 52 53 SND_SOC_DAPM_OUTPUT("Speaker"), 54 + SND_SOC_DAPM_OUT_DRV_E("SD_MODE", SND_SOC_NOPM, 0, 0, NULL, 0, 55 + max98357a_sdmode_event, 56 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 53 57 }; 54 58 55 59 static const struct snd_soc_dapm_route max98357a_dapm_routes[] = { 56 - {"Speaker", NULL, "HiFi Playback"}, 60 + {"SD_MODE", NULL, "HiFi Playback"}, 61 + {"Speaker", NULL, "SD_MODE"}, 57 62 }; 58 63 59 64 static const struct snd_soc_component_driver max98357a_component_driver = { ··· 69 66 .use_pmdown_time = 1, 70 67 .endianness = 1, 71 68 .non_legacy_dai_naming = 1, 72 - }; 73 - 74 - static const struct snd_soc_dai_ops max98357a_dai_ops = { 75 - .trigger = max98357a_daiops_trigger, 76 69 }; 77 70 78 71 static struct snd_soc_dai_driver max98357a_dai_driver = { ··· 90 91 .channels_min = 1, 91 92 .channels_max = 2, 92 93 }, 93 - .ops = &max98357a_dai_ops, 94 94 }; 95 95 96 96 static int max98357a_platform_probe(struct platform_device *pdev) ··· 133 135 #ifdef CONFIG_ACPI 134 136 static const struct acpi_device_id max98357a_acpi_match[] = { 135 137 { "MX98357A", 0 }, 138 + { "MX98360A", 0 }, 136 139 {}, 137 140 }; 138 141 MODULE_DEVICE_TABLE(acpi, max98357a_acpi_match);
+76 -5
sound/soc/codecs/mt6660.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 // 1 + // SPDX-License-Identifier: GPL-2.0 2 2 3 3 // Copyright (c) 2019 MediaTek Inc. 4 4 5 5 #include <linux/module.h> 6 6 #include <linux/kernel.h> 7 - #include <linux/version.h> 8 7 #include <linux/err.h> 9 8 #include <linux/i2c.h> 10 9 #include <linux/pm_runtime.h> 11 10 #include <linux/delay.h> 12 - #include <linux/debugfs.h> 13 11 #include <sound/soc.h> 14 12 #include <sound/tlv.h> 15 13 #include <sound/pcm_params.h> ··· 223 225 0x01, on_off ? 0x00 : 0x01); 224 226 } 225 227 228 + struct reg_table { 229 + uint32_t addr; 230 + uint32_t mask; 231 + uint32_t val; 232 + }; 233 + 234 + static const struct reg_table mt6660_setting_table[] = { 235 + { 0x20, 0x80, 0x00 }, 236 + { 0x30, 0x01, 0x00 }, 237 + { 0x50, 0x1c, 0x04 }, 238 + { 0xB1, 0x0c, 0x00 }, 239 + { 0xD3, 0x03, 0x03 }, 240 + { 0xE0, 0x01, 0x00 }, 241 + { 0x98, 0x44, 0x04 }, 242 + { 0xB9, 0xff, 0x82 }, 243 + { 0xB7, 0x7777, 0x7273 }, 244 + { 0xB6, 0x07, 0x03 }, 245 + { 0x6B, 0xe0, 0x20 }, 246 + { 0x07, 0xff, 0x70 }, 247 + { 0xBB, 0xff, 0x20 }, 248 + { 0x69, 0xff, 0x40 }, 249 + { 0xBD, 0xffff, 0x17f8 }, 250 + { 0x70, 0xff, 0x15 }, 251 + { 0x7C, 0xff, 0x00 }, 252 + { 0x46, 0xff, 0x1d }, 253 + { 0x1A, 0xffffffff, 0x7fdb7ffe }, 254 + { 0x1B, 0xffffffff, 0x7fdb7ffe }, 255 + { 0x51, 0xff, 0x58 }, 256 + { 0xA2, 0xff, 0xce }, 257 + { 0x33, 0xffff, 0x7fff }, 258 + { 0x4C, 0xffff, 0x0116 }, 259 + { 0x16, 0x1800, 0x0800 }, 260 + { 0x68, 0x1f, 0x07 }, 261 + }; 262 + 263 + static int mt6660_component_setting(struct snd_soc_component *component) 264 + { 265 + struct mt6660_chip *chip = snd_soc_component_get_drvdata(component); 266 + int ret = 0; 267 + size_t i = 0; 268 + 269 + ret = _mt6660_chip_power_on(chip, 1); 270 + if (ret < 0) { 271 + dev_err(component->dev, "%s chip power on failed\n", __func__); 272 + return ret; 273 + } 274 + 275 + for (i = 0; i < ARRAY_SIZE(mt6660_setting_table); i++) { 276 + ret = snd_soc_component_update_bits(component, 277 + mt6660_setting_table[i].addr, 278 + mt6660_setting_table[i].mask, 279 + mt6660_setting_table[i].val); 280 + if (ret < 0) { 281 + dev_err(component->dev, "%s update 0x%02x failed\n", 282 + __func__, mt6660_setting_table[i].addr); 283 + return ret; 284 + } 285 + } 286 + 287 + ret = _mt6660_chip_power_on(chip, 0); 288 + if (ret < 0) { 289 + dev_err(component->dev, "%s chip power off failed\n", __func__); 290 + return ret; 291 + } 292 + 293 + return 0; 294 + } 295 + 226 296 static int mt6660_component_probe(struct snd_soc_component *component) 227 297 { 228 298 struct mt6660_chip *chip = snd_soc_component_get_drvdata(component); 299 + int ret; 229 300 230 301 dev_dbg(component->dev, "%s\n", __func__); 231 302 snd_soc_component_init_regmap(component, chip->regmap); 232 303 233 - return 0; 304 + ret = mt6660_component_setting(component); 305 + if (ret < 0) 306 + dev_err(chip->dev, "mt6660 component setting failed\n"); 307 + 308 + return ret; 234 309 } 235 310 236 311 static void mt6660_component_remove(struct snd_soc_component *component) ··· 577 506 MODULE_AUTHOR("Jeff Chang <jeff_chang@richtek.com>"); 578 507 MODULE_DESCRIPTION("MT6660 SPKAMP Driver"); 579 508 MODULE_LICENSE("GPL"); 580 - MODULE_VERSION("1.0.7_G"); 509 + MODULE_VERSION("1.0.8_G");
+16 -15
sound/soc/codecs/rk3328_codec.c
··· 7 7 #include <linux/clk.h> 8 8 #include <linux/delay.h> 9 9 #include <linux/device.h> 10 + #include <linux/gpio/consumer.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of.h> 12 13 #include <linux/platform_device.h> ··· 32 31 33 32 struct rk3328_codec_priv { 34 33 struct regmap *regmap; 35 - struct regmap *grf; 34 + struct gpio_desc *mute; 36 35 struct clk *mclk; 37 36 struct clk *pclk; 38 37 unsigned int sclk; ··· 105 104 DAC_MODE_MASK, val); 106 105 107 106 return 0; 108 - } 109 - 110 - static void rk3328_analog_output(struct rk3328_codec_priv *rk3328, int mute) 111 - { 112 - unsigned int val = BIT(17); 113 - 114 - if (mute) 115 - val |= BIT(1); 116 - 117 - regmap_write(rk3328->grf, RK3328_GRF_SOC_CON10, val); 118 107 } 119 108 120 109 static int rk3328_digital_mute(struct snd_soc_dai *dai, int mute) ··· 196 205 } 197 206 198 207 msleep(rk3328->spk_depop_time); 199 - rk3328_analog_output(rk3328, 1); 208 + gpiod_set_value(rk3328->mute, 0); 200 209 201 210 regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL, 202 211 HPOUTL_GAIN_MASK, OUT_VOLUME); ··· 237 246 { 238 247 size_t i; 239 248 240 - rk3328_analog_output(rk3328, 0); 249 + gpiod_set_value(rk3328->mute, 1); 241 250 242 251 regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL, 243 252 HPOUTL_GAIN_MASK, 0); ··· 437 446 dev_err(&pdev->dev, "missing 'rockchip,grf'\n"); 438 447 return PTR_ERR(grf); 439 448 } 440 - rk3328->grf = grf; 441 449 /* enable i2s_acodec_en */ 442 450 regmap_write(grf, RK3328_GRF_SOC_CON2, 443 451 (BIT(14) << 16 | BIT(14))); ··· 448 458 rk3328->spk_depop_time = 200; 449 459 } 450 460 451 - rk3328_analog_output(rk3328, 0); 461 + rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH); 462 + if (IS_ERR(rk3328->mute)) 463 + return PTR_ERR(rk3328->mute); 464 + /* 465 + * Rock64 is the only supported platform to have widely relied on 466 + * this; if we do happen to come across an old DTB, just leave the 467 + * external mute forced off. 468 + */ 469 + if (!rk3328->mute && of_machine_is_compatible("pine64,rock64")) { 470 + dev_warn(&pdev->dev, "assuming implicit control of GPIO_MUTE; update devicetree if possible\n"); 471 + regmap_write(grf, RK3328_GRF_SOC_CON10, BIT(17) | BIT(1)); 472 + } 452 473 453 474 rk3328->mclk = devm_clk_get(&pdev->dev, "mclk"); 454 475 if (IS_ERR(rk3328->mclk))
+1
sound/soc/codecs/rl6231.c
··· 102 102 static const struct pll_calc_map pll_preset_table[] = { 103 103 {19200000, 4096000, 23, 14, 1, false}, 104 104 {19200000, 24576000, 3, 30, 3, false}, 105 + {3840000, 24576000, 3, 30, 0, true}, 105 106 }; 106 107 107 108 static unsigned int find_best_div(unsigned int in,
+1 -1
sound/soc/codecs/rl6231.h
··· 10 10 #ifndef __RL6231_H__ 11 11 #define __RL6231_H__ 12 12 13 - #define RL6231_PLL_INP_MAX 40000000 13 + #define RL6231_PLL_INP_MAX 50000000 14 14 #define RL6231_PLL_INP_MIN 256000 15 15 #define RL6231_PLL_N_MAX 0x1ff 16 16 #define RL6231_PLL_K_MAX 0x1f
+5 -5
sound/soc/codecs/rt1015.c
··· 444 444 return 0; 445 445 } 446 446 447 - static int rt5518_bypass_boost_get(struct snd_kcontrol *kcontrol, 447 + static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol, 448 448 struct snd_ctl_elem_value *ucontrol) 449 449 { 450 450 struct snd_soc_component *component = ··· 457 457 return 0; 458 458 } 459 459 460 - static int rt5518_bypass_boost_put(struct snd_kcontrol *kcontrol, 460 + static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol, 461 461 struct snd_ctl_elem_value *ucontrol) 462 462 { 463 463 struct snd_soc_component *component = ··· 497 497 rt1015_boost_mode_get, rt1015_boost_mode_put), 498 498 SOC_ENUM("Mono LR Select", rt1015_mono_lr_sel), 499 499 SOC_SINGLE_EXT("Bypass Boost", SND_SOC_NOPM, 0, 1, 0, 500 - rt5518_bypass_boost_get, rt5518_bypass_boost_put), 500 + rt1015_bypass_boost_get, rt1015_bypass_boost_put), 501 501 }; 502 502 503 503 static int rt1015_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, ··· 841 841 #define RT1015_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 842 842 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 843 843 844 - struct snd_soc_dai_ops rt1015_aif_dai_ops = { 844 + static struct snd_soc_dai_ops rt1015_aif_dai_ops = { 845 845 .hw_params = rt1015_hw_params, 846 846 .set_fmt = rt1015_set_dai_fmt, 847 847 }; 848 848 849 - struct snd_soc_dai_driver rt1015_dai[] = { 849 + static struct snd_soc_dai_driver rt1015_dai[] = { 850 850 { 851 851 .name = "rt1015-aif", 852 852 .id = 0,
+34 -4
sound/soc/codecs/rt1308-sdw.c
··· 507 507 kfree(stream); 508 508 } 509 509 510 + static int rt1308_sdw_set_tdm_slot(struct snd_soc_dai *dai, 511 + unsigned int tx_mask, 512 + unsigned int rx_mask, 513 + int slots, int slot_width) 514 + { 515 + struct snd_soc_component *component = dai->component; 516 + struct rt1308_sdw_priv *rt1308 = 517 + snd_soc_component_get_drvdata(component); 518 + 519 + if (tx_mask) 520 + return -EINVAL; 521 + 522 + if (slots > 2) 523 + return -EINVAL; 524 + 525 + rt1308->rx_mask = rx_mask; 526 + rt1308->slots = slots; 527 + /* slot_width is not used since it's irrelevant for SoundWire */ 528 + 529 + return 0; 530 + } 531 + 510 532 static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream, 511 533 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 512 534 { ··· 539 517 struct sdw_port_config port_config; 540 518 enum sdw_data_direction direction; 541 519 struct sdw_stream_data *stream; 542 - int retval, port, num_channels; 520 + int retval, port, num_channels, ch_mask; 543 521 544 522 dev_dbg(dai->dev, "%s %s", __func__, dai->name); 545 523 stream = snd_soc_dai_get_dma_data(dai, substream); ··· 559 537 return -EINVAL; 560 538 } 561 539 540 + if (rt1308->slots) { 541 + num_channels = rt1308->slots; 542 + ch_mask = rt1308->rx_mask; 543 + } else { 544 + num_channels = params_channels(params); 545 + ch_mask = (1 << num_channels) - 1; 546 + } 547 + 562 548 stream_config.frame_rate = params_rate(params); 563 - stream_config.ch_count = params_channels(params); 549 + stream_config.ch_count = num_channels; 564 550 stream_config.bps = snd_pcm_format_width(params_format(params)); 565 551 stream_config.direction = direction; 566 552 567 - num_channels = params_channels(params); 568 - port_config.ch_mask = (1 << (num_channels)) - 1; 553 + port_config.ch_mask = ch_mask; 569 554 port_config.num = port; 570 555 571 556 retval = sdw_stream_add_slave(rt1308->sdw_slave, &stream_config, ··· 626 597 .hw_free = rt1308_sdw_pcm_hw_free, 627 598 .set_sdw_stream = rt1308_set_sdw_stream, 628 599 .shutdown = rt1308_sdw_shutdown, 600 + .set_tdm_slot = rt1308_sdw_set_tdm_slot, 629 601 }; 630 602 631 603 #define RT1308_STEREO_RATES SNDRV_PCM_RATE_48000
+2
sound/soc/codecs/rt1308-sdw.h
··· 160 160 struct sdw_bus_params params; 161 161 bool hw_init; 162 162 bool first_hw_init; 163 + int rx_mask; 164 + int slots; 163 165 }; 164 166 165 167 struct sdw_stream_data {
+1 -1
sound/soc/codecs/rt5659.c
··· 1604 1604 { 1605 1605 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1606 1606 struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component); 1607 - int pd, idx = -EINVAL; 1607 + int pd, idx; 1608 1608 1609 1609 pd = rl6231_get_pre_div(rt5659->regmap, 1610 1610 RT5659_ADDA_CLK_1, RT5659_I2S_PD1_SFT);
+333
sound/soc/codecs/rt5682-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // rt5682-sdw.c -- RT5682 ALSA SoC audio component driver 4 + // 5 + // Copyright 2019 Realtek Semiconductor Corp. 6 + // Author: Oder Chiou <oder_chiou@realtek.com> 7 + // 8 + 9 + #include <linux/module.h> 10 + #include <linux/moduleparam.h> 11 + #include <linux/init.h> 12 + #include <linux/delay.h> 13 + #include <linux/pm.h> 14 + #include <linux/acpi.h> 15 + #include <linux/gpio.h> 16 + #include <linux/of_gpio.h> 17 + #include <linux/regulator/consumer.h> 18 + #include <linux/mutex.h> 19 + #include <linux/soundwire/sdw.h> 20 + #include <linux/soundwire/sdw_type.h> 21 + #include <sound/core.h> 22 + #include <sound/pcm.h> 23 + #include <sound/pcm_params.h> 24 + #include <sound/jack.h> 25 + #include <sound/soc.h> 26 + #include <sound/soc-dapm.h> 27 + #include <sound/initval.h> 28 + #include <sound/tlv.h> 29 + 30 + #include "rt5682.h" 31 + #include "rt5682-sdw.h" 32 + 33 + static bool rt5682_sdw_readable_register(struct device *dev, unsigned int reg) 34 + { 35 + switch (reg) { 36 + case 0x00e0: 37 + case 0x00f0: 38 + case 0x3000: 39 + case 0x3001: 40 + case 0x3004: 41 + case 0x3005: 42 + case 0x3008: 43 + return true; 44 + default: 45 + return false; 46 + } 47 + } 48 + 49 + const struct regmap_config rt5682_sdw_regmap = { 50 + .name = "sdw", 51 + .reg_bits = 32, 52 + .val_bits = 8, 53 + .max_register = RT5682_I2C_MODE, 54 + .readable_reg = rt5682_sdw_readable_register, 55 + .cache_type = REGCACHE_NONE, 56 + .use_single_read = true, 57 + .use_single_write = true, 58 + }; 59 + 60 + static int rt5682_update_status(struct sdw_slave *slave, 61 + enum sdw_slave_status status) 62 + { 63 + struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); 64 + 65 + /* Update the status */ 66 + rt5682->status = status; 67 + 68 + if (status == SDW_SLAVE_UNATTACHED) 69 + rt5682->hw_init = false; 70 + 71 + /* 72 + * Perform initialization only if slave status is present and 73 + * hw_init flag is false 74 + */ 75 + if (rt5682->hw_init || rt5682->status != SDW_SLAVE_ATTACHED) 76 + return 0; 77 + 78 + /* perform I/O transfers required for Slave initialization */ 79 + return rt5682_io_init(&slave->dev, slave); 80 + } 81 + 82 + static int rt5682_read_prop(struct sdw_slave *slave) 83 + { 84 + struct sdw_slave_prop *prop = &slave->prop; 85 + int nval, i, num_of_ports = 1; 86 + u32 bit; 87 + unsigned long addr; 88 + struct sdw_dpn_prop *dpn; 89 + 90 + prop->paging_support = false; 91 + 92 + /* first we need to allocate memory for set bits in port lists */ 93 + prop->source_ports = 0x4; /* BITMAP: 00000100 */ 94 + prop->sink_ports = 0x2; /* BITMAP: 00000010 */ 95 + 96 + nval = hweight32(prop->source_ports); 97 + num_of_ports += nval; 98 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 99 + sizeof(*prop->src_dpn_prop), 100 + GFP_KERNEL); 101 + if (!prop->src_dpn_prop) 102 + return -ENOMEM; 103 + 104 + i = 0; 105 + dpn = prop->src_dpn_prop; 106 + addr = prop->source_ports; 107 + for_each_set_bit(bit, &addr, 32) { 108 + dpn[i].num = bit; 109 + dpn[i].type = SDW_DPN_FULL; 110 + dpn[i].simple_ch_prep_sm = true; 111 + dpn[i].ch_prep_timeout = 10; 112 + i++; 113 + } 114 + 115 + /* do this again for sink now */ 116 + nval = hweight32(prop->sink_ports); 117 + num_of_ports += nval; 118 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 119 + sizeof(*prop->sink_dpn_prop), 120 + GFP_KERNEL); 121 + if (!prop->sink_dpn_prop) 122 + return -ENOMEM; 123 + 124 + i = 0; 125 + dpn = prop->sink_dpn_prop; 126 + addr = prop->sink_ports; 127 + for_each_set_bit(bit, &addr, 32) { 128 + dpn[i].num = bit; 129 + dpn[i].type = SDW_DPN_FULL; 130 + dpn[i].simple_ch_prep_sm = true; 131 + dpn[i].ch_prep_timeout = 10; 132 + i++; 133 + } 134 + 135 + /* Allocate port_ready based on num_of_ports */ 136 + slave->port_ready = devm_kcalloc(&slave->dev, num_of_ports, 137 + sizeof(*slave->port_ready), 138 + GFP_KERNEL); 139 + if (!slave->port_ready) 140 + return -ENOMEM; 141 + 142 + /* Initialize completion */ 143 + for (i = 0; i < num_of_ports; i++) 144 + init_completion(&slave->port_ready[i]); 145 + 146 + /* set the timeout values */ 147 + prop->clk_stop_timeout = 20; 148 + 149 + /* wake-up event */ 150 + prop->wake_capable = 1; 151 + 152 + return 0; 153 + } 154 + 155 + /* Bus clock frequency */ 156 + #define RT5682_CLK_FREQ_9600000HZ 9600000 157 + #define RT5682_CLK_FREQ_12000000HZ 12000000 158 + #define RT5682_CLK_FREQ_6000000HZ 6000000 159 + #define RT5682_CLK_FREQ_4800000HZ 4800000 160 + #define RT5682_CLK_FREQ_2400000HZ 2400000 161 + #define RT5682_CLK_FREQ_12288000HZ 12288000 162 + 163 + static int rt5682_clock_config(struct device *dev) 164 + { 165 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 166 + unsigned int clk_freq, value; 167 + 168 + clk_freq = (rt5682->params.curr_dr_freq >> 1); 169 + 170 + switch (clk_freq) { 171 + case RT5682_CLK_FREQ_12000000HZ: 172 + value = 0x0; 173 + break; 174 + case RT5682_CLK_FREQ_6000000HZ: 175 + value = 0x1; 176 + break; 177 + case RT5682_CLK_FREQ_9600000HZ: 178 + value = 0x2; 179 + break; 180 + case RT5682_CLK_FREQ_4800000HZ: 181 + value = 0x3; 182 + break; 183 + case RT5682_CLK_FREQ_2400000HZ: 184 + value = 0x4; 185 + break; 186 + case RT5682_CLK_FREQ_12288000HZ: 187 + value = 0x5; 188 + break; 189 + default: 190 + return -EINVAL; 191 + } 192 + 193 + regmap_write(rt5682->sdw_regmap, 0xe0, value); 194 + regmap_write(rt5682->sdw_regmap, 0xf0, value); 195 + 196 + dev_dbg(dev, "%s complete, clk_freq=%d\n", __func__, clk_freq); 197 + 198 + return 0; 199 + } 200 + 201 + static int rt5682_bus_config(struct sdw_slave *slave, 202 + struct sdw_bus_params *params) 203 + { 204 + struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); 205 + int ret; 206 + 207 + memcpy(&rt5682->params, params, sizeof(*params)); 208 + 209 + ret = rt5682_clock_config(&slave->dev); 210 + if (ret < 0) 211 + dev_err(&slave->dev, "Invalid clk config"); 212 + 213 + return ret; 214 + } 215 + 216 + static int rt5682_interrupt_callback(struct sdw_slave *slave, 217 + struct sdw_slave_intr_status *status) 218 + { 219 + struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); 220 + 221 + dev_dbg(&slave->dev, 222 + "%s control_port_stat=%x", __func__, status->control_port); 223 + 224 + if (status->control_port & 0x4) { 225 + mod_delayed_work(system_power_efficient_wq, 226 + &rt5682->jack_detect_work, msecs_to_jiffies(250)); 227 + } 228 + 229 + return 0; 230 + } 231 + 232 + static struct sdw_slave_ops rt5682_slave_ops = { 233 + .read_prop = rt5682_read_prop, 234 + .interrupt_callback = rt5682_interrupt_callback, 235 + .update_status = rt5682_update_status, 236 + .bus_config = rt5682_bus_config, 237 + }; 238 + 239 + static int rt5682_sdw_probe(struct sdw_slave *slave, 240 + const struct sdw_device_id *id) 241 + { 242 + struct regmap *regmap; 243 + 244 + /* Assign ops */ 245 + slave->ops = &rt5682_slave_ops; 246 + 247 + /* Regmap Initialization */ 248 + regmap = devm_regmap_init_sdw(slave, &rt5682_sdw_regmap); 249 + if (IS_ERR(regmap)) 250 + return -EINVAL; 251 + 252 + rt5682_sdw_init(&slave->dev, regmap, slave); 253 + 254 + return 0; 255 + } 256 + 257 + static int rt5682_sdw_remove(struct sdw_slave *slave) 258 + { 259 + struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); 260 + 261 + if (rt5682 && rt5682->hw_init) 262 + cancel_delayed_work(&rt5682->jack_detect_work); 263 + 264 + return 0; 265 + } 266 + 267 + static const struct sdw_device_id rt5682_id[] = { 268 + SDW_SLAVE_ENTRY(0x025d, 0x5682, 0), 269 + {}, 270 + }; 271 + MODULE_DEVICE_TABLE(sdw, rt5682_id); 272 + 273 + static int __maybe_unused rt5682_dev_suspend(struct device *dev) 274 + { 275 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 276 + 277 + if (!rt5682->hw_init) 278 + return 0; 279 + 280 + regcache_cache_only(rt5682->regmap, true); 281 + regcache_mark_dirty(rt5682->regmap); 282 + 283 + return 0; 284 + } 285 + 286 + static int __maybe_unused rt5682_dev_resume(struct device *dev) 287 + { 288 + struct sdw_slave *slave = dev_to_sdw_dev(dev); 289 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 290 + unsigned long time; 291 + 292 + if (!rt5682->hw_init) 293 + return 0; 294 + 295 + if (!slave->unattach_request) 296 + goto regmap_sync; 297 + 298 + time = wait_for_completion_timeout(&slave->initialization_complete, 299 + msecs_to_jiffies(RT5682_PROBE_TIMEOUT)); 300 + if (!time) { 301 + dev_err(&slave->dev, "Initialization not complete, timed out\n"); 302 + return -ETIMEDOUT; 303 + } 304 + 305 + regmap_sync: 306 + slave->unattach_request = 0; 307 + regcache_cache_only(rt5682->regmap, false); 308 + regcache_sync(rt5682->regmap); 309 + 310 + return 0; 311 + } 312 + 313 + static const struct dev_pm_ops rt5682_pm = { 314 + SET_SYSTEM_SLEEP_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume) 315 + SET_RUNTIME_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume, NULL) 316 + }; 317 + 318 + static struct sdw_driver rt5682_sdw_driver = { 319 + .driver = { 320 + .name = "rt5682", 321 + .owner = THIS_MODULE, 322 + .pm = &rt5682_pm, 323 + }, 324 + .probe = rt5682_sdw_probe, 325 + .remove = rt5682_sdw_remove, 326 + .ops = &rt5682_slave_ops, 327 + .id_table = rt5682_id, 328 + }; 329 + module_sdw_driver(rt5682_sdw_driver); 330 + 331 + MODULE_DESCRIPTION("ASoC RT5682 driver SDW"); 332 + MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); 333 + MODULE_LICENSE("GPL v2");
+20
sound/soc/codecs/rt5682-sdw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only 2 + * 3 + * rt5682-sdw.h -- RT5682 SDW ALSA SoC audio driver 4 + * 5 + * Copyright 2019 Realtek Semiconductor Corp. 6 + * Author: Oder Chiou <oder_chiou@realtek.com> 7 + */ 8 + 9 + #ifndef __RT5682_SDW_H__ 10 + #define __RT5682_SDW_H__ 11 + 12 + #define RT5682_SDW_ADDR_L 0x3000 13 + #define RT5682_SDW_ADDR_H 0x3001 14 + #define RT5682_SDW_DATA_L 0x3004 15 + #define RT5682_SDW_DATA_H 0x3005 16 + #define RT5682_SDW_CMD 0x3008 17 + 18 + #define RT5682_PROBE_TIMEOUT 2000 19 + 20 + #endif /* __RT5682_SDW_H__ */
+1156 -148
sound/soc/codecs/rt5682.c
··· 11 11 #include <linux/init.h> 12 12 #include <linux/delay.h> 13 13 #include <linux/pm.h> 14 + #include <linux/pm_runtime.h> 14 15 #include <linux/i2c.h> 15 16 #include <linux/platform_device.h> 16 17 #include <linux/spi/spi.h> 17 18 #include <linux/acpi.h> 18 19 #include <linux/gpio.h> 19 20 #include <linux/of_gpio.h> 20 - #include <linux/regulator/consumer.h> 21 21 #include <linux/mutex.h> 22 22 #include <sound/core.h> 23 23 #include <sound/pcm.h> ··· 31 31 32 32 #include "rl6231.h" 33 33 #include "rt5682.h" 34 - 35 - #define RT5682_NUM_SUPPLIES 3 34 + #include "rt5682-sdw.h" 36 35 37 36 static const char *rt5682_supply_names[RT5682_NUM_SUPPLIES] = { 38 37 "AVDD", ··· 44 45 .dmic1_clk_pin = RT5682_DMIC1_CLK_GPIO3, 45 46 .jd_src = RT5682_JD1, 46 47 .btndet_delay = 16, 47 - }; 48 - 49 - struct rt5682_priv { 50 - struct snd_soc_component *component; 51 - struct rt5682_platform_data pdata; 52 - struct regmap *regmap; 53 - struct snd_soc_jack *hs_jack; 54 - struct regulator_bulk_data supplies[RT5682_NUM_SUPPLIES]; 55 - struct delayed_work jack_detect_work; 56 - struct delayed_work jd_check_work; 57 - struct mutex calibrate_mutex; 58 - 59 - int sysclk; 60 - int sysclk_src; 61 - int lrck[RT5682_AIFS]; 62 - int bclk[RT5682_AIFS]; 63 - int master[RT5682_AIFS]; 64 - 65 - int pll_src; 66 - int pll_in; 67 - int pll_out; 68 - 69 - int jack_type; 48 + .dai_clk_names[RT5682_DAI_WCLK_IDX] = "rt5682-dai-wclk", 49 + .dai_clk_names[RT5682_DAI_BCLK_IDX] = "rt5682-dai-bclk", 70 50 }; 71 51 72 52 static const struct reg_sequence patch_list[] = { 73 53 {RT5682_HP_IMP_SENS_CTRL_19, 0x1000}, 74 54 {RT5682_DAC_ADC_DIG_VOL1, 0xa020}, 75 55 {RT5682_I2C_CTRL, 0x000f}, 56 + {RT5682_PLL2_INTERNAL, 0x8266}, 76 57 }; 77 58 78 59 static const struct reg_default rt5682_reg[] = { ··· 200 221 {0x0148, 0x0000}, 201 222 {0x0149, 0x0000}, 202 223 {0x0150, 0x79a1}, 203 - {0x0151, 0x0000}, 224 + {0x0156, 0xaaaa}, 204 225 {0x0160, 0x4ec0}, 205 226 {0x0161, 0x0080}, 206 227 {0x0162, 0x0200}, ··· 784 805 static const struct snd_kcontrol_new rt5682_if1_67_adc_swap_mux = 785 806 SOC_DAPM_ENUM("IF1 67 ADC Swap Mux", rt5682_if1_67_adc_enum); 786 807 787 - static void rt5682_reset(struct regmap *regmap) 808 + static const char * const rt5682_dac_select[] = { 809 + "IF1", "SOUND" 810 + }; 811 + 812 + static SOC_ENUM_SINGLE_DECL(rt5682_dacl_enum, 813 + RT5682_AD_DA_MIXER, RT5682_DAC1_L_SEL_SFT, rt5682_dac_select); 814 + 815 + static const struct snd_kcontrol_new rt5682_dac_l_mux = 816 + SOC_DAPM_ENUM("DAC L Mux", rt5682_dacl_enum); 817 + 818 + static SOC_ENUM_SINGLE_DECL(rt5682_dacr_enum, 819 + RT5682_AD_DA_MIXER, RT5682_DAC1_R_SEL_SFT, rt5682_dac_select); 820 + 821 + static const struct snd_kcontrol_new rt5682_dac_r_mux = 822 + SOC_DAPM_ENUM("DAC R Mux", rt5682_dacr_enum); 823 + 824 + static void rt5682_reset(struct rt5682_priv *rt5682) 788 825 { 789 - regmap_write(regmap, RT5682_RESET, 0); 790 - regmap_write(regmap, RT5682_I2C_MODE, 1); 826 + regmap_write(rt5682->regmap, RT5682_RESET, 0); 827 + if (!rt5682->is_sdw) 828 + regmap_write(rt5682->regmap, RT5682_I2C_MODE, 1); 791 829 } 792 830 /** 793 831 * rt5682_sel_asrc_clk_src - select ASRC clock source for a set of filters ··· 867 871 static void rt5682_enable_push_button_irq(struct snd_soc_component *component, 868 872 bool enable) 869 873 { 874 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 875 + 870 876 if (enable) { 871 877 snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1, 872 878 RT5682_SAR_BUTT_DET_MASK, RT5682_SAR_BUTT_DET_EN); ··· 878 880 snd_soc_component_update_bits(component, RT5682_4BTN_IL_CMD_2, 879 881 RT5682_4BTN_IL_MASK | RT5682_4BTN_IL_RST_MASK, 880 882 RT5682_4BTN_IL_EN | RT5682_4BTN_IL_NOR); 881 - snd_soc_component_update_bits(component, RT5682_IRQ_CTRL_3, 882 - RT5682_IL_IRQ_MASK, RT5682_IL_IRQ_EN); 883 + if (rt5682->is_sdw) 884 + snd_soc_component_update_bits(component, 885 + RT5682_IRQ_CTRL_3, 886 + RT5682_IL_IRQ_MASK | RT5682_IL_IRQ_TYPE_MASK, 887 + RT5682_IL_IRQ_EN | RT5682_IL_IRQ_PUL); 888 + else 889 + snd_soc_component_update_bits(component, 890 + RT5682_IRQ_CTRL_3, RT5682_IL_IRQ_MASK, 891 + RT5682_IL_IRQ_EN); 883 892 } else { 884 893 snd_soc_component_update_bits(component, RT5682_IRQ_CTRL_3, 885 894 RT5682_IL_IRQ_MASK, RT5682_IL_IRQ_DIS); ··· 914 909 int jack_insert) 915 910 { 916 911 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 912 + struct snd_soc_dapm_context *dapm = &component->dapm; 917 913 unsigned int val, count; 918 914 919 915 if (jack_insert) { ··· 923 917 RT5682_PWR_VREF2 | RT5682_PWR_MB, 924 918 RT5682_PWR_VREF2 | RT5682_PWR_MB); 925 919 snd_soc_component_update_bits(component, 926 - RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); 920 + RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0); 927 921 usleep_range(15000, 20000); 928 922 snd_soc_component_update_bits(component, 929 - RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); 923 + RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2); 930 924 snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, 931 925 RT5682_PWR_CBJ, RT5682_PWR_CBJ); 932 926 ··· 957 951 rt5682_enable_push_button_irq(component, false); 958 952 snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, 959 953 RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); 960 - snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, 961 - RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); 954 + if (snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) 955 + snd_soc_component_update_bits(component, 956 + RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); 957 + else 958 + snd_soc_component_update_bits(component, 959 + RT5682_PWR_ANLG_1, 960 + RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); 962 961 snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, 963 962 RT5682_PWR_CBJ, 0); 964 963 ··· 1010 999 1011 1000 rt5682->hs_jack = hs_jack; 1012 1001 1013 - if (!hs_jack) { 1014 - regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1015 - RT5682_JD1_EN_MASK, RT5682_JD1_DIS); 1016 - regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1017 - RT5682_POW_JDH | RT5682_POW_JDL, 0); 1018 - cancel_delayed_work_sync(&rt5682->jack_detect_work); 1019 - return 0; 1020 - } 1002 + if (!rt5682->is_sdw) { 1003 + if (!hs_jack) { 1004 + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1005 + RT5682_JD1_EN_MASK, RT5682_JD1_DIS); 1006 + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1007 + RT5682_POW_JDH | RT5682_POW_JDL, 0); 1008 + cancel_delayed_work_sync(&rt5682->jack_detect_work); 1009 + return 0; 1010 + } 1021 1011 1022 - switch (rt5682->pdata.jd_src) { 1023 - case RT5682_JD1: 1024 - snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2, 1025 - RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); 1026 - snd_soc_component_write(component, RT5682_CBJ_CTRL_1, 0xd042); 1027 - snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_3, 1028 - RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); 1029 - snd_soc_component_update_bits(component, RT5682_SAR_IL_CMD_1, 1030 - RT5682_SAR_POW_MASK, RT5682_SAR_POW_EN); 1031 - regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1, 1032 - RT5682_GP1_PIN_MASK, RT5682_GP1_PIN_IRQ); 1033 - regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1012 + switch (rt5682->pdata.jd_src) { 1013 + case RT5682_JD1: 1014 + snd_soc_component_update_bits(component, 1015 + RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, 1016 + RT5682_EXT_JD_SRC_MANUAL); 1017 + snd_soc_component_write(component, RT5682_CBJ_CTRL_1, 1018 + 0xd042); 1019 + snd_soc_component_update_bits(component, 1020 + RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, 1021 + RT5682_CBJ_IN_BUF_EN); 1022 + snd_soc_component_update_bits(component, 1023 + RT5682_SAR_IL_CMD_1, RT5682_SAR_POW_MASK, 1024 + RT5682_SAR_POW_EN); 1025 + regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1, 1026 + RT5682_GP1_PIN_MASK, RT5682_GP1_PIN_IRQ); 1027 + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1034 1028 RT5682_POW_IRQ | RT5682_POW_JDH | 1035 1029 RT5682_POW_ANA, RT5682_POW_IRQ | 1036 1030 RT5682_POW_JDH | RT5682_POW_ANA); 1037 - regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_2, 1038 - RT5682_PWR_JDH | RT5682_PWR_JDL, 1039 - RT5682_PWR_JDH | RT5682_PWR_JDL); 1040 - regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1041 - RT5682_JD1_EN_MASK | RT5682_JD1_POL_MASK, 1042 - RT5682_JD1_EN | RT5682_JD1_POL_NOR); 1043 - regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_4, 1044 - 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1045 - rt5682->pdata.btndet_delay)); 1046 - regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_5, 1047 - 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1048 - rt5682->pdata.btndet_delay)); 1049 - regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_6, 1050 - 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1051 - rt5682->pdata.btndet_delay)); 1052 - regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_7, 1053 - 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1054 - rt5682->pdata.btndet_delay)); 1055 - mod_delayed_work(system_power_efficient_wq, 1056 - &rt5682->jack_detect_work, msecs_to_jiffies(250)); 1057 - break; 1031 + regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_2, 1032 + RT5682_PWR_JDH | RT5682_PWR_JDL, 1033 + RT5682_PWR_JDH | RT5682_PWR_JDL); 1034 + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1035 + RT5682_JD1_EN_MASK | RT5682_JD1_POL_MASK, 1036 + RT5682_JD1_EN | RT5682_JD1_POL_NOR); 1037 + regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_4, 1038 + 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1039 + rt5682->pdata.btndet_delay)); 1040 + regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_5, 1041 + 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1042 + rt5682->pdata.btndet_delay)); 1043 + regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_6, 1044 + 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1045 + rt5682->pdata.btndet_delay)); 1046 + regmap_update_bits(rt5682->regmap, RT5682_4BTN_IL_CMD_7, 1047 + 0x7f7f, (rt5682->pdata.btndet_delay << 8 | 1048 + rt5682->pdata.btndet_delay)); 1049 + mod_delayed_work(system_power_efficient_wq, 1050 + &rt5682->jack_detect_work, 1051 + msecs_to_jiffies(250)); 1052 + break; 1058 1053 1059 - case RT5682_JD_NULL: 1060 - regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1061 - RT5682_JD1_EN_MASK, RT5682_JD1_DIS); 1062 - regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1063 - RT5682_POW_JDH | RT5682_POW_JDL, 0); 1064 - break; 1054 + case RT5682_JD_NULL: 1055 + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 1056 + RT5682_JD1_EN_MASK, RT5682_JD1_DIS); 1057 + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 1058 + RT5682_POW_JDH | RT5682_POW_JDL, 0); 1059 + break; 1065 1060 1066 - default: 1067 - dev_warn(component->dev, "Wrong JD source\n"); 1068 - break; 1061 + default: 1062 + dev_warn(component->dev, "Wrong JD source\n"); 1063 + break; 1064 + } 1069 1065 } 1070 1066 1071 1067 return 0; ··· 1152 1134 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1153 1135 SND_JACK_BTN_2 | SND_JACK_BTN_3); 1154 1136 1155 - if (rt5682->jack_type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1156 - SND_JACK_BTN_2 | SND_JACK_BTN_3)) 1157 - schedule_delayed_work(&rt5682->jd_check_work, 0); 1158 - else 1159 - cancel_delayed_work_sync(&rt5682->jd_check_work); 1137 + if (!rt5682->is_sdw) { 1138 + if (rt5682->jack_type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1139 + SND_JACK_BTN_2 | SND_JACK_BTN_3)) 1140 + schedule_delayed_work(&rt5682->jd_check_work, 0); 1141 + else 1142 + cancel_delayed_work_sync(&rt5682->jd_check_work); 1143 + } 1160 1144 1161 1145 mutex_unlock(&rt5682->calibrate_mutex); 1162 1146 } ··· 1166 1146 static const struct snd_kcontrol_new rt5682_snd_controls[] = { 1167 1147 /* DAC Digital Volume */ 1168 1148 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5682_DAC1_DIG_VOL, 1169 - RT5682_L_VOL_SFT + 1, RT5682_R_VOL_SFT + 1, 86, 0, dac_vol_tlv), 1149 + RT5682_L_VOL_SFT + 1, RT5682_R_VOL_SFT + 1, 87, 0, dac_vol_tlv), 1170 1150 1171 1151 /* IN Boost Volume */ 1172 1152 SOC_SINGLE_TLV("CBJ Boost Volume", RT5682_CBJ_BST_CTRL, ··· 1197 1177 } 1198 1178 1199 1179 for (i = 0; i < size - 1; i++) { 1200 - pr_info("div[%d]=%d\n", i, div[i]); 1180 + dev_dbg(rt5682->component->dev, "div[%d]=%d\n", i, div[i]); 1201 1181 if (target * div[i] == rt5682->sysclk) 1202 1182 return i; 1203 1183 if (target * div[i + 1] > rt5682->sysclk) { 1204 - pr_err("can't find div for sysclk %d\n", 1184 + dev_dbg(rt5682->component->dev, "can't find div for sysclk %d\n", 1205 1185 rt5682->sysclk); 1206 1186 return i; 1207 1187 } ··· 1231 1211 struct snd_soc_component *component = 1232 1212 snd_soc_dapm_to_component(w->dapm); 1233 1213 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 1234 - int idx = -EINVAL; 1214 + int idx = -EINVAL, dmic_clk_rate = 3072000; 1235 1215 static const int div[] = {2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128}; 1236 1216 1237 - idx = rt5682_div_sel(rt5682, 1500000, div, ARRAY_SIZE(div)); 1217 + if (rt5682->pdata.dmic_clk_rate) 1218 + dmic_clk_rate = rt5682->pdata.dmic_clk_rate; 1219 + 1220 + idx = rt5682_div_sel(rt5682, dmic_clk_rate, div, ARRAY_SIZE(div)); 1238 1221 1239 1222 snd_soc_component_update_bits(component, RT5682_DMIC_CTRL_1, 1240 1223 RT5682_DMIC_CLK_MASK, idx << RT5682_DMIC_CLK_SFT); ··· 1254 1231 int ref, val, reg, idx = -EINVAL; 1255 1232 static const int div_f[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; 1256 1233 static const int div_o[] = {1, 2, 4, 6, 8, 12, 16, 24, 32, 48}; 1234 + 1235 + if (rt5682->is_sdw) 1236 + return 0; 1257 1237 1258 1238 val = snd_soc_component_read32(component, RT5682_GPIO_CTRL_1) & 1259 1239 RT5682_GP4_PIN_MASK; ··· 1299 1273 val = snd_soc_component_read32(component, RT5682_GLB_CLK); 1300 1274 val &= RT5682_SCLK_SRC_MASK; 1301 1275 if (val == RT5682_SCLK_SRC_PLL1) 1276 + return 1; 1277 + else 1278 + return 0; 1279 + } 1280 + 1281 + static int is_sys_clk_from_pll2(struct snd_soc_dapm_widget *w, 1282 + struct snd_soc_dapm_widget *sink) 1283 + { 1284 + unsigned int val; 1285 + struct snd_soc_component *component = 1286 + snd_soc_dapm_to_component(w->dapm); 1287 + 1288 + val = snd_soc_component_read32(component, RT5682_GLB_CLK); 1289 + val &= RT5682_SCLK_SRC_MASK; 1290 + if (val == RT5682_SCLK_SRC_PLL2) 1302 1291 return 1; 1303 1292 else 1304 1293 return 0; ··· 1544 1503 static int set_dmic_power(struct snd_soc_dapm_widget *w, 1545 1504 struct snd_kcontrol *kcontrol, int event) 1546 1505 { 1506 + struct snd_soc_component *component = 1507 + snd_soc_dapm_to_component(w->dapm); 1508 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 1509 + unsigned int delay = 50; 1510 + 1511 + if (rt5682->pdata.dmic_delay) 1512 + delay = rt5682->pdata.dmic_delay; 1513 + 1547 1514 switch (event) { 1548 1515 case SND_SOC_DAPM_POST_PMU: 1549 1516 /*Add delay to avoid pop noise*/ 1550 - msleep(150); 1517 + msleep(delay); 1551 1518 break; 1552 1519 1553 1520 default: ··· 1565 1516 return 0; 1566 1517 } 1567 1518 1568 - static int rt5655_set_verf(struct snd_soc_dapm_widget *w, 1519 + static int rt5682_set_verf(struct snd_soc_dapm_widget *w, 1569 1520 struct snd_kcontrol *kcontrol, int event) 1570 1521 { 1571 1522 struct snd_soc_component *component = ··· 1641 1592 SND_SOC_DAPM_SUPPLY("PLL2B", RT5682_PWR_ANLG_3, RT5682_PWR_PLL2B_BIT, 1642 1593 0, NULL, 0), 1643 1594 SND_SOC_DAPM_SUPPLY("PLL2F", RT5682_PWR_ANLG_3, RT5682_PWR_PLL2F_BIT, 1644 - 0, NULL, 0), 1595 + 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), 1645 1596 SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, 1646 - rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1597 + rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1598 + SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, 1599 + NULL, 0), 1600 + SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0), 1647 1601 1648 1602 /* ASRC */ 1649 1603 SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1, ··· 1738 1686 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), 1739 1687 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), 1740 1688 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), 1689 + SND_SOC_DAPM_PGA("SOUND DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), 1690 + SND_SOC_DAPM_PGA("SOUND DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), 1741 1691 1742 1692 /* Digital Interface Select */ 1743 1693 SND_SOC_DAPM_MUX("IF1 01 ADC Swap Mux", SND_SOC_NOPM, 0, 0, ··· 1756 1702 SND_SOC_DAPM_MUX("ADCDAT Mux", SND_SOC_NOPM, 0, 0, 1757 1703 &rt5682_adcdat_pin_ctrl), 1758 1704 1705 + SND_SOC_DAPM_MUX("DAC L Mux", SND_SOC_NOPM, 0, 0, 1706 + &rt5682_dac_l_mux), 1707 + SND_SOC_DAPM_MUX("DAC R Mux", SND_SOC_NOPM, 0, 0, 1708 + &rt5682_dac_r_mux), 1709 + 1759 1710 /* Audio Interface */ 1760 1711 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, 1761 1712 RT5682_I2S1_SDP, RT5682_SEL_ADCDAT_SFT, 1), 1762 1713 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, 1763 1714 RT5682_I2S2_SDP, RT5682_I2S2_PIN_CFG_SFT, 1), 1764 1715 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1716 + SND_SOC_DAPM_AIF_IN("SDWRX", "SDW Playback", 0, SND_SOC_NOPM, 0, 0), 1717 + SND_SOC_DAPM_AIF_OUT("SDWTX", "SDW Capture", 0, SND_SOC_NOPM, 0, 0), 1765 1718 1766 1719 /* Output Side */ 1767 1720 /* DAC mixer before sound effect */ ··· 1837 1776 static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { 1838 1777 /*PLL*/ 1839 1778 {"ADC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1}, 1779 + {"ADC Stereo1 Filter", NULL, "PLL2B", is_sys_clk_from_pll2}, 1780 + {"ADC Stereo1 Filter", NULL, "PLL2F", is_sys_clk_from_pll2}, 1840 1781 {"DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1}, 1782 + {"DAC Stereo1 Filter", NULL, "PLL2B", is_sys_clk_from_pll2}, 1783 + {"DAC Stereo1 Filter", NULL, "PLL2F", is_sys_clk_from_pll2}, 1841 1784 1842 1785 /*ASRC*/ 1843 1786 {"ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc}, ··· 1925 1860 {"IF1_ADC Mux", "Slot 2", "IF1 23 ADC Swap Mux"}, 1926 1861 {"IF1_ADC Mux", "Slot 4", "IF1 45 ADC Swap Mux"}, 1927 1862 {"IF1_ADC Mux", "Slot 6", "IF1 67 ADC Swap Mux"}, 1928 - {"IF1_ADC Mux", NULL, "I2S1"}, 1929 1863 {"ADCDAT Mux", "ADCDAT1", "IF1_ADC Mux"}, 1864 + {"AIF1TX", NULL, "I2S1"}, 1930 1865 {"AIF1TX", NULL, "ADCDAT Mux"}, 1931 1866 {"IF2 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"}, 1932 1867 {"IF2 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"}, ··· 1935 1870 {"ADCDAT Mux", "ADCDAT2", "IF2 ADC Swap Mux"}, 1936 1871 {"AIF2TX", NULL, "ADCDAT Mux"}, 1937 1872 1873 + {"SDWTX", NULL, "PLL2B"}, 1874 + {"SDWTX", NULL, "PLL2F"}, 1875 + {"SDWTX", NULL, "ADCDAT Mux"}, 1876 + 1938 1877 {"IF1 DAC1 L", NULL, "AIF1RX"}, 1939 1878 {"IF1 DAC1 L", NULL, "I2S1"}, 1940 1879 {"IF1 DAC1 L", NULL, "DAC Stereo1 Filter"}, ··· 1946 1877 {"IF1 DAC1 R", NULL, "I2S1"}, 1947 1878 {"IF1 DAC1 R", NULL, "DAC Stereo1 Filter"}, 1948 1879 1880 + {"SOUND DAC L", NULL, "SDWRX"}, 1881 + {"SOUND DAC L", NULL, "DAC Stereo1 Filter"}, 1882 + {"SOUND DAC L", NULL, "PLL2B"}, 1883 + {"SOUND DAC L", NULL, "PLL2F"}, 1884 + {"SOUND DAC R", NULL, "SDWRX"}, 1885 + {"SOUND DAC R", NULL, "DAC Stereo1 Filter"}, 1886 + {"SOUND DAC R", NULL, "PLL2B"}, 1887 + {"SOUND DAC R", NULL, "PLL2F"}, 1888 + 1889 + {"DAC L Mux", "IF1", "IF1 DAC1 L"}, 1890 + {"DAC L Mux", "SOUND", "SOUND DAC L"}, 1891 + {"DAC R Mux", "IF1", "IF1 DAC1 R"}, 1892 + {"DAC R Mux", "SOUND", "SOUND DAC R"}, 1893 + 1949 1894 {"DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"}, 1950 - {"DAC1 MIXL", "DAC1 Switch", "IF1 DAC1 L"}, 1895 + {"DAC1 MIXL", "DAC1 Switch", "DAC L Mux"}, 1951 1896 {"DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"}, 1952 - {"DAC1 MIXR", "DAC1 Switch", "IF1 DAC1 R"}, 1897 + {"DAC1 MIXR", "DAC1 Switch", "DAC R Mux"}, 1953 1898 1954 1899 {"Stereo1 DAC MIXL", "DAC L1 Switch", "DAC1 MIXL"}, 1955 1900 {"Stereo1 DAC MIXL", "DAC R1 Switch", "DAC1 MIXR"}, ··· 2116 2033 RT5682_I2S1_DL_MASK, len_1); 2117 2034 if (rt5682->master[RT5682_AIF1]) { 2118 2035 snd_soc_component_update_bits(component, 2119 - RT5682_ADDA_CLK_1, RT5682_I2S_M_DIV_MASK, 2120 - pre_div << RT5682_I2S_M_DIV_SFT); 2036 + RT5682_ADDA_CLK_1, RT5682_I2S_M_DIV_MASK | 2037 + RT5682_I2S_CLK_SRC_MASK, 2038 + pre_div << RT5682_I2S_M_DIV_SFT | 2039 + (rt5682->sysclk_src) << RT5682_I2S_CLK_SRC_SFT); 2121 2040 } 2122 2041 if (params_channels(params) == 1) /* mono mode */ 2123 2042 snd_soc_component_update_bits(component, ··· 2292 2207 unsigned int freq_out) 2293 2208 { 2294 2209 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2295 - struct rl6231_pll_code pll_code; 2210 + struct rl6231_pll_code pll_code, pll2f_code, pll2b_code; 2211 + unsigned int pll2_fout1; 2296 2212 int ret; 2297 2213 2298 - if (source == rt5682->pll_src && freq_in == rt5682->pll_in && 2299 - freq_out == rt5682->pll_out) 2214 + if (source == rt5682->pll_src[pll_id] && 2215 + freq_in == rt5682->pll_in[pll_id] && 2216 + freq_out == rt5682->pll_out[pll_id]) 2300 2217 return 0; 2301 2218 2302 2219 if (!freq_in || !freq_out) { 2303 2220 dev_dbg(component->dev, "PLL disabled\n"); 2304 2221 2305 - rt5682->pll_in = 0; 2306 - rt5682->pll_out = 0; 2222 + rt5682->pll_in[pll_id] = 0; 2223 + rt5682->pll_out[pll_id] = 0; 2307 2224 snd_soc_component_update_bits(component, RT5682_GLB_CLK, 2308 2225 RT5682_SCLK_SRC_MASK, RT5682_SCLK_SRC_MCLK); 2309 2226 return 0; 2310 2227 } 2311 2228 2312 - switch (source) { 2313 - case RT5682_PLL1_S_MCLK: 2314 - snd_soc_component_update_bits(component, RT5682_GLB_CLK, 2315 - RT5682_PLL1_SRC_MASK, RT5682_PLL1_SRC_MCLK); 2316 - break; 2317 - case RT5682_PLL1_S_BCLK1: 2318 - snd_soc_component_update_bits(component, RT5682_GLB_CLK, 2319 - RT5682_PLL1_SRC_MASK, RT5682_PLL1_SRC_BCLK1); 2320 - break; 2321 - default: 2322 - dev_err(component->dev, "Unknown PLL Source %d\n", source); 2323 - return -EINVAL; 2229 + if (pll_id == RT5682_PLL2) { 2230 + switch (source) { 2231 + case RT5682_PLL2_S_MCLK: 2232 + snd_soc_component_update_bits(component, 2233 + RT5682_GLB_CLK, RT5682_PLL2_SRC_MASK, 2234 + RT5682_PLL2_SRC_MCLK); 2235 + break; 2236 + default: 2237 + dev_err(component->dev, "Unknown PLL2 Source %d\n", 2238 + source); 2239 + return -EINVAL; 2240 + } 2241 + 2242 + /** 2243 + * PLL2 concatenates 2 PLL units. 2244 + * We suggest the Fout of the front PLL is 3.84MHz. 2245 + */ 2246 + pll2_fout1 = 3840000; 2247 + ret = rl6231_pll_calc(freq_in, pll2_fout1, &pll2f_code); 2248 + if (ret < 0) { 2249 + dev_err(component->dev, "Unsupport input clock %d\n", 2250 + freq_in); 2251 + return ret; 2252 + } 2253 + dev_dbg(component->dev, "PLL2F: fin=%d fout=%d bypass=%d m=%d n=%d k=%d\n", 2254 + freq_in, pll2_fout1, 2255 + pll2f_code.m_bp, 2256 + (pll2f_code.m_bp ? 0 : pll2f_code.m_code), 2257 + pll2f_code.n_code, pll2f_code.k_code); 2258 + 2259 + ret = rl6231_pll_calc(pll2_fout1, freq_out, &pll2b_code); 2260 + if (ret < 0) { 2261 + dev_err(component->dev, "Unsupport input clock %d\n", 2262 + pll2_fout1); 2263 + return ret; 2264 + } 2265 + dev_dbg(component->dev, "PLL2B: fin=%d fout=%d bypass=%d m=%d n=%d k=%d\n", 2266 + pll2_fout1, freq_out, 2267 + pll2b_code.m_bp, 2268 + (pll2b_code.m_bp ? 0 : pll2b_code.m_code), 2269 + pll2b_code.n_code, pll2b_code.k_code); 2270 + 2271 + snd_soc_component_write(component, RT5682_PLL2_CTRL_1, 2272 + pll2f_code.k_code << RT5682_PLL2F_K_SFT | 2273 + pll2b_code.k_code << RT5682_PLL2B_K_SFT | 2274 + pll2b_code.m_code); 2275 + snd_soc_component_write(component, RT5682_PLL2_CTRL_2, 2276 + pll2f_code.m_code << RT5682_PLL2F_M_SFT | 2277 + pll2b_code.n_code); 2278 + snd_soc_component_write(component, RT5682_PLL2_CTRL_3, 2279 + pll2f_code.n_code << RT5682_PLL2F_N_SFT); 2280 + snd_soc_component_update_bits(component, RT5682_PLL2_CTRL_4, 2281 + RT5682_PLL2B_M_BP_MASK | RT5682_PLL2F_M_BP_MASK | 0xf, 2282 + (pll2b_code.m_bp ? 1 : 0) << RT5682_PLL2B_M_BP_SFT | 2283 + (pll2f_code.m_bp ? 1 : 0) << RT5682_PLL2F_M_BP_SFT | 2284 + 0xf); 2285 + } else { 2286 + switch (source) { 2287 + case RT5682_PLL1_S_MCLK: 2288 + snd_soc_component_update_bits(component, 2289 + RT5682_GLB_CLK, RT5682_PLL1_SRC_MASK, 2290 + RT5682_PLL1_SRC_MCLK); 2291 + break; 2292 + case RT5682_PLL1_S_BCLK1: 2293 + snd_soc_component_update_bits(component, 2294 + RT5682_GLB_CLK, RT5682_PLL1_SRC_MASK, 2295 + RT5682_PLL1_SRC_BCLK1); 2296 + break; 2297 + default: 2298 + dev_err(component->dev, "Unknown PLL1 Source %d\n", 2299 + source); 2300 + return -EINVAL; 2301 + } 2302 + 2303 + ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); 2304 + if (ret < 0) { 2305 + dev_err(component->dev, "Unsupport input clock %d\n", 2306 + freq_in); 2307 + return ret; 2308 + } 2309 + 2310 + dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", 2311 + pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), 2312 + pll_code.n_code, pll_code.k_code); 2313 + 2314 + snd_soc_component_write(component, RT5682_PLL_CTRL_1, 2315 + pll_code.n_code << RT5682_PLL_N_SFT | pll_code.k_code); 2316 + snd_soc_component_write(component, RT5682_PLL_CTRL_2, 2317 + (pll_code.m_bp ? 0 : pll_code.m_code) << RT5682_PLL_M_SFT | 2318 + pll_code.m_bp << RT5682_PLL_M_BP_SFT | RT5682_PLL_RST); 2324 2319 } 2325 2320 2326 - ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); 2327 - if (ret < 0) { 2328 - dev_err(component->dev, "Unsupport input clock %d\n", freq_in); 2329 - return ret; 2330 - } 2331 - 2332 - dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", 2333 - pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), 2334 - pll_code.n_code, pll_code.k_code); 2335 - 2336 - snd_soc_component_write(component, RT5682_PLL_CTRL_1, 2337 - pll_code.n_code << RT5682_PLL_N_SFT | pll_code.k_code); 2338 - snd_soc_component_write(component, RT5682_PLL_CTRL_2, 2339 - (pll_code.m_bp ? 0 : pll_code.m_code) << RT5682_PLL_M_SFT | 2340 - pll_code.m_bp << RT5682_PLL_M_BP_SFT | RT5682_PLL_RST); 2341 - 2342 - rt5682->pll_in = freq_in; 2343 - rt5682->pll_out = freq_out; 2344 - rt5682->pll_src = source; 2321 + rt5682->pll_in[pll_id] = freq_in; 2322 + rt5682->pll_out[pll_id] = freq_out; 2323 + rt5682->pll_src[pll_id] = source; 2345 2324 2346 2325 return 0; 2347 2326 } 2348 2327 2349 - static int rt5682_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) 2328 + static int rt5682_set_bclk1_ratio(struct snd_soc_dai *dai, unsigned int ratio) 2329 + { 2330 + struct snd_soc_component *component = dai->component; 2331 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2332 + 2333 + rt5682->bclk[dai->id] = ratio; 2334 + 2335 + switch (ratio) { 2336 + case 256: 2337 + snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL, 2338 + RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_256); 2339 + break; 2340 + case 128: 2341 + snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL, 2342 + RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_128); 2343 + break; 2344 + case 64: 2345 + snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL, 2346 + RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_64); 2347 + break; 2348 + case 32: 2349 + snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL, 2350 + RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_32); 2351 + break; 2352 + default: 2353 + dev_err(dai->dev, "Invalid bclk1 ratio %d\n", ratio); 2354 + return -EINVAL; 2355 + } 2356 + 2357 + return 0; 2358 + } 2359 + 2360 + static int rt5682_set_bclk2_ratio(struct snd_soc_dai *dai, unsigned int ratio) 2350 2361 { 2351 2362 struct snd_soc_component *component = dai->component; 2352 2363 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); ··· 2461 2280 RT5682_I2S2_BCLK_MS2_32); 2462 2281 break; 2463 2282 default: 2464 - dev_err(dai->dev, "Invalid bclk ratio %d\n", ratio); 2283 + dev_err(dai->dev, "Invalid bclk2 ratio %d\n", ratio); 2465 2284 return -EINVAL; 2466 2285 } 2467 2286 ··· 2500 2319 return 0; 2501 2320 } 2502 2321 2322 + #ifdef CONFIG_COMMON_CLK 2323 + #define CLK_PLL2_FIN 48000000 2324 + #define CLK_PLL2_FOUT 24576000 2325 + #define CLK_48 48000 2326 + 2327 + static bool rt5682_clk_check(struct rt5682_priv *rt5682) 2328 + { 2329 + if (!rt5682->master[RT5682_AIF1]) { 2330 + dev_err(rt5682->component->dev, "sysclk/dai not set correctly\n"); 2331 + return false; 2332 + } 2333 + return true; 2334 + } 2335 + 2336 + static int rt5682_wclk_prepare(struct clk_hw *hw) 2337 + { 2338 + struct rt5682_priv *rt5682 = 2339 + container_of(hw, struct rt5682_priv, 2340 + dai_clks_hw[RT5682_DAI_WCLK_IDX]); 2341 + struct snd_soc_component *component = rt5682->component; 2342 + struct snd_soc_dapm_context *dapm = 2343 + snd_soc_component_get_dapm(component); 2344 + 2345 + if (!rt5682_clk_check(rt5682)) 2346 + return -EINVAL; 2347 + 2348 + snd_soc_dapm_mutex_lock(dapm); 2349 + 2350 + snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); 2351 + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, 2352 + RT5682_PWR_MB, RT5682_PWR_MB); 2353 + snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1"); 2354 + snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F"); 2355 + snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B"); 2356 + snd_soc_dapm_sync_unlocked(dapm); 2357 + 2358 + snd_soc_dapm_mutex_unlock(dapm); 2359 + 2360 + return 0; 2361 + } 2362 + 2363 + static void rt5682_wclk_unprepare(struct clk_hw *hw) 2364 + { 2365 + struct rt5682_priv *rt5682 = 2366 + container_of(hw, struct rt5682_priv, 2367 + dai_clks_hw[RT5682_DAI_WCLK_IDX]); 2368 + struct snd_soc_component *component = rt5682->component; 2369 + struct snd_soc_dapm_context *dapm = 2370 + snd_soc_component_get_dapm(component); 2371 + 2372 + if (!rt5682_clk_check(rt5682)) 2373 + return; 2374 + 2375 + snd_soc_dapm_mutex_lock(dapm); 2376 + 2377 + snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); 2378 + if (!rt5682->jack_type) 2379 + snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, 2380 + RT5682_PWR_MB, 0); 2381 + snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1"); 2382 + snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F"); 2383 + snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B"); 2384 + snd_soc_dapm_sync_unlocked(dapm); 2385 + 2386 + snd_soc_dapm_mutex_unlock(dapm); 2387 + } 2388 + 2389 + static unsigned long rt5682_wclk_recalc_rate(struct clk_hw *hw, 2390 + unsigned long parent_rate) 2391 + { 2392 + struct rt5682_priv *rt5682 = 2393 + container_of(hw, struct rt5682_priv, 2394 + dai_clks_hw[RT5682_DAI_WCLK_IDX]); 2395 + 2396 + if (!rt5682_clk_check(rt5682)) 2397 + return 0; 2398 + /* 2399 + * Only accept to set wclk rate to 48kHz temporarily. 2400 + */ 2401 + return CLK_48; 2402 + } 2403 + 2404 + static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate, 2405 + unsigned long *parent_rate) 2406 + { 2407 + struct rt5682_priv *rt5682 = 2408 + container_of(hw, struct rt5682_priv, 2409 + dai_clks_hw[RT5682_DAI_WCLK_IDX]); 2410 + 2411 + if (!rt5682_clk_check(rt5682)) 2412 + return -EINVAL; 2413 + /* 2414 + * Only accept to set wclk rate to 48kHz temporarily. 2415 + */ 2416 + return CLK_48; 2417 + } 2418 + 2419 + static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate, 2420 + unsigned long parent_rate) 2421 + { 2422 + struct rt5682_priv *rt5682 = 2423 + container_of(hw, struct rt5682_priv, 2424 + dai_clks_hw[RT5682_DAI_WCLK_IDX]); 2425 + struct snd_soc_component *component = rt5682->component; 2426 + struct clk *parent_clk; 2427 + const char * const clk_name = __clk_get_name(hw->clk); 2428 + int pre_div; 2429 + 2430 + if (!rt5682_clk_check(rt5682)) 2431 + return -EINVAL; 2432 + 2433 + /* 2434 + * Whether the wclk's parent clk (mclk) exists or not, please ensure 2435 + * it is fixed or set to 48MHz before setting wclk rate. It's a 2436 + * temporary limitation. Only accept 48MHz clk as the clk provider. 2437 + * 2438 + * It will set the codec anyway by assuming mclk is 48MHz. 2439 + */ 2440 + parent_clk = clk_get_parent(hw->clk); 2441 + if (!parent_clk) 2442 + dev_warn(component->dev, 2443 + "Parent mclk of wclk not acquired in driver. Please ensure mclk was provided as %d Hz.\n", 2444 + CLK_PLL2_FIN); 2445 + 2446 + if (parent_rate != CLK_PLL2_FIN) 2447 + dev_warn(component->dev, "clk %s only support %d Hz input\n", 2448 + clk_name, CLK_PLL2_FIN); 2449 + 2450 + /* 2451 + * It's a temporary limitation. Only accept to set wclk rate to 48kHz. 2452 + * It will force wclk to 48kHz even it's not. 2453 + */ 2454 + if (rate != CLK_48) { 2455 + dev_warn(component->dev, "clk %s only support %d Hz output\n", 2456 + clk_name, CLK_48); 2457 + rate = CLK_48; 2458 + } 2459 + 2460 + /* 2461 + * To achieve the rate conversion from 48MHz to 48kHz, PLL2 is needed. 2462 + */ 2463 + rt5682_set_component_pll(component, RT5682_PLL2, RT5682_PLL2_S_MCLK, 2464 + CLK_PLL2_FIN, CLK_PLL2_FOUT); 2465 + 2466 + rt5682_set_component_sysclk(component, RT5682_SCLK_S_PLL2, 0, 2467 + CLK_PLL2_FOUT, SND_SOC_CLOCK_IN); 2468 + 2469 + pre_div = rl6231_get_clk_info(rt5682->sysclk, rate); 2470 + 2471 + snd_soc_component_update_bits(component, RT5682_ADDA_CLK_1, 2472 + RT5682_I2S_M_DIV_MASK | RT5682_I2S_CLK_SRC_MASK, 2473 + pre_div << RT5682_I2S_M_DIV_SFT | 2474 + (rt5682->sysclk_src) << RT5682_I2S_CLK_SRC_SFT); 2475 + 2476 + return 0; 2477 + } 2478 + 2479 + static unsigned long rt5682_bclk_recalc_rate(struct clk_hw *hw, 2480 + unsigned long parent_rate) 2481 + { 2482 + struct rt5682_priv *rt5682 = 2483 + container_of(hw, struct rt5682_priv, 2484 + dai_clks_hw[RT5682_DAI_BCLK_IDX]); 2485 + struct snd_soc_component *component = rt5682->component; 2486 + unsigned int bclks_per_wclk; 2487 + 2488 + snd_soc_component_read(component, RT5682_TDM_TCON_CTRL, 2489 + &bclks_per_wclk); 2490 + 2491 + switch (bclks_per_wclk & RT5682_TDM_BCLK_MS1_MASK) { 2492 + case RT5682_TDM_BCLK_MS1_256: 2493 + return parent_rate * 256; 2494 + case RT5682_TDM_BCLK_MS1_128: 2495 + return parent_rate * 128; 2496 + case RT5682_TDM_BCLK_MS1_64: 2497 + return parent_rate * 64; 2498 + case RT5682_TDM_BCLK_MS1_32: 2499 + return parent_rate * 32; 2500 + default: 2501 + return 0; 2502 + } 2503 + } 2504 + 2505 + static unsigned long rt5682_bclk_get_factor(unsigned long rate, 2506 + unsigned long parent_rate) 2507 + { 2508 + unsigned long factor; 2509 + 2510 + factor = rate / parent_rate; 2511 + if (factor < 64) 2512 + return 32; 2513 + else if (factor < 128) 2514 + return 64; 2515 + else if (factor < 256) 2516 + return 128; 2517 + else 2518 + return 256; 2519 + } 2520 + 2521 + static long rt5682_bclk_round_rate(struct clk_hw *hw, unsigned long rate, 2522 + unsigned long *parent_rate) 2523 + { 2524 + struct rt5682_priv *rt5682 = 2525 + container_of(hw, struct rt5682_priv, 2526 + dai_clks_hw[RT5682_DAI_BCLK_IDX]); 2527 + unsigned long factor; 2528 + 2529 + if (!*parent_rate || !rt5682_clk_check(rt5682)) 2530 + return -EINVAL; 2531 + 2532 + /* 2533 + * BCLK rates are set as a multiplier of WCLK in HW. 2534 + * We don't allow changing the parent WCLK. We just do 2535 + * some rounding down based on the parent WCLK rate 2536 + * and find the appropriate multiplier of BCLK to 2537 + * get the rounded down BCLK value. 2538 + */ 2539 + factor = rt5682_bclk_get_factor(rate, *parent_rate); 2540 + 2541 + return *parent_rate * factor; 2542 + } 2543 + 2544 + static int rt5682_bclk_set_rate(struct clk_hw *hw, unsigned long rate, 2545 + unsigned long parent_rate) 2546 + { 2547 + struct rt5682_priv *rt5682 = 2548 + container_of(hw, struct rt5682_priv, 2549 + dai_clks_hw[RT5682_DAI_BCLK_IDX]); 2550 + struct snd_soc_component *component = rt5682->component; 2551 + struct snd_soc_dai *dai = NULL; 2552 + unsigned long factor; 2553 + 2554 + if (!rt5682_clk_check(rt5682)) 2555 + return -EINVAL; 2556 + 2557 + factor = rt5682_bclk_get_factor(rate, parent_rate); 2558 + 2559 + for_each_component_dais(component, dai) 2560 + if (dai->id == RT5682_AIF1) 2561 + break; 2562 + if (!dai) { 2563 + dev_err(component->dev, "dai %d not found in component\n", 2564 + RT5682_AIF1); 2565 + return -ENODEV; 2566 + } 2567 + 2568 + return rt5682_set_bclk1_ratio(dai, factor); 2569 + } 2570 + 2571 + static const struct clk_ops rt5682_dai_clk_ops[RT5682_DAI_NUM_CLKS] = { 2572 + [RT5682_DAI_WCLK_IDX] = { 2573 + .prepare = rt5682_wclk_prepare, 2574 + .unprepare = rt5682_wclk_unprepare, 2575 + .recalc_rate = rt5682_wclk_recalc_rate, 2576 + .round_rate = rt5682_wclk_round_rate, 2577 + .set_rate = rt5682_wclk_set_rate, 2578 + }, 2579 + [RT5682_DAI_BCLK_IDX] = { 2580 + .recalc_rate = rt5682_bclk_recalc_rate, 2581 + .round_rate = rt5682_bclk_round_rate, 2582 + .set_rate = rt5682_bclk_set_rate, 2583 + }, 2584 + }; 2585 + 2586 + static int rt5682_register_dai_clks(struct snd_soc_component *component) 2587 + { 2588 + struct device *dev = component->dev; 2589 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2590 + struct rt5682_platform_data *pdata = &rt5682->pdata; 2591 + struct clk_init_data init; 2592 + struct clk *dai_clk; 2593 + struct clk_lookup *dai_clk_lookup; 2594 + struct clk_hw *dai_clk_hw; 2595 + const char *parent_name; 2596 + int i, ret; 2597 + 2598 + for (i = 0; i < RT5682_DAI_NUM_CLKS; ++i) { 2599 + dai_clk_hw = &rt5682->dai_clks_hw[i]; 2600 + 2601 + switch (i) { 2602 + case RT5682_DAI_WCLK_IDX: 2603 + /* Make MCLK the parent of WCLK */ 2604 + if (rt5682->mclk) { 2605 + parent_name = __clk_get_name(rt5682->mclk); 2606 + init.parent_names = &parent_name; 2607 + init.num_parents = 1; 2608 + } else { 2609 + init.parent_names = NULL; 2610 + init.num_parents = 0; 2611 + } 2612 + break; 2613 + case RT5682_DAI_BCLK_IDX: 2614 + /* Make WCLK the parent of BCLK */ 2615 + parent_name = __clk_get_name( 2616 + rt5682->dai_clks[RT5682_DAI_WCLK_IDX]); 2617 + init.parent_names = &parent_name; 2618 + init.num_parents = 1; 2619 + break; 2620 + default: 2621 + dev_err(dev, "Invalid clock index\n"); 2622 + ret = -EINVAL; 2623 + goto err; 2624 + } 2625 + 2626 + init.name = pdata->dai_clk_names[i]; 2627 + init.ops = &rt5682_dai_clk_ops[i]; 2628 + init.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE; 2629 + dai_clk_hw->init = &init; 2630 + 2631 + dai_clk = devm_clk_register(dev, dai_clk_hw); 2632 + if (IS_ERR(dai_clk)) { 2633 + dev_warn(dev, "Failed to register %s: %ld\n", 2634 + init.name, PTR_ERR(dai_clk)); 2635 + ret = PTR_ERR(dai_clk); 2636 + goto err; 2637 + } 2638 + rt5682->dai_clks[i] = dai_clk; 2639 + 2640 + if (dev->of_node) { 2641 + devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, 2642 + dai_clk_hw); 2643 + } else { 2644 + dai_clk_lookup = clkdev_create(dai_clk, init.name, 2645 + "%s", dev_name(dev)); 2646 + if (!dai_clk_lookup) { 2647 + ret = -ENOMEM; 2648 + goto err; 2649 + } else { 2650 + rt5682->dai_clks_lookup[i] = dai_clk_lookup; 2651 + } 2652 + } 2653 + } 2654 + 2655 + return 0; 2656 + 2657 + err: 2658 + do { 2659 + if (rt5682->dai_clks_lookup[i]) 2660 + clkdev_drop(rt5682->dai_clks_lookup[i]); 2661 + } while (i-- > 0); 2662 + 2663 + return ret; 2664 + } 2665 + #endif /* CONFIG_COMMON_CLK */ 2666 + 2503 2667 static int rt5682_probe(struct snd_soc_component *component) 2504 2668 { 2505 2669 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2670 + struct sdw_slave *slave; 2671 + unsigned long time; 2506 2672 2673 + #ifdef CONFIG_COMMON_CLK 2674 + int ret; 2675 + #endif 2507 2676 rt5682->component = component; 2677 + 2678 + if (rt5682->is_sdw) { 2679 + slave = rt5682->slave; 2680 + time = wait_for_completion_timeout( 2681 + &slave->initialization_complete, 2682 + msecs_to_jiffies(RT5682_PROBE_TIMEOUT)); 2683 + if (!time) { 2684 + dev_err(&slave->dev, "Initialization not complete, timed out\n"); 2685 + return -ETIMEDOUT; 2686 + } 2687 + } else { 2688 + #ifdef CONFIG_COMMON_CLK 2689 + /* Check if MCLK provided */ 2690 + rt5682->mclk = devm_clk_get(component->dev, "mclk"); 2691 + if (IS_ERR(rt5682->mclk)) { 2692 + if (PTR_ERR(rt5682->mclk) != -ENOENT) { 2693 + ret = PTR_ERR(rt5682->mclk); 2694 + return ret; 2695 + } 2696 + rt5682->mclk = NULL; 2697 + } else { 2698 + /* Register CCF DAI clock control */ 2699 + ret = rt5682_register_dai_clks(component); 2700 + if (ret) 2701 + return ret; 2702 + } 2703 + /* Initial setup for CCF */ 2704 + rt5682->lrck[RT5682_AIF1] = CLK_48; 2705 + #endif 2706 + } 2508 2707 2509 2708 return 0; 2510 2709 } ··· 2893 2332 { 2894 2333 struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2895 2334 2896 - rt5682_reset(rt5682->regmap); 2335 + #ifdef CONFIG_COMMON_CLK 2336 + int i; 2337 + 2338 + for (i = RT5682_DAI_NUM_CLKS - 1; i >= 0; --i) { 2339 + if (rt5682->dai_clks_lookup[i]) 2340 + clkdev_drop(rt5682->dai_clks_lookup[i]); 2341 + } 2342 + #endif 2343 + 2344 + rt5682_reset(rt5682); 2897 2345 } 2898 2346 2899 2347 #ifdef CONFIG_PM ··· 2939 2369 .hw_params = rt5682_hw_params, 2940 2370 .set_fmt = rt5682_set_dai_fmt, 2941 2371 .set_tdm_slot = rt5682_set_tdm_slot, 2372 + .set_bclk_ratio = rt5682_set_bclk1_ratio, 2942 2373 }; 2943 2374 2944 2375 static const struct snd_soc_dai_ops rt5682_aif2_dai_ops = { 2945 2376 .hw_params = rt5682_hw_params, 2946 2377 .set_fmt = rt5682_set_dai_fmt, 2947 - .set_bclk_ratio = rt5682_set_bclk_ratio, 2378 + .set_bclk_ratio = rt5682_set_bclk2_ratio, 2948 2379 }; 2380 + 2381 + #if IS_ENABLED(CONFIG_SND_SOC_RT5682_SDW) 2382 + struct sdw_stream_data { 2383 + struct sdw_stream_runtime *sdw_stream; 2384 + }; 2385 + 2386 + static int rt5682_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, 2387 + int direction) 2388 + { 2389 + struct sdw_stream_data *stream; 2390 + 2391 + stream = kzalloc(sizeof(*stream), GFP_KERNEL); 2392 + if (!stream) 2393 + return -ENOMEM; 2394 + 2395 + stream->sdw_stream = (struct sdw_stream_runtime *)sdw_stream; 2396 + 2397 + /* Use tx_mask or rx_mask to configure stream tag and set dma_data */ 2398 + if (direction == SNDRV_PCM_STREAM_PLAYBACK) 2399 + dai->playback_dma_data = stream; 2400 + else 2401 + dai->capture_dma_data = stream; 2402 + 2403 + return 0; 2404 + } 2405 + 2406 + static void rt5682_sdw_shutdown(struct snd_pcm_substream *substream, 2407 + struct snd_soc_dai *dai) 2408 + { 2409 + struct sdw_stream_data *stream; 2410 + 2411 + stream = snd_soc_dai_get_dma_data(dai, substream); 2412 + snd_soc_dai_set_dma_data(dai, substream, NULL); 2413 + kfree(stream); 2414 + } 2415 + 2416 + static int rt5682_sdw_hw_params(struct snd_pcm_substream *substream, 2417 + struct snd_pcm_hw_params *params, 2418 + struct snd_soc_dai *dai) 2419 + { 2420 + struct snd_soc_component *component = dai->component; 2421 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2422 + struct sdw_stream_config stream_config; 2423 + struct sdw_port_config port_config; 2424 + enum sdw_data_direction direction; 2425 + struct sdw_stream_data *stream; 2426 + int retval, port, num_channels; 2427 + unsigned int val_p = 0, val_c = 0, osr_p = 0, osr_c = 0; 2428 + 2429 + dev_dbg(dai->dev, "%s %s", __func__, dai->name); 2430 + stream = snd_soc_dai_get_dma_data(dai, substream); 2431 + 2432 + if (!stream) 2433 + return -ENOMEM; 2434 + 2435 + if (!rt5682->slave) 2436 + return -EINVAL; 2437 + 2438 + /* SoundWire specific configuration */ 2439 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 2440 + direction = SDW_DATA_DIR_RX; 2441 + port = 1; 2442 + } else { 2443 + direction = SDW_DATA_DIR_TX; 2444 + port = 2; 2445 + } 2446 + 2447 + stream_config.frame_rate = params_rate(params); 2448 + stream_config.ch_count = params_channels(params); 2449 + stream_config.bps = snd_pcm_format_width(params_format(params)); 2450 + stream_config.direction = direction; 2451 + 2452 + num_channels = params_channels(params); 2453 + port_config.ch_mask = (1 << (num_channels)) - 1; 2454 + port_config.num = port; 2455 + 2456 + retval = sdw_stream_add_slave(rt5682->slave, &stream_config, 2457 + &port_config, 1, stream->sdw_stream); 2458 + if (retval) { 2459 + dev_err(dai->dev, "Unable to configure port\n"); 2460 + return retval; 2461 + } 2462 + 2463 + switch (params_rate(params)) { 2464 + case 48000: 2465 + val_p = RT5682_SDW_REF_1_48K; 2466 + val_c = RT5682_SDW_REF_2_48K; 2467 + break; 2468 + case 96000: 2469 + val_p = RT5682_SDW_REF_1_96K; 2470 + val_c = RT5682_SDW_REF_2_96K; 2471 + break; 2472 + case 192000: 2473 + val_p = RT5682_SDW_REF_1_192K; 2474 + val_c = RT5682_SDW_REF_2_192K; 2475 + break; 2476 + case 32000: 2477 + val_p = RT5682_SDW_REF_1_32K; 2478 + val_c = RT5682_SDW_REF_2_32K; 2479 + break; 2480 + case 24000: 2481 + val_p = RT5682_SDW_REF_1_24K; 2482 + val_c = RT5682_SDW_REF_2_24K; 2483 + break; 2484 + case 16000: 2485 + val_p = RT5682_SDW_REF_1_16K; 2486 + val_c = RT5682_SDW_REF_2_16K; 2487 + break; 2488 + case 12000: 2489 + val_p = RT5682_SDW_REF_1_12K; 2490 + val_c = RT5682_SDW_REF_2_12K; 2491 + break; 2492 + case 8000: 2493 + val_p = RT5682_SDW_REF_1_8K; 2494 + val_c = RT5682_SDW_REF_2_8K; 2495 + break; 2496 + case 44100: 2497 + val_p = RT5682_SDW_REF_1_44K; 2498 + val_c = RT5682_SDW_REF_2_44K; 2499 + break; 2500 + case 88200: 2501 + val_p = RT5682_SDW_REF_1_88K; 2502 + val_c = RT5682_SDW_REF_2_88K; 2503 + break; 2504 + case 176400: 2505 + val_p = RT5682_SDW_REF_1_176K; 2506 + val_c = RT5682_SDW_REF_2_176K; 2507 + break; 2508 + case 22050: 2509 + val_p = RT5682_SDW_REF_1_22K; 2510 + val_c = RT5682_SDW_REF_2_22K; 2511 + break; 2512 + case 11025: 2513 + val_p = RT5682_SDW_REF_1_11K; 2514 + val_c = RT5682_SDW_REF_2_11K; 2515 + break; 2516 + default: 2517 + return -EINVAL; 2518 + } 2519 + 2520 + if (params_rate(params) <= 48000) { 2521 + osr_p = RT5682_DAC_OSR_D_8; 2522 + osr_c = RT5682_ADC_OSR_D_8; 2523 + } else if (params_rate(params) <= 96000) { 2524 + osr_p = RT5682_DAC_OSR_D_4; 2525 + osr_c = RT5682_ADC_OSR_D_4; 2526 + } else { 2527 + osr_p = RT5682_DAC_OSR_D_2; 2528 + osr_c = RT5682_ADC_OSR_D_2; 2529 + } 2530 + 2531 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 2532 + regmap_update_bits(rt5682->regmap, RT5682_SDW_REF_CLK, 2533 + RT5682_SDW_REF_1_MASK, val_p); 2534 + regmap_update_bits(rt5682->regmap, RT5682_ADDA_CLK_1, 2535 + RT5682_DAC_OSR_MASK, osr_p); 2536 + } else { 2537 + regmap_update_bits(rt5682->regmap, RT5682_SDW_REF_CLK, 2538 + RT5682_SDW_REF_2_MASK, val_c); 2539 + regmap_update_bits(rt5682->regmap, RT5682_ADDA_CLK_1, 2540 + RT5682_ADC_OSR_MASK, osr_c); 2541 + } 2542 + 2543 + return retval; 2544 + } 2545 + 2546 + static int rt5682_sdw_hw_free(struct snd_pcm_substream *substream, 2547 + struct snd_soc_dai *dai) 2548 + { 2549 + struct snd_soc_component *component = dai->component; 2550 + struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); 2551 + struct sdw_stream_data *stream = 2552 + snd_soc_dai_get_dma_data(dai, substream); 2553 + 2554 + if (!rt5682->slave) 2555 + return -EINVAL; 2556 + 2557 + sdw_stream_remove_slave(rt5682->slave, stream->sdw_stream); 2558 + return 0; 2559 + } 2560 + 2561 + static struct snd_soc_dai_ops rt5682_sdw_ops = { 2562 + .hw_params = rt5682_sdw_hw_params, 2563 + .hw_free = rt5682_sdw_hw_free, 2564 + .set_sdw_stream = rt5682_set_sdw_stream, 2565 + .shutdown = rt5682_sdw_shutdown, 2566 + }; 2567 + #endif 2949 2568 2950 2569 static struct snd_soc_dai_driver rt5682_dai[] = { 2951 2570 { ··· 3168 2409 }, 3169 2410 .ops = &rt5682_aif2_dai_ops, 3170 2411 }, 2412 + #if IS_ENABLED(CONFIG_SND_SOC_RT5682_SDW) 2413 + { 2414 + .name = "rt5682-sdw", 2415 + .id = RT5682_SDW, 2416 + .playback = { 2417 + .stream_name = "SDW Playback", 2418 + .channels_min = 1, 2419 + .channels_max = 2, 2420 + .rates = RT5682_STEREO_RATES, 2421 + .formats = RT5682_FORMATS, 2422 + }, 2423 + .capture = { 2424 + .stream_name = "SDW Capture", 2425 + .channels_min = 1, 2426 + .channels_max = 2, 2427 + .rates = RT5682_STEREO_RATES, 2428 + .formats = RT5682_FORMATS, 2429 + }, 2430 + .ops = &rt5682_sdw_ops, 2431 + }, 2432 + #endif 3171 2433 }; 3172 2434 3173 2435 static const struct snd_soc_component_driver soc_component_dev_rt5682 = { ··· 3241 2461 &rt5682->pdata.jd_src); 3242 2462 device_property_read_u32(dev, "realtek,btndet-delay", 3243 2463 &rt5682->pdata.btndet_delay); 2464 + device_property_read_u32(dev, "realtek,dmic-clk-rate-hz", 2465 + &rt5682->pdata.dmic_clk_rate); 2466 + device_property_read_u32(dev, "realtek,dmic-delay-ms", 2467 + &rt5682->pdata.dmic_delay); 3244 2468 3245 2469 rt5682->pdata.ldo1_en = of_get_named_gpio(dev->of_node, 3246 2470 "realtek,ldo1-en-gpios", 0); 2471 + 2472 + if (device_property_read_string_array(dev, "clock-output-names", 2473 + rt5682->pdata.dai_clk_names, 2474 + RT5682_DAI_NUM_CLKS) < 0) 2475 + dev_warn(dev, "Using default DAI clk names: %s, %s\n", 2476 + rt5682->pdata.dai_clk_names[RT5682_DAI_WCLK_IDX], 2477 + rt5682->pdata.dai_clk_names[RT5682_DAI_BCLK_IDX]); 3247 2478 3248 2479 return 0; 3249 2480 } ··· 3265 2474 3266 2475 mutex_lock(&rt5682->calibrate_mutex); 3267 2476 3268 - rt5682_reset(rt5682->regmap); 2477 + rt5682_reset(rt5682); 3269 2478 regmap_write(rt5682->regmap, RT5682_I2C_CTRL, 0x000f); 3270 2479 regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xa2af); 3271 2480 usleep_range(15000, 20000); ··· 3310 2519 mutex_unlock(&rt5682->calibrate_mutex); 3311 2520 3312 2521 } 2522 + 2523 + #if IS_ENABLED(CONFIG_SND_SOC_RT5682_SDW) 2524 + static int rt5682_sdw_read(void *context, unsigned int reg, unsigned int *val) 2525 + { 2526 + struct device *dev = context; 2527 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 2528 + unsigned int data_l, data_h; 2529 + 2530 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_CMD, 0); 2531 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_ADDR_H, (reg >> 8) & 0xff); 2532 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_ADDR_L, (reg & 0xff)); 2533 + regmap_read(rt5682->sdw_regmap, RT5682_SDW_DATA_H, &data_h); 2534 + regmap_read(rt5682->sdw_regmap, RT5682_SDW_DATA_L, &data_l); 2535 + 2536 + *val = (data_h << 8) | data_l; 2537 + 2538 + dev_vdbg(dev, "[%s] %04x => %04x\n", __func__, reg, *val); 2539 + 2540 + return 0; 2541 + } 2542 + 2543 + static int rt5682_sdw_write(void *context, unsigned int reg, unsigned int val) 2544 + { 2545 + struct device *dev = context; 2546 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 2547 + 2548 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_CMD, 1); 2549 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_ADDR_H, (reg >> 8) & 0xff); 2550 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_ADDR_L, (reg & 0xff)); 2551 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_DATA_H, (val >> 8) & 0xff); 2552 + regmap_write(rt5682->sdw_regmap, RT5682_SDW_DATA_L, (val & 0xff)); 2553 + 2554 + dev_vdbg(dev, "[%s] %04x <= %04x\n", __func__, reg, val); 2555 + 2556 + return 0; 2557 + } 2558 + 2559 + static const struct regmap_config rt5682_sdw_regmap = { 2560 + .reg_bits = 16, 2561 + .val_bits = 16, 2562 + .max_register = RT5682_I2C_MODE, 2563 + .volatile_reg = rt5682_volatile_register, 2564 + .readable_reg = rt5682_readable_register, 2565 + .cache_type = REGCACHE_RBTREE, 2566 + .reg_defaults = rt5682_reg, 2567 + .num_reg_defaults = ARRAY_SIZE(rt5682_reg), 2568 + .use_single_read = true, 2569 + .use_single_write = true, 2570 + .reg_read = rt5682_sdw_read, 2571 + .reg_write = rt5682_sdw_write, 2572 + }; 2573 + 2574 + int rt5682_sdw_init(struct device *dev, struct regmap *regmap, 2575 + struct sdw_slave *slave) 2576 + { 2577 + struct rt5682_priv *rt5682; 2578 + int ret; 2579 + 2580 + rt5682 = devm_kzalloc(dev, sizeof(*rt5682), GFP_KERNEL); 2581 + if (!rt5682) 2582 + return -ENOMEM; 2583 + 2584 + dev_set_drvdata(dev, rt5682); 2585 + rt5682->slave = slave; 2586 + rt5682->sdw_regmap = regmap; 2587 + rt5682->is_sdw = true; 2588 + 2589 + rt5682->regmap = devm_regmap_init(dev, NULL, dev, &rt5682_sdw_regmap); 2590 + if (IS_ERR(rt5682->regmap)) { 2591 + ret = PTR_ERR(rt5682->regmap); 2592 + dev_err(dev, "Failed to allocate register map: %d\n", 2593 + ret); 2594 + return ret; 2595 + } 2596 + 2597 + /* 2598 + * Mark hw_init to false 2599 + * HW init will be performed when device reports present 2600 + */ 2601 + rt5682->hw_init = false; 2602 + rt5682->first_hw_init = false; 2603 + 2604 + mutex_init(&rt5682->calibrate_mutex); 2605 + INIT_DELAYED_WORK(&rt5682->jack_detect_work, 2606 + rt5682_jack_detect_handler); 2607 + 2608 + ret = devm_snd_soc_register_component(dev, &soc_component_dev_rt5682, 2609 + rt5682_dai, ARRAY_SIZE(rt5682_dai)); 2610 + 2611 + dev_dbg(&slave->dev, "%s\n", __func__); 2612 + 2613 + return ret; 2614 + } 2615 + EXPORT_SYMBOL_GPL(rt5682_sdw_init); 2616 + 2617 + int rt5682_io_init(struct device *dev, struct sdw_slave *slave) 2618 + { 2619 + struct rt5682_priv *rt5682 = dev_get_drvdata(dev); 2620 + int ret = 0; 2621 + unsigned int val; 2622 + 2623 + if (rt5682->hw_init) 2624 + return 0; 2625 + 2626 + regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val); 2627 + if (val != DEVICE_ID) { 2628 + pr_err("Device with ID register %x is not rt5682\n", val); 2629 + return -ENODEV; 2630 + } 2631 + 2632 + /* 2633 + * PM runtime is only enabled when a Slave reports as Attached 2634 + */ 2635 + if (!rt5682->first_hw_init) { 2636 + /* set autosuspend parameters */ 2637 + pm_runtime_set_autosuspend_delay(&slave->dev, 3000); 2638 + pm_runtime_use_autosuspend(&slave->dev); 2639 + 2640 + /* update count of parent 'active' children */ 2641 + pm_runtime_set_active(&slave->dev); 2642 + 2643 + /* make sure the device does not suspend immediately */ 2644 + pm_runtime_mark_last_busy(&slave->dev); 2645 + 2646 + pm_runtime_enable(&slave->dev); 2647 + } 2648 + 2649 + pm_runtime_get_noresume(&slave->dev); 2650 + 2651 + rt5682_reset(rt5682); 2652 + 2653 + if (rt5682->first_hw_init) { 2654 + regcache_cache_only(rt5682->regmap, false); 2655 + regcache_cache_bypass(rt5682->regmap, true); 2656 + } 2657 + 2658 + rt5682_calibrate(rt5682); 2659 + 2660 + if (rt5682->first_hw_init) { 2661 + regcache_cache_bypass(rt5682->regmap, false); 2662 + regcache_mark_dirty(rt5682->regmap); 2663 + regcache_sync(rt5682->regmap); 2664 + 2665 + /* volatile registers */ 2666 + regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_2, 2667 + RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); 2668 + 2669 + goto reinit; 2670 + } 2671 + 2672 + ret = regmap_multi_reg_write(rt5682->regmap, patch_list, 2673 + ARRAY_SIZE(patch_list)); 2674 + if (ret != 0) 2675 + dev_warn(dev, "Failed to apply regmap patch: %d\n", ret); 2676 + 2677 + regmap_write(rt5682->regmap, RT5682_DEPOP_1, 0x0000); 2678 + 2679 + regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1, 2680 + RT5682_LDO1_DVO_MASK | RT5682_HP_DRIVER_MASK, 2681 + RT5682_LDO1_DVO_12 | RT5682_HP_DRIVER_5X); 2682 + regmap_write(rt5682->regmap, RT5682_MICBIAS_2, 0x0380); 2683 + regmap_write(rt5682->regmap, RT5682_TEST_MODE_CTRL_1, 0x0000); 2684 + regmap_update_bits(rt5682->regmap, RT5682_BIAS_CUR_CTRL_8, 2685 + RT5682_HPA_CP_BIAS_CTRL_MASK, RT5682_HPA_CP_BIAS_3UA); 2686 + regmap_update_bits(rt5682->regmap, RT5682_CHARGE_PUMP_1, 2687 + RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ); 2688 + regmap_update_bits(rt5682->regmap, RT5682_HP_CHARGE_PUMP_1, 2689 + RT5682_PM_HP_MASK, RT5682_PM_HP_HV); 2690 + 2691 + /* Soundwire */ 2692 + regmap_write(rt5682->regmap, RT5682_PLL2_INTERNAL, 0xa266); 2693 + regmap_write(rt5682->regmap, RT5682_PLL2_CTRL_1, 0x1700); 2694 + regmap_write(rt5682->regmap, RT5682_PLL2_CTRL_2, 0x0006); 2695 + regmap_write(rt5682->regmap, RT5682_PLL2_CTRL_3, 0x2600); 2696 + regmap_write(rt5682->regmap, RT5682_PLL2_CTRL_4, 0x0c8f); 2697 + regmap_write(rt5682->regmap, RT5682_PLL_TRACK_2, 0x3000); 2698 + regmap_write(rt5682->regmap, RT5682_PLL_TRACK_3, 0x4000); 2699 + regmap_update_bits(rt5682->regmap, RT5682_GLB_CLK, 2700 + RT5682_SCLK_SRC_MASK | RT5682_PLL2_SRC_MASK, 2701 + RT5682_SCLK_SRC_PLL2 | RT5682_PLL2_SRC_SDW); 2702 + 2703 + regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_2, 2704 + RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); 2705 + regmap_write(rt5682->regmap, RT5682_CBJ_CTRL_1, 0xd042); 2706 + regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_3, 2707 + RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); 2708 + regmap_update_bits(rt5682->regmap, RT5682_SAR_IL_CMD_1, 2709 + RT5682_SAR_POW_MASK, RT5682_SAR_POW_EN); 2710 + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, 2711 + RT5682_POW_IRQ | RT5682_POW_JDH | 2712 + RT5682_POW_ANA, RT5682_POW_IRQ | 2713 + RT5682_POW_JDH | RT5682_POW_ANA); 2714 + regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_2, 2715 + RT5682_PWR_JDH, RT5682_PWR_JDH); 2716 + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, 2717 + RT5682_JD1_EN_MASK | RT5682_JD1_IRQ_MASK, 2718 + RT5682_JD1_EN | RT5682_JD1_IRQ_PUL); 2719 + 2720 + reinit: 2721 + mod_delayed_work(system_power_efficient_wq, 2722 + &rt5682->jack_detect_work, msecs_to_jiffies(250)); 2723 + 2724 + /* Mark Slave initialization complete */ 2725 + rt5682->hw_init = true; 2726 + rt5682->first_hw_init = true; 2727 + 2728 + pm_runtime_mark_last_busy(&slave->dev); 2729 + pm_runtime_put_autosuspend(&slave->dev); 2730 + 2731 + dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); 2732 + 2733 + return ret; 2734 + } 2735 + EXPORT_SYMBOL_GPL(rt5682_io_init); 2736 + #endif 3313 2737 3314 2738 static int rt5682_i2c_probe(struct i2c_client *i2c, 3315 2739 const struct i2c_device_id *id) ··· 3592 2586 return -ENODEV; 3593 2587 } 3594 2588 3595 - rt5682_reset(rt5682->regmap); 2589 + rt5682_reset(rt5682); 3596 2590 3597 2591 mutex_init(&rt5682->calibrate_mutex); 3598 2592 rt5682_calibrate(rt5682); ··· 3657 2651 RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ); 3658 2652 regmap_update_bits(rt5682->regmap, RT5682_HP_CHARGE_PUMP_1, 3659 2653 RT5682_PM_HP_MASK, RT5682_PM_HP_HV); 2654 + regmap_update_bits(rt5682->regmap, RT5682_DMIC_CTRL_1, 2655 + RT5682_FIFO_CLK_DIV_MASK, RT5682_FIFO_CLK_DIV_2); 3660 2656 3661 2657 INIT_DELAYED_WORK(&rt5682->jack_detect_work, 3662 2658 rt5682_jack_detect_handler); ··· 3684 2676 { 3685 2677 struct rt5682_priv *rt5682 = i2c_get_clientdata(client); 3686 2678 3687 - rt5682_reset(rt5682->regmap); 2679 + rt5682_reset(rt5682); 3688 2680 } 3689 2681 3690 2682 #ifdef CONFIG_OF
+96 -4
sound/soc/codecs/rt5682.h
··· 10 10 #define __RT5682_H__ 11 11 12 12 #include <sound/rt5682.h> 13 + #include <linux/regulator/consumer.h> 14 + #include <linux/clk.h> 15 + #include <linux/clkdev.h> 16 + #include <linux/clk-provider.h> 17 + #include <linux/soundwire/sdw.h> 18 + #include <linux/soundwire/sdw_type.h> 13 19 14 20 #define DEVICE_ID 0x6530 15 21 ··· 183 177 #define RT5682_TEST_MODE_CTRL_4 0x0148 184 178 #define RT5682_TEST_MODE_CTRL_5 0x0149 185 179 #define RT5682_PLL1_INTERNAL 0x0150 186 - #define RT5682_PLL2_INTERNAL 0x0151 180 + #define RT5682_PLL2_INTERNAL 0x0156 187 181 #define RT5682_STO_NG2_CTRL_1 0x0160 188 182 #define RT5682_STO_NG2_CTRL_2 0x0161 189 183 #define RT5682_STO_NG2_CTRL_3 0x0162 ··· 657 651 #define RT5682_DMIC_1_EN_SFT 15 658 652 #define RT5682_DMIC_1_DIS (0x0 << 15) 659 653 #define RT5682_DMIC_1_EN (0x1 << 15) 654 + #define RT5682_FIFO_CLK_DIV_MASK (0x7 << 12) 655 + #define RT5682_FIFO_CLK_DIV_2 (0x1 << 12) 660 656 #define RT5682_DMIC_1_DP_MASK (0x3 << 4) 661 657 #define RT5682_DMIC_1_DP_SFT 4 662 658 #define RT5682_DMIC_1_DP_GPIO2 (0x0 << 4) ··· 746 738 #define RT5682_ADC_OSR_D_24 (0x7 << 12) 747 739 #define RT5682_ADC_OSR_D_32 (0x8 << 12) 748 740 #define RT5682_ADC_OSR_D_48 (0x9 << 12) 749 - #define RT5682_I2S_M_DIV_MASK (0xf << 12) 741 + #define RT5682_I2S_M_DIV_MASK (0xf << 8) 750 742 #define RT5682_I2S_M_DIV_SFT 8 751 743 #define RT5682_I2S_M_D_1 (0x0 << 8) 752 744 #define RT5682_I2S_M_D_2 (0x1 << 8) ··· 828 820 #define RT5682_TDM_DF_PCM_B (0x3 << 11) 829 821 #define RT5682_TDM_DF_PCM_A_N (0x6 << 11) 830 822 #define RT5682_TDM_DF_PCM_B_N (0x7 << 11) 823 + #define RT5682_TDM_BCLK_MS1_MASK (0x3 << 9) 824 + #define RT5682_TDM_BCLK_MS1_SFT 9 825 + #define RT5682_TDM_BCLK_MS1_32 (0x0 << 9) 826 + #define RT5682_TDM_BCLK_MS1_64 (0x1 << 9) 827 + #define RT5682_TDM_BCLK_MS1_128 (0x2 << 9) 828 + #define RT5682_TDM_BCLK_MS1_256 (0x3 << 9) 831 829 #define RT5682_TDM_CL_MASK (0x3 << 4) 832 830 #define RT5682_TDM_CL_16 (0x0 << 4) 833 831 #define RT5682_TDM_CL_20 (0x1 << 4) ··· 849 835 #define RT5682_TDM_M_LP_INV (0x1 << 1) 850 836 #define RT5682_TDM_MS_MASK (0x1 << 0) 851 837 #define RT5682_TDM_MS_SFT 0 852 - #define RT5682_TDM_MS_M (0x0 << 0) 853 - #define RT5682_TDM_MS_S (0x1 << 0) 838 + #define RT5682_TDM_MS_S (0x0 << 0) 839 + #define RT5682_TDM_MS_M (0x1 << 0) 854 840 855 841 /* Global Clock Control (0x0080) */ 856 842 #define RT5682_SCLK_SRC_MASK (0x7 << 13) ··· 1063 1049 #define RT5682_PWR_CLK1M_PD (0x0 << 8) 1064 1050 #define RT5682_PWR_CLK1M_PU (0x1 << 8) 1065 1051 1052 + /* PLL2 M/N/K Code Control 1 (0x009b) */ 1053 + #define RT5682_PLL2F_K_MASK (0x1f << 8) 1054 + #define RT5682_PLL2F_K_SFT 8 1055 + #define RT5682_PLL2B_K_MASK (0xf << 4) 1056 + #define RT5682_PLL2B_K_SFT 4 1057 + #define RT5682_PLL2B_M_MASK (0xf << 0) 1058 + 1059 + /* PLL2 M/N/K Code Control 2 (0x009c) */ 1060 + #define RT5682_PLL2F_M_MASK (0x3f << 8) 1061 + #define RT5682_PLL2F_M_SFT 8 1062 + #define RT5682_PLL2B_N_MASK (0x3f << 0) 1063 + 1064 + /* PLL2 M/N/K Code Control 2 (0x009d) */ 1065 + #define RT5682_PLL2F_N_MASK (0x7f << 8) 1066 + #define RT5682_PLL2F_N_SFT 8 1067 + 1068 + /* PLL2 M/N/K Code Control 2 (0x009e) */ 1069 + #define RT5682_PLL2B_M_BP_MASK (0x1 << 11) 1070 + #define RT5682_PLL2B_M_BP_SFT 11 1071 + #define RT5682_PLL2F_M_BP_MASK (0x1 << 7) 1072 + #define RT5682_PLL2F_M_BP_SFT 7 1073 + 1066 1074 /* RC Clock Control (0x009f) */ 1067 1075 #define RT5682_POW_IRQ (0x1 << 15) 1068 1076 #define RT5682_POW_JDH (0x1 << 14) ··· 1127 1091 #define RT5682_JD1_POL_MASK (0x1 << 13) 1128 1092 #define RT5682_JD1_POL_NOR (0x0 << 13) 1129 1093 #define RT5682_JD1_POL_INV (0x1 << 13) 1094 + #define RT5682_JD1_IRQ_MASK (0x1 << 10) 1095 + #define RT5682_JD1_IRQ_LEV (0x0 << 10) 1096 + #define RT5682_JD1_IRQ_PUL (0x1 << 10) 1130 1097 1131 1098 /* IRQ Control 3 (0x00b8) */ 1132 1099 #define RT5682_IL_IRQ_MASK (0x1 << 7) 1133 1100 #define RT5682_IL_IRQ_DIS (0x0 << 7) 1134 1101 #define RT5682_IL_IRQ_EN (0x1 << 7) 1102 + #define RT5682_IL_IRQ_TYPE_MASK (0x1 << 4) 1103 + #define RT5682_IL_IRQ_LEV (0x0 << 4) 1104 + #define RT5682_IL_IRQ_PUL (0x1 << 4) 1135 1105 1136 1106 /* GPIO Control 1 (0x00c0) */ 1137 1107 #define RT5682_GP1_PIN_MASK (0x3 << 14) ··· 1351 1309 RT5682_PLL1_S_MCLK, 1352 1310 RT5682_PLL1_S_BCLK1, 1353 1311 RT5682_PLL1_S_RCCLK, 1312 + RT5682_PLL2_S_MCLK, 1313 + }; 1314 + 1315 + enum { 1316 + RT5682_PLL1, 1317 + RT5682_PLL2, 1318 + RT5682_PLLS, 1354 1319 }; 1355 1320 1356 1321 enum { 1357 1322 RT5682_AIF1, 1358 1323 RT5682_AIF2, 1324 + RT5682_SDW, 1359 1325 RT5682_AIFS 1360 1326 }; 1361 1327 ··· 1379 1329 RT5682_CLK_SEL_I2S2_ASRC, 1380 1330 }; 1381 1331 1332 + #define RT5682_NUM_SUPPLIES 3 1333 + 1334 + struct rt5682_priv { 1335 + struct snd_soc_component *component; 1336 + struct rt5682_platform_data pdata; 1337 + struct regmap *regmap; 1338 + struct regmap *sdw_regmap; 1339 + struct snd_soc_jack *hs_jack; 1340 + struct regulator_bulk_data supplies[RT5682_NUM_SUPPLIES]; 1341 + struct delayed_work jack_detect_work; 1342 + struct delayed_work jd_check_work; 1343 + struct mutex calibrate_mutex; 1344 + struct sdw_slave *slave; 1345 + enum sdw_slave_status status; 1346 + struct sdw_bus_params params; 1347 + bool hw_init; 1348 + bool first_hw_init; 1349 + bool is_sdw; 1350 + 1351 + #ifdef CONFIG_COMMON_CLK 1352 + struct clk_hw dai_clks_hw[RT5682_DAI_NUM_CLKS]; 1353 + struct clk_lookup *dai_clks_lookup[RT5682_DAI_NUM_CLKS]; 1354 + struct clk *dai_clks[RT5682_DAI_NUM_CLKS]; 1355 + struct clk *mclk; 1356 + #endif 1357 + 1358 + int sysclk; 1359 + int sysclk_src; 1360 + int lrck[RT5682_AIFS]; 1361 + int bclk[RT5682_AIFS]; 1362 + int master[RT5682_AIFS]; 1363 + 1364 + int pll_src[RT5682_PLLS]; 1365 + int pll_in[RT5682_PLLS]; 1366 + int pll_out[RT5682_PLLS]; 1367 + 1368 + int jack_type; 1369 + }; 1370 + 1382 1371 int rt5682_sel_asrc_clk_src(struct snd_soc_component *component, 1383 1372 unsigned int filter_mask, unsigned int clk_src); 1373 + int rt5682_sdw_init(struct device *dev, struct regmap *regmap, 1374 + struct sdw_slave *slave); 1375 + int rt5682_io_init(struct device *dev, struct sdw_slave *slave); 1384 1376 1385 1377 #endif /* __RT5682_H__ */
+114 -7
sound/soc/codecs/tas2562.c
··· 26 26 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 27 27 SNDRV_PCM_FORMAT_S32_LE) 28 28 29 + /* DVC equation involves floating point math 30 + * round(10^(volume in dB/20)*2^30) 31 + * so create a lookup table for 2dB step 32 + */ 33 + static const unsigned int float_vol_db_lookup[] = { 34 + 0x00000d43, 0x000010b2, 0x00001505, 0x00001a67, 0x00002151, 35 + 0x000029f1, 0x000034cd, 0x00004279, 0x000053af, 0x0000695b, 36 + 0x0000695b, 0x0000a6fa, 0x0000d236, 0x000108a4, 0x00014d2a, 37 + 0x0001a36e, 0x00021008, 0x000298c0, 0x000344df, 0x00041d8f, 38 + 0x00052e5a, 0x000685c8, 0x00083621, 0x000a566d, 0x000d03a7, 39 + 0x0010624d, 0x0014a050, 0x0019f786, 0x0020b0bc, 0x0029279d, 40 + 0x0033cf8d, 0x004139d3, 0x00521d50, 0x00676044, 0x0082248a, 41 + 0x00a3d70a, 0x00ce4328, 0x0103ab3d, 0x0146e75d, 0x019b8c27, 42 + 0x02061b89, 0x028c423f, 0x03352529, 0x0409c2b0, 0x05156d68, 43 + 0x080e9f96, 0x0a24b062, 0x0cc509ab, 0x10137987, 0x143d1362, 44 + 0x197a967f, 0x2013739e, 0x28619ae9, 0x32d64617, 0x40000000 45 + }; 46 + 29 47 struct tas2562_data { 30 48 struct snd_soc_component *component; 31 49 struct gpio_desc *sdz_gpio; ··· 52 34 struct i2c_client *client; 53 35 int v_sense_slot; 54 36 int i_sense_slot; 37 + int volume_lvl; 38 + }; 39 + 40 + enum tas256x_model { 41 + TAS2562, 42 + TAS2563, 55 43 }; 56 44 57 45 static int tas2562_set_bias_level(struct snd_soc_component *component, ··· 407 383 struct snd_soc_component *component = 408 384 snd_soc_dapm_to_component(w->dapm); 409 385 struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 386 + int ret; 410 387 411 388 switch (event) { 412 389 case SND_SOC_DAPM_POST_PMU: 413 - dev_info(tas2562->dev, "SND_SOC_DAPM_POST_PMU\n"); 390 + ret = snd_soc_component_update_bits(component, 391 + TAS2562_PWR_CTRL, 392 + TAS2562_MODE_MASK, 393 + TAS2562_MUTE); 394 + if (ret) 395 + goto end; 414 396 break; 415 397 case SND_SOC_DAPM_PRE_PMD: 416 - dev_info(tas2562->dev, "SND_SOC_DAPM_PRE_PMD\n"); 398 + ret = snd_soc_component_update_bits(component, 399 + TAS2562_PWR_CTRL, 400 + TAS2562_MODE_MASK, 401 + TAS2562_SHUTDOWN); 402 + if (ret) 403 + goto end; 417 404 break; 418 405 default: 419 - break; 406 + dev_err(tas2562->dev, "Not supported evevt\n"); 407 + return -EINVAL; 420 408 } 409 + 410 + end: 411 + if (ret < 0) 412 + return ret; 421 413 422 414 return 0; 423 415 } 416 + 417 + static int tas2562_volume_control_get(struct snd_kcontrol *kcontrol, 418 + struct snd_ctl_elem_value *ucontrol) 419 + { 420 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 421 + struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 422 + 423 + ucontrol->value.integer.value[0] = tas2562->volume_lvl; 424 + return 0; 425 + } 426 + 427 + static int tas2562_volume_control_put(struct snd_kcontrol *kcontrol, 428 + struct snd_ctl_elem_value *ucontrol) 429 + { 430 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 431 + struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component); 432 + int ret; 433 + u32 reg_val; 434 + 435 + reg_val = float_vol_db_lookup[ucontrol->value.integer.value[0]/2]; 436 + ret = snd_soc_component_write(component, TAS2562_DVC_CFG4, 437 + (reg_val & 0xff)); 438 + if (ret) 439 + return ret; 440 + ret = snd_soc_component_write(component, TAS2562_DVC_CFG3, 441 + ((reg_val >> 8) & 0xff)); 442 + if (ret) 443 + return ret; 444 + ret = snd_soc_component_write(component, TAS2562_DVC_CFG2, 445 + ((reg_val >> 16) & 0xff)); 446 + if (ret) 447 + return ret; 448 + ret = snd_soc_component_write(component, TAS2562_DVC_CFG1, 449 + ((reg_val >> 24) & 0xff)); 450 + if (ret) 451 + return ret; 452 + 453 + tas2562->volume_lvl = ucontrol->value.integer.value[0]; 454 + 455 + return ret; 456 + } 457 + 458 + /* Digital Volume Control. From 0 dB to -110 dB in 1 dB steps */ 459 + static const DECLARE_TLV_DB_SCALE(dvc_tlv, -11000, 100, 0); 424 460 425 461 static DECLARE_TLV_DB_SCALE(tas2562_dac_tlv, 850, 50, 0); 426 462 ··· 493 409 1, 1); 494 410 495 411 static const struct snd_kcontrol_new tas2562_snd_controls[] = { 496 - SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 0, 0x1c, 0, 412 + SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 1, 0x1c, 0, 497 413 tas2562_dac_tlv), 414 + { 415 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 416 + .name = "Digital Volume Control", 417 + .index = 0, 418 + .tlv.p = dvc_tlv, 419 + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, 420 + .info = snd_soc_info_volsw, 421 + .get = tas2562_volume_control_get, 422 + .put = tas2562_volume_control_put, 423 + .private_value = SOC_SINGLE_VALUE(TAS2562_DVC_CFG1, 0, 110, 0, 0) , 424 + }, 498 425 }; 499 426 500 427 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = { 501 428 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 502 429 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux), 503 - SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM, 0, 0), 504 430 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event, 505 431 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 506 432 SND_SOC_DAPM_SWITCH("ISENSE", TAS2562_PWR_CTRL, 3, 1, &isense_switch), ··· 525 431 {"ASI1 Sel", "Left", "ASI1"}, 526 432 {"ASI1 Sel", "Right", "ASI1"}, 527 433 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 528 - { "DAC", NULL, "DAC IN" }, 434 + { "DAC", NULL, "ASI1 Sel" }, 529 435 { "OUT", NULL, "DAC" }, 530 436 {"ISENSE", "Switch", "IMON"}, 531 437 {"VSENSE", "Switch", "VMON"}, ··· 566 472 .rates = SNDRV_PCM_RATE_8000_192000, 567 473 .formats = TAS2562_FORMATS, 568 474 }, 475 + .capture = { 476 + .stream_name = "ASI1 Capture", 477 + .channels_min = 0, 478 + .channels_max = 2, 479 + .rates = SNDRV_PCM_RATE_8000_192000, 480 + .formats = TAS2562_FORMATS, 481 + }, 569 482 .ops = &tas2562_speaker_dai_ops, 570 483 }, 571 484 }; ··· 596 495 { TAS2562_PB_CFG1, 0x20 }, 597 496 { TAS2562_TDM_CFG0, 0x09 }, 598 497 { TAS2562_TDM_CFG1, 0x02 }, 498 + { TAS2562_DVC_CFG1, 0x40 }, 499 + { TAS2562_DVC_CFG2, 0x40 }, 500 + { TAS2562_DVC_CFG3, 0x00 }, 501 + { TAS2562_DVC_CFG4, 0x00 }, 599 502 }; 600 503 601 504 static const struct regmap_config tas2562_regmap_config = { ··· 669 564 } 670 565 671 566 static const struct i2c_device_id tas2562_id[] = { 672 - { "tas2562", 0 }, 567 + { "tas2562", TAS2562 }, 568 + { "tas2563", TAS2563 }, 673 569 { } 674 570 }; 675 571 MODULE_DEVICE_TABLE(i2c, tas2562_id); 676 572 677 573 static const struct of_device_id tas2562_of_match[] = { 678 574 { .compatible = "ti,tas2562", }, 575 + { .compatible = "ti,tas2563", }, 679 576 { }, 680 577 }; 681 578 MODULE_DEVICE_TABLE(of, tas2562_of_match);
+7 -5
sound/soc/codecs/tas2562.h
··· 35 35 #define TAS2562_REV_ID TAS2562_REG(0, 0x7d) 36 36 37 37 /* Page 2 */ 38 - #define TAS2562_DVC_CFG1 TAS2562_REG(2, 0x01) 39 - #define TAS2562_DVC_CFG2 TAS2562_REG(2, 0x02) 38 + #define TAS2562_DVC_CFG1 TAS2562_REG(2, 0x0c) 39 + #define TAS2562_DVC_CFG2 TAS2562_REG(2, 0x0d) 40 + #define TAS2562_DVC_CFG3 TAS2562_REG(2, 0x0e) 41 + #define TAS2562_DVC_CFG4 TAS2562_REG(2, 0x0f) 40 42 41 43 #define TAS2562_RESET BIT(0) 42 44 43 - #define TAS2562_MODE_MASK 0x3 45 + #define TAS2562_MODE_MASK GENMASK(1,0) 44 46 #define TAS2562_ACTIVE 0x0 45 47 #define TAS2562_MUTE 0x1 46 48 #define TAS2562_SHUTDOWN 0x2 ··· 75 73 #define TAS2562_TDM_CFG2_RXWLEN_24B BIT(3) 76 74 #define TAS2562_TDM_CFG2_RXWLEN_32B (BIT(2) | BIT(3)) 77 75 78 - #define TAS2562_VSENSE_POWER_EN BIT(2) 79 - #define TAS2562_ISENSE_POWER_EN BIT(3) 76 + #define TAS2562_VSENSE_POWER_EN 2 77 + #define TAS2562_ISENSE_POWER_EN 3 80 78 81 79 #define TAS2562_TDM_CFG5_VSNS_EN BIT(6) 82 80 #define TAS2562_TDM_CFG5_VSNS_SLOT_MASK GENMASK(5, 0)
+920
sound/soc/codecs/tlv320adcx140.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // TLV320ADCX140 Sound driver 3 + // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 4 + 5 + #include <linux/module.h> 6 + #include <linux/moduleparam.h> 7 + #include <linux/init.h> 8 + #include <linux/delay.h> 9 + #include <linux/pm.h> 10 + #include <linux/i2c.h> 11 + #include <linux/gpio/consumer.h> 12 + #include <linux/regulator/consumer.h> 13 + #include <linux/acpi.h> 14 + #include <linux/of.h> 15 + #include <linux/of_gpio.h> 16 + #include <linux/slab.h> 17 + #include <sound/core.h> 18 + #include <sound/pcm.h> 19 + #include <sound/pcm_params.h> 20 + #include <sound/soc.h> 21 + #include <sound/initval.h> 22 + #include <sound/tlv.h> 23 + 24 + #include "tlv320adcx140.h" 25 + 26 + struct adcx140_priv { 27 + struct snd_soc_component *component; 28 + struct regulator *supply_areg; 29 + struct gpio_desc *gpio_reset; 30 + struct regmap *regmap; 31 + struct device *dev; 32 + 33 + int micbias_vg; 34 + 35 + unsigned int dai_fmt; 36 + unsigned int tdm_delay; 37 + unsigned int slot_width; 38 + }; 39 + 40 + static const struct reg_default adcx140_reg_defaults[] = { 41 + { ADCX140_PAGE_SELECT, 0x00 }, 42 + { ADCX140_SW_RESET, 0x00 }, 43 + { ADCX140_SLEEP_CFG, 0x00 }, 44 + { ADCX140_SHDN_CFG, 0x05 }, 45 + { ADCX140_ASI_CFG0, 0x30 }, 46 + { ADCX140_ASI_CFG1, 0x00 }, 47 + { ADCX140_ASI_CFG2, 0x00 }, 48 + { ADCX140_ASI_CH1, 0x00 }, 49 + { ADCX140_ASI_CH2, 0x01 }, 50 + { ADCX140_ASI_CH3, 0x02 }, 51 + { ADCX140_ASI_CH4, 0x03 }, 52 + { ADCX140_ASI_CH5, 0x04 }, 53 + { ADCX140_ASI_CH6, 0x05 }, 54 + { ADCX140_ASI_CH7, 0x06 }, 55 + { ADCX140_ASI_CH8, 0x07 }, 56 + { ADCX140_MST_CFG0, 0x02 }, 57 + { ADCX140_MST_CFG1, 0x48 }, 58 + { ADCX140_ASI_STS, 0xff }, 59 + { ADCX140_CLK_SRC, 0x10 }, 60 + { ADCX140_PDMCLK_CFG, 0x40 }, 61 + { ADCX140_PDM_CFG, 0x00 }, 62 + { ADCX140_GPIO_CFG0, 0x22 }, 63 + { ADCX140_GPO_CFG1, 0x00 }, 64 + { ADCX140_GPO_CFG2, 0x00 }, 65 + { ADCX140_GPO_CFG3, 0x00 }, 66 + { ADCX140_GPO_CFG4, 0x00 }, 67 + { ADCX140_GPO_VAL, 0x00 }, 68 + { ADCX140_GPIO_MON, 0x00 }, 69 + { ADCX140_GPI_CFG0, 0x00 }, 70 + { ADCX140_GPI_CFG1, 0x00 }, 71 + { ADCX140_GPI_MON, 0x00 }, 72 + { ADCX140_INT_CFG, 0x00 }, 73 + { ADCX140_INT_MASK0, 0xff }, 74 + { ADCX140_INT_LTCH0, 0x00 }, 75 + { ADCX140_BIAS_CFG, 0x00 }, 76 + { ADCX140_CH1_CFG0, 0x00 }, 77 + { ADCX140_CH1_CFG1, 0x00 }, 78 + { ADCX140_CH1_CFG2, 0xc9 }, 79 + { ADCX140_CH1_CFG3, 0x80 }, 80 + { ADCX140_CH1_CFG4, 0x00 }, 81 + { ADCX140_CH2_CFG0, 0x00 }, 82 + { ADCX140_CH2_CFG1, 0x00 }, 83 + { ADCX140_CH2_CFG2, 0xc9 }, 84 + { ADCX140_CH2_CFG3, 0x80 }, 85 + { ADCX140_CH2_CFG4, 0x00 }, 86 + { ADCX140_CH3_CFG0, 0x00 }, 87 + { ADCX140_CH3_CFG1, 0x00 }, 88 + { ADCX140_CH3_CFG2, 0xc9 }, 89 + { ADCX140_CH3_CFG3, 0x80 }, 90 + { ADCX140_CH3_CFG4, 0x00 }, 91 + { ADCX140_CH4_CFG0, 0x00 }, 92 + { ADCX140_CH4_CFG1, 0x00 }, 93 + { ADCX140_CH4_CFG2, 0xc9 }, 94 + { ADCX140_CH4_CFG3, 0x80 }, 95 + { ADCX140_CH4_CFG4, 0x00 }, 96 + { ADCX140_CH5_CFG2, 0xc9 }, 97 + { ADCX140_CH5_CFG3, 0x80 }, 98 + { ADCX140_CH5_CFG4, 0x00 }, 99 + { ADCX140_CH6_CFG2, 0xc9 }, 100 + { ADCX140_CH6_CFG3, 0x80 }, 101 + { ADCX140_CH6_CFG4, 0x00 }, 102 + { ADCX140_CH7_CFG2, 0xc9 }, 103 + { ADCX140_CH7_CFG3, 0x80 }, 104 + { ADCX140_CH7_CFG4, 0x00 }, 105 + { ADCX140_CH8_CFG2, 0xc9 }, 106 + { ADCX140_CH8_CFG3, 0x80 }, 107 + { ADCX140_CH8_CFG4, 0x00 }, 108 + { ADCX140_DSP_CFG0, 0x01 }, 109 + { ADCX140_DSP_CFG1, 0x40 }, 110 + { ADCX140_DRE_CFG0, 0x7b }, 111 + { ADCX140_AGC_CFG0, 0xe7 }, 112 + { ADCX140_IN_CH_EN, 0xf0 }, 113 + { ADCX140_ASI_OUT_CH_EN, 0x00 }, 114 + { ADCX140_PWR_CFG, 0x00 }, 115 + { ADCX140_DEV_STS0, 0x00 }, 116 + { ADCX140_DEV_STS1, 0x80 }, 117 + }; 118 + 119 + static const struct regmap_range_cfg adcx140_ranges[] = { 120 + { 121 + .range_min = 0, 122 + .range_max = 12 * 128, 123 + .selector_reg = ADCX140_PAGE_SELECT, 124 + .selector_mask = 0xff, 125 + .selector_shift = 0, 126 + .window_start = 0, 127 + .window_len = 128, 128 + }, 129 + }; 130 + 131 + static bool adcx140_volatile(struct device *dev, unsigned int reg) 132 + { 133 + switch (reg) { 134 + case ADCX140_SW_RESET: 135 + case ADCX140_DEV_STS0: 136 + case ADCX140_DEV_STS1: 137 + case ADCX140_ASI_STS: 138 + return true; 139 + default: 140 + return false; 141 + } 142 + } 143 + 144 + static const struct regmap_config adcx140_i2c_regmap = { 145 + .reg_bits = 8, 146 + .val_bits = 8, 147 + .reg_defaults = adcx140_reg_defaults, 148 + .num_reg_defaults = ARRAY_SIZE(adcx140_reg_defaults), 149 + .cache_type = REGCACHE_FLAT, 150 + .ranges = adcx140_ranges, 151 + .num_ranges = ARRAY_SIZE(adcx140_ranges), 152 + .max_register = 12 * 128, 153 + .volatile_reg = adcx140_volatile, 154 + }; 155 + 156 + /* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */ 157 + static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10000, 50, 0); 158 + 159 + /* ADC gain. From 0 to 42 dB in 1 dB steps */ 160 + static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); 161 + 162 + /* DRE Level. From -12 dB to -66 dB in 1 dB steps */ 163 + static DECLARE_TLV_DB_SCALE(dre_thresh_tlv, -6600, 100, 0); 164 + /* DRE Max Gain. From 2 dB to 26 dB in 2 dB steps */ 165 + static DECLARE_TLV_DB_SCALE(dre_gain_tlv, 200, 200, 0); 166 + 167 + /* AGC Level. From -6 dB to -36 dB in 2 dB steps */ 168 + static DECLARE_TLV_DB_SCALE(agc_thresh_tlv, -3600, 200, 0); 169 + /* AGC Max Gain. From 3 dB to 42 dB in 3 dB steps */ 170 + static DECLARE_TLV_DB_SCALE(agc_gain_tlv, 300, 300, 0); 171 + 172 + static const char * const decimation_filter_text[] = { 173 + "Linear Phase", "Low Latency", "Ultra-low Latency" 174 + }; 175 + 176 + static SOC_ENUM_SINGLE_DECL(decimation_filter_enum, ADCX140_DSP_CFG0, 4, 177 + decimation_filter_text); 178 + 179 + static const struct snd_kcontrol_new decimation_filter_controls[] = { 180 + SOC_DAPM_ENUM("Decimation Filter", decimation_filter_enum), 181 + }; 182 + 183 + static const char * const resistor_text[] = { 184 + "2.5 kOhm", "10 kOhm", "20 kOhm" 185 + }; 186 + 187 + static SOC_ENUM_SINGLE_DECL(in1_resistor_enum, ADCX140_CH1_CFG0, 2, 188 + resistor_text); 189 + static SOC_ENUM_SINGLE_DECL(in2_resistor_enum, ADCX140_CH2_CFG0, 2, 190 + resistor_text); 191 + static SOC_ENUM_SINGLE_DECL(in3_resistor_enum, ADCX140_CH3_CFG0, 2, 192 + resistor_text); 193 + static SOC_ENUM_SINGLE_DECL(in4_resistor_enum, ADCX140_CH4_CFG0, 2, 194 + resistor_text); 195 + 196 + static const struct snd_kcontrol_new in1_resistor_controls[] = { 197 + SOC_DAPM_ENUM("CH1 Resistor Select", in1_resistor_enum), 198 + }; 199 + static const struct snd_kcontrol_new in2_resistor_controls[] = { 200 + SOC_DAPM_ENUM("CH2 Resistor Select", in2_resistor_enum), 201 + }; 202 + static const struct snd_kcontrol_new in3_resistor_controls[] = { 203 + SOC_DAPM_ENUM("CH3 Resistor Select", in3_resistor_enum), 204 + }; 205 + static const struct snd_kcontrol_new in4_resistor_controls[] = { 206 + SOC_DAPM_ENUM("CH4 Resistor Select", in4_resistor_enum), 207 + }; 208 + 209 + /* Analog/Digital Selection */ 210 + static const char *adcx140_mic_sel_text[] = {"Analog", "Line In", "Digital"}; 211 + static const char *adcx140_analog_sel_text[] = {"Analog", "Line In"}; 212 + 213 + static SOC_ENUM_SINGLE_DECL(adcx140_mic1p_enum, 214 + ADCX140_CH1_CFG0, 5, 215 + adcx140_mic_sel_text); 216 + 217 + static const struct snd_kcontrol_new adcx140_dapm_mic1p_control = 218 + SOC_DAPM_ENUM("MIC1P MUX", adcx140_mic1p_enum); 219 + 220 + static SOC_ENUM_SINGLE_DECL(adcx140_mic1_analog_enum, 221 + ADCX140_CH1_CFG0, 7, 222 + adcx140_analog_sel_text); 223 + 224 + static const struct snd_kcontrol_new adcx140_dapm_mic1_analog_control = 225 + SOC_DAPM_ENUM("MIC1 Analog MUX", adcx140_mic1_analog_enum); 226 + 227 + static SOC_ENUM_SINGLE_DECL(adcx140_mic1m_enum, 228 + ADCX140_CH1_CFG0, 5, 229 + adcx140_mic_sel_text); 230 + 231 + static const struct snd_kcontrol_new adcx140_dapm_mic1m_control = 232 + SOC_DAPM_ENUM("MIC1M MUX", adcx140_mic1m_enum); 233 + 234 + static SOC_ENUM_SINGLE_DECL(adcx140_mic2p_enum, 235 + ADCX140_CH2_CFG0, 5, 236 + adcx140_mic_sel_text); 237 + 238 + static const struct snd_kcontrol_new adcx140_dapm_mic2p_control = 239 + SOC_DAPM_ENUM("MIC2P MUX", adcx140_mic2p_enum); 240 + 241 + static SOC_ENUM_SINGLE_DECL(adcx140_mic2_analog_enum, 242 + ADCX140_CH2_CFG0, 7, 243 + adcx140_analog_sel_text); 244 + 245 + static const struct snd_kcontrol_new adcx140_dapm_mic2_analog_control = 246 + SOC_DAPM_ENUM("MIC2 Analog MUX", adcx140_mic2_analog_enum); 247 + 248 + static SOC_ENUM_SINGLE_DECL(adcx140_mic2m_enum, 249 + ADCX140_CH2_CFG0, 5, 250 + adcx140_mic_sel_text); 251 + 252 + static const struct snd_kcontrol_new adcx140_dapm_mic2m_control = 253 + SOC_DAPM_ENUM("MIC2M MUX", adcx140_mic2m_enum); 254 + 255 + static SOC_ENUM_SINGLE_DECL(adcx140_mic3p_enum, 256 + ADCX140_CH3_CFG0, 5, 257 + adcx140_mic_sel_text); 258 + 259 + static const struct snd_kcontrol_new adcx140_dapm_mic3p_control = 260 + SOC_DAPM_ENUM("MIC3P MUX", adcx140_mic3p_enum); 261 + 262 + static SOC_ENUM_SINGLE_DECL(adcx140_mic3_analog_enum, 263 + ADCX140_CH3_CFG0, 7, 264 + adcx140_analog_sel_text); 265 + 266 + static const struct snd_kcontrol_new adcx140_dapm_mic3_analog_control = 267 + SOC_DAPM_ENUM("MIC3 Analog MUX", adcx140_mic3_analog_enum); 268 + 269 + static SOC_ENUM_SINGLE_DECL(adcx140_mic3m_enum, 270 + ADCX140_CH3_CFG0, 5, 271 + adcx140_mic_sel_text); 272 + 273 + static const struct snd_kcontrol_new adcx140_dapm_mic3m_control = 274 + SOC_DAPM_ENUM("MIC3M MUX", adcx140_mic3m_enum); 275 + 276 + static SOC_ENUM_SINGLE_DECL(adcx140_mic4p_enum, 277 + ADCX140_CH4_CFG0, 5, 278 + adcx140_mic_sel_text); 279 + 280 + static const struct snd_kcontrol_new adcx140_dapm_mic4p_control = 281 + SOC_DAPM_ENUM("MIC4P MUX", adcx140_mic4p_enum); 282 + 283 + static SOC_ENUM_SINGLE_DECL(adcx140_mic4_analog_enum, 284 + ADCX140_CH4_CFG0, 7, 285 + adcx140_analog_sel_text); 286 + 287 + static const struct snd_kcontrol_new adcx140_dapm_mic4_analog_control = 288 + SOC_DAPM_ENUM("MIC4 Analog MUX", adcx140_mic4_analog_enum); 289 + 290 + static SOC_ENUM_SINGLE_DECL(adcx140_mic4m_enum, 291 + ADCX140_CH4_CFG0, 5, 292 + adcx140_mic_sel_text); 293 + 294 + static const struct snd_kcontrol_new adcx140_dapm_mic4m_control = 295 + SOC_DAPM_ENUM("MIC4M MUX", adcx140_mic4m_enum); 296 + 297 + static const struct snd_kcontrol_new adcx140_dapm_ch1_en_switch = 298 + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 7, 1, 0); 299 + static const struct snd_kcontrol_new adcx140_dapm_ch2_en_switch = 300 + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 6, 1, 0); 301 + static const struct snd_kcontrol_new adcx140_dapm_ch3_en_switch = 302 + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 5, 1, 0); 303 + static const struct snd_kcontrol_new adcx140_dapm_ch4_en_switch = 304 + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 4, 1, 0); 305 + 306 + static const struct snd_kcontrol_new adcx140_dapm_ch1_dre_en_switch = 307 + SOC_DAPM_SINGLE("Switch", ADCX140_CH1_CFG0, 0, 1, 0); 308 + static const struct snd_kcontrol_new adcx140_dapm_ch2_dre_en_switch = 309 + SOC_DAPM_SINGLE("Switch", ADCX140_CH2_CFG0, 0, 1, 0); 310 + static const struct snd_kcontrol_new adcx140_dapm_ch3_dre_en_switch = 311 + SOC_DAPM_SINGLE("Switch", ADCX140_CH3_CFG0, 0, 1, 0); 312 + static const struct snd_kcontrol_new adcx140_dapm_ch4_dre_en_switch = 313 + SOC_DAPM_SINGLE("Switch", ADCX140_CH4_CFG0, 0, 1, 0); 314 + 315 + static const struct snd_kcontrol_new adcx140_dapm_dre_en_switch = 316 + SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 0); 317 + 318 + /* Output Mixer */ 319 + static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = { 320 + SOC_DAPM_SINGLE("Digital CH1 Switch", 0, 0, 0, 0), 321 + SOC_DAPM_SINGLE("Digital CH2 Switch", 0, 0, 0, 0), 322 + SOC_DAPM_SINGLE("Digital CH3 Switch", 0, 0, 0, 0), 323 + SOC_DAPM_SINGLE("Digital CH4 Switch", 0, 0, 0, 0), 324 + }; 325 + 326 + static const struct snd_soc_dapm_widget adcx140_dapm_widgets[] = { 327 + /* Analog Differential Inputs */ 328 + SND_SOC_DAPM_INPUT("MIC1P"), 329 + SND_SOC_DAPM_INPUT("MIC1M"), 330 + SND_SOC_DAPM_INPUT("MIC2P"), 331 + SND_SOC_DAPM_INPUT("MIC2M"), 332 + SND_SOC_DAPM_INPUT("MIC3P"), 333 + SND_SOC_DAPM_INPUT("MIC3M"), 334 + SND_SOC_DAPM_INPUT("MIC4P"), 335 + SND_SOC_DAPM_INPUT("MIC4M"), 336 + 337 + SND_SOC_DAPM_OUTPUT("CH1_OUT"), 338 + SND_SOC_DAPM_OUTPUT("CH2_OUT"), 339 + SND_SOC_DAPM_OUTPUT("CH3_OUT"), 340 + SND_SOC_DAPM_OUTPUT("CH4_OUT"), 341 + SND_SOC_DAPM_OUTPUT("CH5_OUT"), 342 + SND_SOC_DAPM_OUTPUT("CH6_OUT"), 343 + SND_SOC_DAPM_OUTPUT("CH7_OUT"), 344 + SND_SOC_DAPM_OUTPUT("CH8_OUT"), 345 + 346 + SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0, 347 + &adcx140_output_mixer_controls[0], 348 + ARRAY_SIZE(adcx140_output_mixer_controls)), 349 + 350 + /* Input Selection to MIC_PGA */ 351 + SND_SOC_DAPM_MUX("MIC1P Input Mux", SND_SOC_NOPM, 0, 0, 352 + &adcx140_dapm_mic1p_control), 353 + SND_SOC_DAPM_MUX("MIC2P Input Mux", SND_SOC_NOPM, 0, 0, 354 + &adcx140_dapm_mic2p_control), 355 + SND_SOC_DAPM_MUX("MIC3P Input Mux", SND_SOC_NOPM, 0, 0, 356 + &adcx140_dapm_mic3p_control), 357 + SND_SOC_DAPM_MUX("MIC4P Input Mux", SND_SOC_NOPM, 0, 0, 358 + &adcx140_dapm_mic4p_control), 359 + 360 + /* Input Selection to MIC_PGA */ 361 + SND_SOC_DAPM_MUX("MIC1 Analog Mux", SND_SOC_NOPM, 0, 0, 362 + &adcx140_dapm_mic1_analog_control), 363 + SND_SOC_DAPM_MUX("MIC2 Analog Mux", SND_SOC_NOPM, 0, 0, 364 + &adcx140_dapm_mic2_analog_control), 365 + SND_SOC_DAPM_MUX("MIC3 Analog Mux", SND_SOC_NOPM, 0, 0, 366 + &adcx140_dapm_mic3_analog_control), 367 + SND_SOC_DAPM_MUX("MIC4 Analog Mux", SND_SOC_NOPM, 0, 0, 368 + &adcx140_dapm_mic4_analog_control), 369 + 370 + SND_SOC_DAPM_MUX("MIC1M Input Mux", SND_SOC_NOPM, 0, 0, 371 + &adcx140_dapm_mic1m_control), 372 + SND_SOC_DAPM_MUX("MIC2M Input Mux", SND_SOC_NOPM, 0, 0, 373 + &adcx140_dapm_mic2m_control), 374 + SND_SOC_DAPM_MUX("MIC3M Input Mux", SND_SOC_NOPM, 0, 0, 375 + &adcx140_dapm_mic3m_control), 376 + SND_SOC_DAPM_MUX("MIC4M Input Mux", SND_SOC_NOPM, 0, 0, 377 + &adcx140_dapm_mic4m_control), 378 + 379 + SND_SOC_DAPM_PGA("MIC_GAIN_CTL_CH1", SND_SOC_NOPM, 0, 0, NULL, 0), 380 + SND_SOC_DAPM_PGA("MIC_GAIN_CTL_CH2", SND_SOC_NOPM, 0, 0, NULL, 0), 381 + SND_SOC_DAPM_PGA("MIC_GAIN_CTL_CH3", SND_SOC_NOPM, 0, 0, NULL, 0), 382 + SND_SOC_DAPM_PGA("MIC_GAIN_CTL_CH4", SND_SOC_NOPM, 0, 0, NULL, 0), 383 + 384 + SND_SOC_DAPM_ADC("CH1_ADC", "CH1 Capture", ADCX140_IN_CH_EN, 7, 0), 385 + SND_SOC_DAPM_ADC("CH2_ADC", "CH2 Capture", ADCX140_IN_CH_EN, 6, 0), 386 + SND_SOC_DAPM_ADC("CH3_ADC", "CH3 Capture", ADCX140_IN_CH_EN, 5, 0), 387 + SND_SOC_DAPM_ADC("CH4_ADC", "CH4 Capture", ADCX140_IN_CH_EN, 4, 0), 388 + 389 + SND_SOC_DAPM_SWITCH("CH1_ASI_EN", SND_SOC_NOPM, 0, 0, 390 + &adcx140_dapm_ch1_en_switch), 391 + SND_SOC_DAPM_SWITCH("CH2_ASI_EN", SND_SOC_NOPM, 0, 0, 392 + &adcx140_dapm_ch2_en_switch), 393 + SND_SOC_DAPM_SWITCH("CH3_ASI_EN", SND_SOC_NOPM, 0, 0, 394 + &adcx140_dapm_ch3_en_switch), 395 + SND_SOC_DAPM_SWITCH("CH4_ASI_EN", SND_SOC_NOPM, 0, 0, 396 + &adcx140_dapm_ch4_en_switch), 397 + 398 + SND_SOC_DAPM_SWITCH("DRE_ENABLE", SND_SOC_NOPM, 0, 0, 399 + &adcx140_dapm_dre_en_switch), 400 + 401 + SND_SOC_DAPM_SWITCH("CH1_DRE_EN", SND_SOC_NOPM, 0, 0, 402 + &adcx140_dapm_ch1_dre_en_switch), 403 + SND_SOC_DAPM_SWITCH("CH2_DRE_EN", SND_SOC_NOPM, 0, 0, 404 + &adcx140_dapm_ch2_dre_en_switch), 405 + SND_SOC_DAPM_SWITCH("CH3_DRE_EN", SND_SOC_NOPM, 0, 0, 406 + &adcx140_dapm_ch3_dre_en_switch), 407 + SND_SOC_DAPM_SWITCH("CH4_DRE_EN", SND_SOC_NOPM, 0, 0, 408 + &adcx140_dapm_ch4_dre_en_switch), 409 + 410 + SND_SOC_DAPM_MUX("IN1 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, 411 + in1_resistor_controls), 412 + SND_SOC_DAPM_MUX("IN2 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, 413 + in2_resistor_controls), 414 + SND_SOC_DAPM_MUX("IN3 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, 415 + in3_resistor_controls), 416 + SND_SOC_DAPM_MUX("IN4 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, 417 + in4_resistor_controls), 418 + 419 + SND_SOC_DAPM_MUX("Decimation Filter", SND_SOC_NOPM, 0, 0, 420 + decimation_filter_controls), 421 + }; 422 + 423 + static const struct snd_soc_dapm_route adcx140_audio_map[] = { 424 + /* Outputs */ 425 + {"CH1_OUT", NULL, "Output Mixer"}, 426 + {"CH2_OUT", NULL, "Output Mixer"}, 427 + {"CH3_OUT", NULL, "Output Mixer"}, 428 + {"CH4_OUT", NULL, "Output Mixer"}, 429 + 430 + {"CH1_ASI_EN", "Switch", "CH1_ADC"}, 431 + {"CH2_ASI_EN", "Switch", "CH2_ADC"}, 432 + {"CH3_ASI_EN", "Switch", "CH3_ADC"}, 433 + {"CH4_ASI_EN", "Switch", "CH4_ADC"}, 434 + 435 + {"Decimation Filter", "Linear Phase", "DRE_ENABLE"}, 436 + {"Decimation Filter", "Low Latency", "DRE_ENABLE"}, 437 + {"Decimation Filter", "Ultra-low Latency", "DRE_ENABLE"}, 438 + 439 + {"DRE_ENABLE", "Switch", "CH1_DRE_EN"}, 440 + {"DRE_ENABLE", "Switch", "CH2_DRE_EN"}, 441 + {"DRE_ENABLE", "Switch", "CH3_DRE_EN"}, 442 + {"DRE_ENABLE", "Switch", "CH4_DRE_EN"}, 443 + 444 + {"CH1_DRE_EN", "Switch", "CH1_ADC"}, 445 + {"CH2_DRE_EN", "Switch", "CH2_ADC"}, 446 + {"CH3_DRE_EN", "Switch", "CH3_ADC"}, 447 + {"CH4_DRE_EN", "Switch", "CH4_ADC"}, 448 + 449 + /* Mic input */ 450 + {"CH1_ADC", NULL, "MIC_GAIN_CTL_CH1"}, 451 + {"CH2_ADC", NULL, "MIC_GAIN_CTL_CH2"}, 452 + {"CH3_ADC", NULL, "MIC_GAIN_CTL_CH3"}, 453 + {"CH4_ADC", NULL, "MIC_GAIN_CTL_CH4"}, 454 + 455 + {"MIC_GAIN_CTL_CH1", NULL, "IN1 Analog Mic Resistor"}, 456 + {"MIC_GAIN_CTL_CH1", NULL, "IN1 Analog Mic Resistor"}, 457 + {"MIC_GAIN_CTL_CH2", NULL, "IN2 Analog Mic Resistor"}, 458 + {"MIC_GAIN_CTL_CH2", NULL, "IN2 Analog Mic Resistor"}, 459 + {"MIC_GAIN_CTL_CH3", NULL, "IN3 Analog Mic Resistor"}, 460 + {"MIC_GAIN_CTL_CH3", NULL, "IN3 Analog Mic Resistor"}, 461 + {"MIC_GAIN_CTL_CH4", NULL, "IN4 Analog Mic Resistor"}, 462 + {"MIC_GAIN_CTL_CH4", NULL, "IN4 Analog Mic Resistor"}, 463 + 464 + {"IN1 Analog Mic Resistor", "2.5 kOhm", "MIC1P Input Mux"}, 465 + {"IN1 Analog Mic Resistor", "10 kOhm", "MIC1P Input Mux"}, 466 + {"IN1 Analog Mic Resistor", "20 kOhm", "MIC1P Input Mux"}, 467 + 468 + {"IN1 Analog Mic Resistor", "2.5 kOhm", "MIC1M Input Mux"}, 469 + {"IN1 Analog Mic Resistor", "10 kOhm", "MIC1M Input Mux"}, 470 + {"IN1 Analog Mic Resistor", "20 kOhm", "MIC1M Input Mux"}, 471 + 472 + {"IN2 Analog Mic Resistor", "2.5 kOhm", "MIC2P Input Mux"}, 473 + {"IN2 Analog Mic Resistor", "10 kOhm", "MIC2P Input Mux"}, 474 + {"IN2 Analog Mic Resistor", "20 kOhm", "MIC2P Input Mux"}, 475 + 476 + {"IN2 Analog Mic Resistor", "2.5 kOhm", "MIC2M Input Mux"}, 477 + {"IN2 Analog Mic Resistor", "10 kOhm", "MIC2M Input Mux"}, 478 + {"IN2 Analog Mic Resistor", "20 kOhm", "MIC2M Input Mux"}, 479 + 480 + {"IN3 Analog Mic Resistor", "2.5 kOhm", "MIC3P Input Mux"}, 481 + {"IN3 Analog Mic Resistor", "10 kOhm", "MIC3P Input Mux"}, 482 + {"IN3 Analog Mic Resistor", "20 kOhm", "MIC3P Input Mux"}, 483 + 484 + {"IN3 Analog Mic Resistor", "2.5 kOhm", "MIC3M Input Mux"}, 485 + {"IN3 Analog Mic Resistor", "10 kOhm", "MIC3M Input Mux"}, 486 + {"IN3 Analog Mic Resistor", "20 kOhm", "MIC3M Input Mux"}, 487 + 488 + {"IN4 Analog Mic Resistor", "2.5 kOhm", "MIC4P Input Mux"}, 489 + {"IN4 Analog Mic Resistor", "10 kOhm", "MIC4P Input Mux"}, 490 + {"IN4 Analog Mic Resistor", "20 kOhm", "MIC4P Input Mux"}, 491 + 492 + {"IN4 Analog Mic Resistor", "2.5 kOhm", "MIC4M Input Mux"}, 493 + {"IN4 Analog Mic Resistor", "10 kOhm", "MIC4M Input Mux"}, 494 + {"IN4 Analog Mic Resistor", "20 kOhm", "MIC4M Input Mux"}, 495 + 496 + {"MIC1 Analog Mux", "Line In", "MIC1P"}, 497 + {"MIC2 Analog Mux", "Line In", "MIC2P"}, 498 + {"MIC3 Analog Mux", "Line In", "MIC3P"}, 499 + {"MIC4 Analog Mux", "Line In", "MIC4P"}, 500 + 501 + {"MIC1P Input Mux", "Analog", "MIC1P"}, 502 + {"MIC1M Input Mux", "Analog", "MIC1M"}, 503 + {"MIC2P Input Mux", "Analog", "MIC2P"}, 504 + {"MIC2M Input Mux", "Analog", "MIC2M"}, 505 + {"MIC3P Input Mux", "Analog", "MIC3P"}, 506 + {"MIC3M Input Mux", "Analog", "MIC3M"}, 507 + {"MIC4P Input Mux", "Analog", "MIC4P"}, 508 + {"MIC4M Input Mux", "Analog", "MIC4M"}, 509 + }; 510 + 511 + static const struct snd_kcontrol_new adcx140_snd_controls[] = { 512 + SOC_SINGLE_TLV("Analog CH1 Mic Gain Volume", ADCX140_CH1_CFG1, 2, 42, 0, 513 + adc_tlv), 514 + SOC_SINGLE_TLV("Analog CH2 Mic Gain Volume", ADCX140_CH1_CFG2, 2, 42, 0, 515 + adc_tlv), 516 + SOC_SINGLE_TLV("Analog CH3 Mic Gain Volume", ADCX140_CH1_CFG3, 2, 42, 0, 517 + adc_tlv), 518 + SOC_SINGLE_TLV("Analog CH4 Mic Gain Volume", ADCX140_CH1_CFG4, 2, 42, 0, 519 + adc_tlv), 520 + 521 + SOC_SINGLE_TLV("DRE Threshold", ADCX140_DRE_CFG0, 4, 9, 0, 522 + dre_thresh_tlv), 523 + SOC_SINGLE_TLV("DRE Max Gain", ADCX140_DRE_CFG0, 0, 12, 0, 524 + dre_gain_tlv), 525 + 526 + SOC_SINGLE_TLV("AGC Threshold", ADCX140_AGC_CFG0, 4, 15, 0, 527 + agc_thresh_tlv), 528 + SOC_SINGLE_TLV("AGC Max Gain", ADCX140_AGC_CFG0, 0, 13, 0, 529 + agc_gain_tlv), 530 + 531 + SOC_SINGLE_TLV("Digital CH1 Out Volume", ADCX140_CH1_CFG2, 532 + 0, 0xff, 0, dig_vol_tlv), 533 + SOC_SINGLE_TLV("Digital CH2 Out Volume", ADCX140_CH2_CFG2, 534 + 0, 0xff, 0, dig_vol_tlv), 535 + SOC_SINGLE_TLV("Digital CH3 Out Volume", ADCX140_CH3_CFG2, 536 + 0, 0xff, 0, dig_vol_tlv), 537 + SOC_SINGLE_TLV("Digital CH4 Out Volume", ADCX140_CH4_CFG2, 538 + 0, 0xff, 0, dig_vol_tlv), 539 + SOC_SINGLE_TLV("Digital CH5 Out Volume", ADCX140_CH5_CFG2, 540 + 0, 0xff, 0, dig_vol_tlv), 541 + SOC_SINGLE_TLV("Digital CH6 Out Volume", ADCX140_CH6_CFG2, 542 + 0, 0xff, 0, dig_vol_tlv), 543 + SOC_SINGLE_TLV("Digital CH7 Out Volume", ADCX140_CH7_CFG2, 544 + 0, 0xff, 0, dig_vol_tlv), 545 + SOC_SINGLE_TLV("Digital CH8 Out Volume", ADCX140_CH8_CFG2, 546 + 0, 0xff, 0, dig_vol_tlv), 547 + }; 548 + 549 + static int adcx140_reset(struct adcx140_priv *adcx140) 550 + { 551 + int ret = 0; 552 + 553 + if (adcx140->gpio_reset) { 554 + gpiod_direction_output(adcx140->gpio_reset, 0); 555 + /* 8.4.1: wait for hw shutdown (25ms) + >= 1ms */ 556 + usleep_range(30000, 100000); 557 + gpiod_direction_output(adcx140->gpio_reset, 1); 558 + } else { 559 + ret = regmap_write(adcx140->regmap, ADCX140_SW_RESET, 560 + ADCX140_RESET); 561 + } 562 + 563 + /* 8.4.2: wait >= 10 ms after entering sleep mode. */ 564 + usleep_range(10000, 100000); 565 + 566 + return 0; 567 + } 568 + 569 + static int adcx140_hw_params(struct snd_pcm_substream *substream, 570 + struct snd_pcm_hw_params *params, 571 + struct snd_soc_dai *dai) 572 + { 573 + struct snd_soc_component *component = dai->component; 574 + u8 data = 0; 575 + 576 + switch (params_width(params)) { 577 + case 16: 578 + data = ADCX140_16_BIT_WORD; 579 + break; 580 + case 20: 581 + data = ADCX140_20_BIT_WORD; 582 + break; 583 + case 24: 584 + data = ADCX140_24_BIT_WORD; 585 + break; 586 + case 32: 587 + data = ADCX140_32_BIT_WORD; 588 + break; 589 + default: 590 + dev_err(component->dev, "%s: Unsupported width %d\n", 591 + __func__, params_width(params)); 592 + return -EINVAL; 593 + } 594 + 595 + snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, 596 + ADCX140_WORD_LEN_MSK, data); 597 + 598 + return 0; 599 + } 600 + 601 + static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, 602 + unsigned int fmt) 603 + { 604 + struct snd_soc_component *component = codec_dai->component; 605 + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); 606 + u8 iface_reg1 = 0; 607 + u8 iface_reg2 = 0; 608 + 609 + /* set master/slave audio interface */ 610 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 611 + case SND_SOC_DAIFMT_CBM_CFM: 612 + iface_reg2 |= ADCX140_BCLK_FSYNC_MASTER; 613 + break; 614 + case SND_SOC_DAIFMT_CBS_CFS: 615 + break; 616 + case SND_SOC_DAIFMT_CBS_CFM: 617 + case SND_SOC_DAIFMT_CBM_CFS: 618 + default: 619 + dev_err(component->dev, "Invalid DAI master/slave interface\n"); 620 + return -EINVAL; 621 + } 622 + 623 + /* signal polarity */ 624 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 625 + case SND_SOC_DAIFMT_NB_IF: 626 + iface_reg1 |= ADCX140_FSYNCINV_BIT; 627 + break; 628 + case SND_SOC_DAIFMT_IB_IF: 629 + iface_reg1 |= ADCX140_BCLKINV_BIT | ADCX140_FSYNCINV_BIT; 630 + break; 631 + case SND_SOC_DAIFMT_IB_NF: 632 + iface_reg1 |= ADCX140_BCLKINV_BIT; 633 + break; 634 + case SND_SOC_DAIFMT_NB_NF: 635 + break; 636 + default: 637 + dev_err(component->dev, "Invalid DAI clock signal polarity\n"); 638 + return -EINVAL; 639 + } 640 + 641 + /* interface format */ 642 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 643 + case SND_SOC_DAIFMT_I2S: 644 + iface_reg1 |= ADCX140_I2S_MODE_BIT; 645 + break; 646 + case SND_SOC_DAIFMT_LEFT_J: 647 + iface_reg1 |= ADCX140_LEFT_JUST_BIT; 648 + break; 649 + case SND_SOC_DAIFMT_DSP_A: 650 + case SND_SOC_DAIFMT_DSP_B: 651 + break; 652 + default: 653 + dev_err(component->dev, "Invalid DAI interface format\n"); 654 + return -EINVAL; 655 + } 656 + 657 + adcx140->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 658 + 659 + snd_soc_component_update_bits(component, ADCX140_ASI_CFG0, 660 + ADCX140_FSYNCINV_BIT | 661 + ADCX140_BCLKINV_BIT | 662 + ADCX140_ASI_FORMAT_MSK, 663 + iface_reg1); 664 + snd_soc_component_update_bits(component, ADCX140_MST_CFG0, 665 + ADCX140_BCLK_FSYNC_MASTER, iface_reg2); 666 + 667 + return 0; 668 + } 669 + 670 + static int adcx140_set_dai_tdm_slot(struct snd_soc_dai *codec_dai, 671 + unsigned int tx_mask, unsigned int rx_mask, 672 + int slots, int slot_width) 673 + { 674 + struct snd_soc_component *component = codec_dai->component; 675 + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); 676 + unsigned int lsb; 677 + 678 + if (tx_mask != rx_mask) { 679 + dev_err(component->dev, "tx and rx masks must be symmetric\n"); 680 + return -EINVAL; 681 + } 682 + 683 + /* TDM based on DSP mode requires slots to be adjacent */ 684 + lsb = __ffs(tx_mask); 685 + if ((lsb + 1) != __fls(tx_mask)) { 686 + dev_err(component->dev, "Invalid mask, slots must be adjacent\n"); 687 + return -EINVAL; 688 + } 689 + 690 + switch (slot_width) { 691 + case 16: 692 + case 20: 693 + case 24: 694 + case 32: 695 + break; 696 + default: 697 + dev_err(component->dev, "Unsupported slot width %d\n", slot_width); 698 + return -EINVAL; 699 + } 700 + 701 + adcx140->tdm_delay = lsb; 702 + adcx140->slot_width = slot_width; 703 + 704 + return 0; 705 + } 706 + 707 + static int adcx140_prepare(struct snd_pcm_substream *substream, 708 + struct snd_soc_dai *dai) 709 + { 710 + struct snd_soc_component *component = dai->component; 711 + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); 712 + int offset = 0; 713 + int width = adcx140->slot_width; 714 + 715 + if (!width) 716 + width = substream->runtime->sample_bits; 717 + 718 + /* TDM slot selection only valid in DSP_A/_B mode */ 719 + if (adcx140->dai_fmt == SND_SOC_DAIFMT_DSP_A) 720 + offset += (adcx140->tdm_delay * width + 1); 721 + else if (adcx140->dai_fmt == SND_SOC_DAIFMT_DSP_B) 722 + offset += adcx140->tdm_delay * width; 723 + 724 + /* Configure data offset */ 725 + snd_soc_component_update_bits(component, ADCX140_ASI_CFG1, 726 + ADCX140_TX_OFFSET_MASK, offset); 727 + 728 + return 0; 729 + } 730 + 731 + static const struct snd_soc_dai_ops adcx140_dai_ops = { 732 + .hw_params = adcx140_hw_params, 733 + .set_fmt = adcx140_set_dai_fmt, 734 + .prepare = adcx140_prepare, 735 + .set_tdm_slot = adcx140_set_dai_tdm_slot, 736 + }; 737 + 738 + static int adcx140_codec_probe(struct snd_soc_component *component) 739 + { 740 + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); 741 + int sleep_cfg_val = ADCX140_WAKE_DEV; 742 + u8 bias_source; 743 + u8 vref_source; 744 + int ret; 745 + 746 + ret = device_property_read_u8(adcx140->dev, "ti,mic-bias-source", 747 + &bias_source); 748 + if (ret) 749 + bias_source = ADCX140_MIC_BIAS_VAL_VREF; 750 + 751 + if (bias_source < ADCX140_MIC_BIAS_VAL_VREF || 752 + bias_source > ADCX140_MIC_BIAS_VAL_AVDD) { 753 + dev_err(adcx140->dev, "Mic Bias source value is invalid\n"); 754 + return -EINVAL; 755 + } 756 + 757 + ret = device_property_read_u8(adcx140->dev, "ti,vref-source", 758 + &vref_source); 759 + if (ret) 760 + vref_source = ADCX140_MIC_BIAS_VREF_275V; 761 + 762 + if (vref_source < ADCX140_MIC_BIAS_VREF_275V || 763 + vref_source > ADCX140_MIC_BIAS_VREF_1375V) { 764 + dev_err(adcx140->dev, "Mic Bias source value is invalid\n"); 765 + return -EINVAL; 766 + } 767 + 768 + bias_source |= vref_source; 769 + 770 + ret = adcx140_reset(adcx140); 771 + if (ret) 772 + goto out; 773 + 774 + if(adcx140->supply_areg == NULL) 775 + sleep_cfg_val |= ADCX140_AREG_INTERNAL; 776 + 777 + ret = regmap_write(adcx140->regmap, ADCX140_SLEEP_CFG, sleep_cfg_val); 778 + if (ret) { 779 + dev_err(adcx140->dev, "setting sleep config failed %d\n", ret); 780 + goto out; 781 + } 782 + 783 + /* 8.4.3: Wait >= 1ms after entering active mode. */ 784 + usleep_range(1000, 100000); 785 + 786 + ret = regmap_update_bits(adcx140->regmap, ADCX140_BIAS_CFG, 787 + ADCX140_MIC_BIAS_VAL_MSK | 788 + ADCX140_MIC_BIAS_VREF_MSK, bias_source); 789 + if (ret) 790 + dev_err(adcx140->dev, "setting MIC bias failed %d\n", ret); 791 + out: 792 + return ret; 793 + } 794 + 795 + static int adcx140_set_bias_level(struct snd_soc_component *component, 796 + enum snd_soc_bias_level level) 797 + { 798 + struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); 799 + int pwr_cfg = 0; 800 + 801 + switch (level) { 802 + case SND_SOC_BIAS_ON: 803 + case SND_SOC_BIAS_PREPARE: 804 + case SND_SOC_BIAS_STANDBY: 805 + pwr_cfg = ADCX140_PWR_CFG_BIAS_PDZ | ADCX140_PWR_CFG_PLL_PDZ | 806 + ADCX140_PWR_CFG_ADC_PDZ; 807 + break; 808 + case SND_SOC_BIAS_OFF: 809 + pwr_cfg = 0x0; 810 + break; 811 + } 812 + 813 + return regmap_write(adcx140->regmap, ADCX140_PWR_CFG, pwr_cfg); 814 + } 815 + 816 + static const struct snd_soc_component_driver soc_codec_driver_adcx140 = { 817 + .probe = adcx140_codec_probe, 818 + .set_bias_level = adcx140_set_bias_level, 819 + .controls = adcx140_snd_controls, 820 + .num_controls = ARRAY_SIZE(adcx140_snd_controls), 821 + .dapm_widgets = adcx140_dapm_widgets, 822 + .num_dapm_widgets = ARRAY_SIZE(adcx140_dapm_widgets), 823 + .dapm_routes = adcx140_audio_map, 824 + .num_dapm_routes = ARRAY_SIZE(adcx140_audio_map), 825 + .suspend_bias_off = 1, 826 + .idle_bias_on = 0, 827 + .use_pmdown_time = 1, 828 + .endianness = 1, 829 + .non_legacy_dai_naming = 1, 830 + }; 831 + 832 + static struct snd_soc_dai_driver adcx140_dai_driver[] = { 833 + { 834 + .name = "tlv320adcx140-codec", 835 + .capture = { 836 + .stream_name = "Capture", 837 + .channels_min = 2, 838 + .channels_max = ADCX140_MAX_CHANNELS, 839 + .rates = ADCX140_RATES, 840 + .formats = ADCX140_FORMATS, 841 + }, 842 + .ops = &adcx140_dai_ops, 843 + .symmetric_rates = 1, 844 + } 845 + }; 846 + 847 + static const struct of_device_id tlv320adcx140_of_match[] = { 848 + { .compatible = "ti,tlv320adc3140" }, 849 + { .compatible = "ti,tlv320adc5140" }, 850 + { .compatible = "ti,tlv320adc6140" }, 851 + {}, 852 + }; 853 + MODULE_DEVICE_TABLE(of, tlv320adcx140_of_match); 854 + 855 + static int adcx140_i2c_probe(struct i2c_client *i2c, 856 + const struct i2c_device_id *id) 857 + { 858 + struct adcx140_priv *adcx140; 859 + int ret; 860 + 861 + adcx140 = devm_kzalloc(&i2c->dev, sizeof(*adcx140), GFP_KERNEL); 862 + if (!adcx140) 863 + return -ENOMEM; 864 + 865 + adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, 866 + "reset", GPIOD_OUT_LOW); 867 + if (IS_ERR(adcx140->gpio_reset)) 868 + dev_info(&i2c->dev, "Reset GPIO not defined\n"); 869 + 870 + adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev, 871 + "areg"); 872 + if (IS_ERR(adcx140->supply_areg)) { 873 + if (PTR_ERR(adcx140->supply_areg) == -EPROBE_DEFER) 874 + return -EPROBE_DEFER; 875 + else 876 + adcx140->supply_areg = NULL; 877 + } else { 878 + ret = regulator_enable(adcx140->supply_areg); 879 + if (ret) { 880 + dev_err(adcx140->dev, "Failed to enable areg\n"); 881 + return ret; 882 + } 883 + } 884 + 885 + adcx140->regmap = devm_regmap_init_i2c(i2c, &adcx140_i2c_regmap); 886 + if (IS_ERR(adcx140->regmap)) { 887 + ret = PTR_ERR(adcx140->regmap); 888 + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 889 + ret); 890 + return ret; 891 + } 892 + adcx140->dev = &i2c->dev; 893 + i2c_set_clientdata(i2c, adcx140); 894 + 895 + return devm_snd_soc_register_component(&i2c->dev, 896 + &soc_codec_driver_adcx140, 897 + adcx140_dai_driver, 1); 898 + } 899 + 900 + static const struct i2c_device_id adcx140_i2c_id[] = { 901 + { "tlv320adc3140", 0 }, 902 + { "tlv320adc5140", 1 }, 903 + { "tlv320adc6140", 2 }, 904 + {} 905 + }; 906 + MODULE_DEVICE_TABLE(i2c, adcx140_i2c_id); 907 + 908 + static struct i2c_driver adcx140_i2c_driver = { 909 + .driver = { 910 + .name = "tlv320adcx140-codec", 911 + .of_match_table = of_match_ptr(tlv320adcx140_of_match), 912 + }, 913 + .probe = adcx140_i2c_probe, 914 + .id_table = adcx140_i2c_id, 915 + }; 916 + module_i2c_driver(adcx140_i2c_driver); 917 + 918 + MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 919 + MODULE_DESCRIPTION("ASoC TLV320ADCX140 CODEC Driver"); 920 + MODULE_LICENSE("GPL v2");
+131
sound/soc/codecs/tlv320adcx140.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // TLV320ADCX104 Sound driver 3 + // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 4 + 5 + #ifndef _TLV320ADCX140_H 6 + #define _TLV320ADCX140_H 7 + 8 + #define ADCX140_RATES (SNDRV_PCM_RATE_44100 | \ 9 + SNDRV_PCM_RATE_48000) 10 + 11 + #define ADCX140_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 12 + SNDRV_PCM_FMTBIT_S20_3LE | \ 13 + SNDRV_PCM_FMTBIT_S24_3LE | \ 14 + SNDRV_PCM_FMTBIT_S24_LE | \ 15 + SNDRV_PCM_FMTBIT_S32_LE) 16 + 17 + #define ADCX140_PAGE_SELECT 0x00 18 + #define ADCX140_SW_RESET 0x01 19 + #define ADCX140_SLEEP_CFG 0x02 20 + #define ADCX140_SHDN_CFG 0x05 21 + #define ADCX140_ASI_CFG0 0x07 22 + #define ADCX140_ASI_CFG1 0x08 23 + #define ADCX140_ASI_CFG2 0x09 24 + #define ADCX140_ASI_CH1 0x0b 25 + #define ADCX140_ASI_CH2 0x0c 26 + #define ADCX140_ASI_CH3 0x0d 27 + #define ADCX140_ASI_CH4 0x0e 28 + #define ADCX140_ASI_CH5 0x0f 29 + #define ADCX140_ASI_CH6 0x10 30 + #define ADCX140_ASI_CH7 0x11 31 + #define ADCX140_ASI_CH8 0x12 32 + #define ADCX140_MST_CFG0 0x13 33 + #define ADCX140_MST_CFG1 0x14 34 + #define ADCX140_ASI_STS 0x15 35 + #define ADCX140_CLK_SRC 0x16 36 + #define ADCX140_PDMCLK_CFG 0x1f 37 + #define ADCX140_PDM_CFG 0x20 38 + #define ADCX140_GPIO_CFG0 0x21 39 + #define ADCX140_GPO_CFG1 0x22 40 + #define ADCX140_GPO_CFG2 0x23 41 + #define ADCX140_GPO_CFG3 0x24 42 + #define ADCX140_GPO_CFG4 0x25 43 + #define ADCX140_GPO_VAL 0x29 44 + #define ADCX140_GPIO_MON 0x2a 45 + #define ADCX140_GPI_CFG0 0x2b 46 + #define ADCX140_GPI_CFG1 0x2c 47 + #define ADCX140_GPI_MON 0x2f 48 + #define ADCX140_INT_CFG 0x32 49 + #define ADCX140_INT_MASK0 0x33 50 + #define ADCX140_INT_LTCH0 0x36 51 + #define ADCX140_BIAS_CFG 0x3b 52 + #define ADCX140_CH1_CFG0 0x3c 53 + #define ADCX140_CH1_CFG1 0x3d 54 + #define ADCX140_CH1_CFG2 0x3e 55 + #define ADCX140_CH1_CFG3 0x3f 56 + #define ADCX140_CH1_CFG4 0x40 57 + #define ADCX140_CH2_CFG0 0x41 58 + #define ADCX140_CH2_CFG1 0x42 59 + #define ADCX140_CH2_CFG2 0x43 60 + #define ADCX140_CH2_CFG3 0x44 61 + #define ADCX140_CH2_CFG4 0x45 62 + #define ADCX140_CH3_CFG0 0x46 63 + #define ADCX140_CH3_CFG1 0x47 64 + #define ADCX140_CH3_CFG2 0x48 65 + #define ADCX140_CH3_CFG3 0x49 66 + #define ADCX140_CH3_CFG4 0x4a 67 + #define ADCX140_CH4_CFG0 0x4b 68 + #define ADCX140_CH4_CFG1 0x4c 69 + #define ADCX140_CH4_CFG2 0x4d 70 + #define ADCX140_CH4_CFG3 0x4e 71 + #define ADCX140_CH4_CFG4 0x4f 72 + #define ADCX140_CH5_CFG2 0x52 73 + #define ADCX140_CH5_CFG3 0x53 74 + #define ADCX140_CH5_CFG4 0x54 75 + #define ADCX140_CH6_CFG2 0x57 76 + #define ADCX140_CH6_CFG3 0x58 77 + #define ADCX140_CH6_CFG4 0x59 78 + #define ADCX140_CH7_CFG2 0x5c 79 + #define ADCX140_CH7_CFG3 0x5d 80 + #define ADCX140_CH7_CFG4 0x5e 81 + #define ADCX140_CH8_CFG2 0x61 82 + #define ADCX140_CH8_CFG3 0x62 83 + #define ADCX140_CH8_CFG4 0x63 84 + #define ADCX140_DSP_CFG0 0x6b 85 + #define ADCX140_DSP_CFG1 0x6c 86 + #define ADCX140_DRE_CFG0 0x6d 87 + #define ADCX140_AGC_CFG0 0x70 88 + #define ADCX140_IN_CH_EN 0x73 89 + #define ADCX140_ASI_OUT_CH_EN 0x74 90 + #define ADCX140_PWR_CFG 0x75 91 + #define ADCX140_DEV_STS0 0x76 92 + #define ADCX140_DEV_STS1 0x77 93 + 94 + #define ADCX140_RESET BIT(0) 95 + 96 + #define ADCX140_WAKE_DEV BIT(0) 97 + #define ADCX140_AREG_INTERNAL BIT(7) 98 + 99 + #define ADCX140_BCLKINV_BIT BIT(2) 100 + #define ADCX140_FSYNCINV_BIT BIT(3) 101 + #define ADCX140_INV_MSK (ADCX140_BCLKINV_BIT | ADCX140_FSYNCINV_BIT) 102 + #define ADCX140_BCLK_FSYNC_MASTER BIT(7) 103 + #define ADCX140_I2S_MODE_BIT BIT(6) 104 + #define ADCX140_LEFT_JUST_BIT BIT(7) 105 + #define ADCX140_ASI_FORMAT_MSK (ADCX140_I2S_MODE_BIT | ADCX140_LEFT_JUST_BIT) 106 + 107 + #define ADCX140_16_BIT_WORD 0x0 108 + #define ADCX140_20_BIT_WORD BIT(4) 109 + #define ADCX140_24_BIT_WORD BIT(5) 110 + #define ADCX140_32_BIT_WORD (BIT(4) | BIT(5)) 111 + #define ADCX140_WORD_LEN_MSK 0x30 112 + 113 + #define ADCX140_MAX_CHANNELS 8 114 + 115 + #define ADCX140_MIC_BIAS_VAL_VREF 0 116 + #define ADCX140_MIC_BIAS_VAL_VREF_1096 1 117 + #define ADCX140_MIC_BIAS_VAL_AVDD 6 118 + #define ADCX140_MIC_BIAS_VAL_MSK GENMASK(6, 4) 119 + 120 + #define ADCX140_MIC_BIAS_VREF_275V 0 121 + #define ADCX140_MIC_BIAS_VREF_25V 1 122 + #define ADCX140_MIC_BIAS_VREF_1375V 2 123 + #define ADCX140_MIC_BIAS_VREF_MSK GENMASK(1, 0) 124 + 125 + #define ADCX140_PWR_CFG_BIAS_PDZ BIT(7) 126 + #define ADCX140_PWR_CFG_ADC_PDZ BIT(6) 127 + #define ADCX140_PWR_CFG_PLL_PDZ BIT(5) 128 + 129 + #define ADCX140_TX_OFFSET_MASK GENMASK(4, 0) 130 + 131 + #endif /* _TLV320ADCX140_ */
+9 -9
sound/soc/codecs/wcd9335.c
··· 4926 4926 .name = "WCD9335", 4927 4927 .range_min = 0x0, 4928 4928 .range_max = WCD9335_MAX_REGISTER, 4929 - .selector_reg = WCD9335_REG(0x0, 0), 4929 + .selector_reg = WCD9335_SEL_REGISTER, 4930 4930 .selector_mask = 0xff, 4931 4931 .selector_shift = 0, 4932 - .window_start = 0x0, 4933 - .window_len = 0x1000, 4932 + .window_start = 0x800, 4933 + .window_len = 0x100, 4934 4934 }, 4935 4935 }; 4936 4936 ··· 4968 4968 { 4969 4969 .name = "WCD9335-IFC-DEV", 4970 4970 .range_min = 0x0, 4971 - .range_max = WCD9335_REG(0, 0x7ff), 4972 - .selector_reg = WCD9335_REG(0, 0x0), 4973 - .selector_mask = 0xff, 4971 + .range_max = WCD9335_MAX_REGISTER, 4972 + .selector_reg = WCD9335_SEL_REGISTER, 4973 + .selector_mask = 0xfff, 4974 4974 .selector_shift = 0, 4975 - .window_start = 0x0, 4976 - .window_len = 0x1000, 4975 + .window_start = 0x800, 4976 + .window_len = 0x400, 4977 4977 }, 4978 4978 }; 4979 4979 ··· 4981 4981 .reg_bits = 16, 4982 4982 .val_bits = 8, 4983 4983 .can_multi_write = true, 4984 - .max_register = WCD9335_REG(0, 0x7FF), 4984 + .max_register = WCD9335_MAX_REGISTER, 4985 4985 .ranges = wcd9335_ifc_ranges, 4986 4986 .num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges), 4987 4987 };
+4 -3
sound/soc/codecs/wcd9335.h
··· 8 8 * in slimbus mode the reg base starts from 0x800 9 9 * in i2s/i2c mode the reg base is 0x0 10 10 */ 11 - #define WCD9335_REG(pg, r) ((pg << 12) | (r) | 0x800) 11 + #define WCD9335_REG(pg, r) ((pg << 8) | (r)) 12 12 #define WCD9335_REG_OFFSET(r) (r & 0xFF) 13 - #define WCD9335_PAGE_OFFSET(r) ((r >> 12) & 0xFF) 13 + #define WCD9335_PAGE_OFFSET(r) ((r >> 8) & 0xFF) 14 14 15 15 /* Page-0 Registers */ 16 16 #define WCD9335_PAGE0_PAGE_REGISTER WCD9335_REG(0x00, 0x000) ··· 600 600 #define WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE BIT(0) 601 601 #define WCD9335_CDC_CLK_RST_CTRL_FS_CNT_DISABLE 0 602 602 #define WCD9335_CDC_TOP_TOP_CFG1 WCD9335_REG(0x0d, 0x082) 603 - #define WCD9335_MAX_REGISTER WCD9335_REG(0x80, 0x0FF) 603 + #define WCD9335_MAX_REGISTER 0xffff 604 + #define WCD9335_SEL_REGISTER 0x800 604 605 605 606 /* SLIMBUS Slave Registers */ 606 607 #define WCD9335_SLIM_PGD_PORT_INT_EN0 WCD9335_REG(0, 0x30)
+13 -24
sound/soc/codecs/wcd934x.c
··· 3 3 4 4 #include <linux/clk.h> 5 5 #include <linux/clk-provider.h> 6 - #include <linux/gpio.h> 7 6 #include <linux/interrupt.h> 8 7 #include <linux/kernel.h> 9 8 #include <linux/mfd/wcd934x/registers.h> ··· 10 11 #include <linux/module.h> 11 12 #include <linux/mutex.h> 12 13 #include <linux/of_clk.h> 13 - #include <linux/of_device.h> 14 - #include <linux/of_gpio.h> 15 14 #include <linux/of.h> 16 - #include <linux/of_irq.h> 17 15 #include <linux/platform_device.h> 18 16 #include <linux/regmap.h> 19 17 #include <linux/regulator/consumer.h> ··· 1198 1202 regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO, 1199 1203 WCD934X_ANA_RCO_BG_EN_MASK, 0); 1200 1204 usleep_range(100, 110); 1201 - } else if (sido_src == SIDO_SOURCE_RCO_BG) { 1202 - regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO, 1203 - WCD934X_ANA_RCO_BG_EN_MASK, 1204 - WCD934X_ANA_RCO_BG_ENABLE); 1205 - usleep_range(100, 110); 1206 1205 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, 1207 1206 WCD934X_ANA_BUCK_PRE_EN1_MASK, 1208 1207 WCD934X_ANA_BUCK_PRE_EN1_ENABLE); ··· 1209 1218 regmap_update_bits(wcd->regmap, WCD934X_ANA_BUCK_CTL, 1210 1219 WCD934X_ANA_BUCK_HI_ACCU_EN_MASK, 1211 1220 WCD934X_ANA_BUCK_HI_ACCU_ENABLE); 1221 + usleep_range(100, 110); 1222 + } else if (sido_src == SIDO_SOURCE_RCO_BG) { 1223 + regmap_update_bits(wcd->regmap, WCD934X_ANA_RCO, 1224 + WCD934X_ANA_RCO_BG_EN_MASK, 1225 + WCD934X_ANA_RCO_BG_ENABLE); 1212 1226 usleep_range(100, 110); 1213 1227 } 1214 1228 wcd->sido_input_src = sido_src; ··· 1879 1883 return -EINVAL; 1880 1884 } 1881 1885 1882 - if (wcd->rx_chs) { 1883 - wcd->num_rx_port = rx_num; 1884 - for (i = 0; i < rx_num; i++) { 1885 - wcd->rx_chs[i].ch_num = rx_slot[i]; 1886 - INIT_LIST_HEAD(&wcd->rx_chs[i].list); 1887 - } 1886 + wcd->num_rx_port = rx_num; 1887 + for (i = 0; i < rx_num; i++) { 1888 + wcd->rx_chs[i].ch_num = rx_slot[i]; 1889 + INIT_LIST_HEAD(&wcd->rx_chs[i].list); 1888 1890 } 1889 1891 1890 - if (wcd->tx_chs) { 1891 - wcd->num_tx_port = tx_num; 1892 - for (i = 0; i < tx_num; i++) { 1893 - wcd->tx_chs[i].ch_num = tx_slot[i]; 1894 - INIT_LIST_HEAD(&wcd->tx_chs[i].list); 1895 - } 1892 + wcd->num_tx_port = tx_num; 1893 + for (i = 0; i < tx_num; i++) { 1894 + wcd->tx_chs[i].ch_num = tx_slot[i]; 1895 + INIT_LIST_HEAD(&wcd->tx_chs[i].list); 1896 1896 } 1897 1897 1898 1898 return 0; ··· 3384 3392 { 3385 3393 u8 hph_dly_mask; 3386 3394 u16 hph_lut_bypass_reg = 0; 3387 - u16 hph_comp_ctrl7 = 0; 3388 3395 3389 3396 switch (interp_idx) { 3390 3397 case INTERP_HPHL: 3391 3398 hph_dly_mask = 1; 3392 3399 hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHL_COMP_LUT; 3393 - hph_comp_ctrl7 = WCD934X_CDC_COMPANDER1_CTL7; 3394 3400 break; 3395 3401 case INTERP_HPHR: 3396 3402 hph_dly_mask = 2; 3397 3403 hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHR_COMP_LUT; 3398 - hph_comp_ctrl7 = WCD934X_CDC_COMPANDER2_CTL7; 3399 3404 break; 3400 3405 default: 3401 3406 return;
+1 -1
sound/soc/codecs/wm0010.c
··· 43 43 u8 command; 44 44 u32 length:24; 45 45 u32 address; 46 - uint8_t data[0]; 46 + uint8_t data[]; 47 47 } __packed; 48 48 49 49 struct dfw_inforec {
+3 -3
sound/soc/codecs/wm5110.c
··· 2245 2245 struct arizona *arizona = priv->core.arizona; 2246 2246 int n_adsp; 2247 2247 2248 - if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) { 2248 + if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "wm5110-dsp-voicectrl") == 0) { 2249 2249 n_adsp = 2; 2250 - } else if (strcmp(rtd->codec_dai->name, "wm5110-dsp-trace") == 0) { 2250 + } else if (strcmp(asoc_rtd_to_codec(rtd, 0)->name, "wm5110-dsp-trace") == 0) { 2251 2251 n_adsp = 0; 2252 2252 } else { 2253 2253 dev_err(arizona->dev, 2254 2254 "No suitable compressed stream for DAI '%s'\n", 2255 - rtd->codec_dai->name); 2255 + asoc_rtd_to_codec(rtd, 0)->name); 2256 2256 return -EINVAL; 2257 2257 } 2258 2258
-8
sound/soc/codecs/wm8974.c
··· 196 196 SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0), 197 197 }; 198 198 199 - /* AUX Input boost vol */ 200 - static const struct snd_kcontrol_new wm8974_aux_boost_controls = 201 - SOC_DAPM_SINGLE("Aux Volume", WM8974_ADCBOOST, 0, 7, 0); 202 - 203 - /* Mic Input boost vol */ 204 - static const struct snd_kcontrol_new wm8974_mic_boost_controls = 205 - SOC_DAPM_SINGLE("Mic Volume", WM8974_ADCBOOST, 4, 7, 0); 206 - 207 199 static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = { 208 200 SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0, 209 201 &wm8974_speaker_mixer_controls[0],
+7 -7
sound/soc/codecs/wm_adsp.c
··· 1436 1436 subname = NULL; /* don't append subname */ 1437 1437 break; 1438 1438 case 2: 1439 - ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1439 + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1440 1440 "%s%c %.12s %x", dsp->name, *region_name, 1441 1441 wm_adsp_fw_text[dsp->fw], alg_region->alg); 1442 1442 break; 1443 1443 default: 1444 - ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1444 + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1445 1445 "%s %.12s %x", dsp->name, 1446 1446 wm_adsp_fw_text[dsp->fw], alg_region->alg); 1447 1447 break; ··· 3467 3467 3468 3468 if (wm_adsp_fw[dsp->fw].num_caps == 0) { 3469 3469 adsp_err(dsp, "%s: Firmware does not support compressed API\n", 3470 - rtd->codec_dai->name); 3470 + asoc_rtd_to_codec(rtd, 0)->name); 3471 3471 ret = -ENXIO; 3472 3472 goto out; 3473 3473 } 3474 3474 3475 3475 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { 3476 3476 adsp_err(dsp, "%s: Firmware does not support stream direction\n", 3477 - rtd->codec_dai->name); 3477 + asoc_rtd_to_codec(rtd, 0)->name); 3478 3478 ret = -EINVAL; 3479 3479 goto out; 3480 3480 } 3481 3481 3482 3482 list_for_each_entry(tmp, &dsp->compr_list, list) { 3483 - if (!strcmp(tmp->name, rtd->codec_dai->name)) { 3483 + if (!strcmp(tmp->name, asoc_rtd_to_codec(rtd, 0)->name)) { 3484 3484 adsp_err(dsp, "%s: Only a single stream supported per dai\n", 3485 - rtd->codec_dai->name); 3485 + asoc_rtd_to_codec(rtd, 0)->name); 3486 3486 ret = -EBUSY; 3487 3487 goto out; 3488 3488 } ··· 3496 3496 3497 3497 compr->dsp = dsp; 3498 3498 compr->stream = stream; 3499 - compr->name = rtd->codec_dai->name; 3499 + compr->name = asoc_rtd_to_codec(rtd, 0)->name; 3500 3500 3501 3501 list_add_tail(&compr->list, &dsp->compr_list); 3502 3502
+2 -44
sound/soc/codecs/wsa881x.c
··· 676 676 int active_ports; 677 677 bool port_prepared[WSA881X_MAX_SWR_PORTS]; 678 678 bool port_enable[WSA881X_MAX_SWR_PORTS]; 679 - bool stream_prepared; 680 679 }; 681 680 682 681 static void wsa881x_init(struct wsa881x_priv *wsa881x) ··· 953 954 SND_SOC_DAPM_OUTPUT("SPKR"), 954 955 }; 955 956 956 - static int wsa881x_prepare(struct snd_pcm_substream *substream, 957 - struct snd_soc_dai *dai) 958 - { 959 - struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev); 960 - int ret; 961 - 962 - if (wsa881x->stream_prepared) { 963 - sdw_disable_stream(wsa881x->sruntime); 964 - sdw_deprepare_stream(wsa881x->sruntime); 965 - wsa881x->stream_prepared = false; 966 - } 967 - 968 - 969 - ret = sdw_prepare_stream(wsa881x->sruntime); 970 - if (ret) 971 - return ret; 972 - 973 - /** 974 - * NOTE: there is a strict hw requirement about the ordering of port 975 - * enables and actual PA enable. PA enable should only happen after 976 - * soundwire ports are enabled if not DC on the line is accumulated 977 - * resulting in Click/Pop Noise 978 - * PA enable/mute are handled as part of DAPM and digital mute. 979 - */ 980 - 981 - ret = sdw_enable_stream(wsa881x->sruntime); 982 - if (ret) { 983 - sdw_deprepare_stream(wsa881x->sruntime); 984 - return ret; 985 - } 986 - wsa881x->stream_prepared = true; 987 - 988 - return ret; 989 - } 990 - 991 957 static int wsa881x_hw_params(struct snd_pcm_substream *substream, 992 958 struct snd_pcm_hw_params *params, 993 959 struct snd_soc_dai *dai) ··· 980 1016 { 981 1017 struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev); 982 1018 983 - if (wsa881x->stream_prepared) { 984 - sdw_disable_stream(wsa881x->sruntime); 985 - sdw_deprepare_stream(wsa881x->sruntime); 986 - sdw_stream_remove_slave(wsa881x->slave, wsa881x->sruntime); 987 - wsa881x->stream_prepared = false; 988 - } 1019 + sdw_stream_remove_slave(wsa881x->slave, wsa881x->sruntime); 989 1020 990 1021 return 0; 991 1022 } ··· 1011 1052 1012 1053 static struct snd_soc_dai_ops wsa881x_dai_ops = { 1013 1054 .hw_params = wsa881x_hw_params, 1014 - .prepare = wsa881x_prepare, 1015 1055 .hw_free = wsa881x_hw_free, 1016 1056 .mute_stream = wsa881x_digital_mute, 1017 1057 .set_sdw_stream = wsa881x_set_sdw_stream, ··· 1108 1150 wsa881x->sconfig.type = SDW_STREAM_PDM; 1109 1151 pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0); 1110 1152 pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; 1111 - gpiod_set_value(wsa881x->sd_n, 1); 1153 + gpiod_direction_output(wsa881x->sd_n, 1); 1112 1154 1113 1155 wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config); 1114 1156 if (IS_ERR(wsa881x->regmap)) {
+4 -4
sound/soc/dwc/dwc-i2s.c
··· 422 422 { 423 423 struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component); 424 424 struct snd_soc_dai *dai; 425 + int stream; 425 426 426 427 if (dev->capability & DW_I2S_MASTER) 427 428 clk_enable(dev->clk); 428 429 429 430 for_each_component_dais(component, dai) { 430 - if (dai->playback_active) 431 - dw_i2s_config(dev, SNDRV_PCM_STREAM_PLAYBACK); 432 - if (dai->capture_active) 433 - dw_i2s_config(dev, SNDRV_PCM_STREAM_CAPTURE); 431 + for_each_pcm_streams(stream) 432 + if (dai->stream_active[stream]) 433 + dw_i2s_config(dev, stream); 434 434 } 435 435 436 436 return 0;
+1 -1
sound/soc/dwc/dwc-pcm.c
··· 140 140 { 141 141 struct snd_pcm_runtime *runtime = substream->runtime; 142 142 struct snd_soc_pcm_runtime *rtd = substream->private_data; 143 - struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai); 143 + struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 144 144 145 145 snd_soc_set_runtime_hwparams(substream, &dw_pcm_hardware); 146 146 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+2 -2
sound/soc/fsl/eukrea-tlv320.c
··· 31 31 struct snd_pcm_hw_params *params) 32 32 { 33 33 struct snd_soc_pcm_runtime *rtd = substream->private_data; 34 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 35 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 34 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 35 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 36 36 int ret; 37 37 38 38 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+5 -5
sound/soc/fsl/fsl-asoc-card.c
··· 159 159 return 0; 160 160 161 161 /* Specific configurations of DAIs starts from here */ 162 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, cpu_priv->sysclk_id[tx], 162 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), cpu_priv->sysclk_id[tx], 163 163 cpu_priv->sysclk_freq[tx], 164 164 cpu_priv->sysclk_dir[tx]); 165 165 if (ret && ret != -ENOTSUPP) { ··· 168 168 } 169 169 170 170 if (cpu_priv->slot_width) { 171 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 171 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 172 172 cpu_priv->slot_width); 173 173 if (ret && ret != -ENOTSUPP) { 174 174 dev_err(dev, "failed to set TDM slot for cpu dai\n"); ··· 257 257 int ret; 258 258 259 259 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 260 - codec_dai = rtd->codec_dai; 260 + codec_dai = asoc_rtd_to_codec(rtd, 0); 261 261 if (dapm->dev != codec_dai->dev) 262 262 return 0; 263 263 ··· 446 446 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 447 447 struct snd_soc_pcm_runtime *rtd = list_first_entry( 448 448 &card->rtd_list, struct snd_soc_pcm_runtime, list); 449 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 449 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 450 450 struct codec_priv *codec_priv = &priv->codec_priv; 451 451 struct device *dev = card->dev; 452 452 int ret; 453 453 454 454 if (fsl_asoc_card_is_ac97(priv)) { 455 455 #if IS_ENABLED(CONFIG_SND_AC97_CODEC) 456 - struct snd_soc_component *component = rtd->codec_dai->component; 456 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 457 457 struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component); 458 458 459 459 /*
+5 -5
sound/soc/fsl/fsl_asrc_dma.c
··· 152 152 for_each_dpcm_be(rtd, stream, dpcm) { 153 153 struct snd_soc_pcm_runtime *be = dpcm->be; 154 154 struct snd_pcm_substream *substream_be; 155 - struct snd_soc_dai *dai = be->cpu_dai; 155 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(be, 0); 156 156 157 157 if (dpcm->fe != rtd) 158 158 continue; ··· 169 169 } 170 170 171 171 /* Override dma_data of the Front-End and config its dmaengine */ 172 - dma_params_fe = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 172 + dma_params_fe = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 173 173 dma_params_fe->addr = asrc_priv->paddr + REG_ASRDx(!dir, index); 174 174 dma_params_fe->maxburst = dma_params_be->maxburst; 175 175 ··· 328 328 goto dma_chan_err; 329 329 } 330 330 331 - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 331 + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 332 332 333 333 /* Refine the snd_imx_hardware according to caps of DMA. */ 334 334 ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream, ··· 400 400 return ret; 401 401 } 402 402 403 - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_LAST; i++) { 403 + for_each_pcm_streams(i) { 404 404 substream = pcm->streams[i].substream; 405 405 if (!substream) 406 406 continue; ··· 428 428 struct snd_pcm_substream *substream; 429 429 int i; 430 430 431 - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_LAST; i++) { 431 + for_each_pcm_streams(i) { 432 432 substream = pcm->streams[i].substream; 433 433 if (!substream) 434 434 continue;
+5 -5
sound/soc/fsl/fsl_spdif.c
··· 370 370 int sample_rate) 371 371 { 372 372 struct snd_soc_pcm_runtime *rtd = substream->private_data; 373 - struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 373 + struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 374 374 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; 375 375 struct regmap *regmap = spdif_priv->regmap; 376 376 struct platform_device *pdev = spdif_priv->pdev; ··· 458 458 struct snd_soc_dai *cpu_dai) 459 459 { 460 460 struct snd_soc_pcm_runtime *rtd = substream->private_data; 461 - struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 461 + struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 462 462 struct platform_device *pdev = spdif_priv->pdev; 463 463 struct regmap *regmap = spdif_priv->regmap; 464 464 u32 scr, mask; ··· 534 534 struct snd_soc_dai *cpu_dai) 535 535 { 536 536 struct snd_soc_pcm_runtime *rtd = substream->private_data; 537 - struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 537 + struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 538 538 struct regmap *regmap = spdif_priv->regmap; 539 539 u32 scr, mask, i; 540 540 ··· 569 569 struct snd_soc_dai *dai) 570 570 { 571 571 struct snd_soc_pcm_runtime *rtd = substream->private_data; 572 - struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 572 + struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 573 573 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; 574 574 struct platform_device *pdev = spdif_priv->pdev; 575 575 u32 sample_rate = params_rate(params); ··· 597 597 int cmd, struct snd_soc_dai *dai) 598 598 { 599 599 struct snd_soc_pcm_runtime *rtd = substream->private_data; 600 - struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 600 + struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 601 601 struct regmap *regmap = spdif_priv->regmap; 602 602 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 603 603 u32 intr = SIE_INTR_FOR(tx);
+4 -4
sound/soc/fsl/fsl_ssi.c
··· 631 631 struct snd_soc_dai *dai) 632 632 { 633 633 struct snd_soc_pcm_runtime *rtd = substream->private_data; 634 - struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); 634 + struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 635 635 int ret; 636 636 637 637 ret = clk_prepare_enable(ssi->clk); ··· 655 655 struct snd_soc_dai *dai) 656 656 { 657 657 struct snd_soc_pcm_runtime *rtd = substream->private_data; 658 - struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); 658 + struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 659 659 660 660 clk_disable_unprepare(ssi->clk); 661 661 } ··· 854 854 struct snd_soc_dai *dai) 855 855 { 856 856 struct snd_soc_pcm_runtime *rtd = substream->private_data; 857 - struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); 857 + struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 858 858 859 859 if (fsl_ssi_is_i2s_master(ssi) && 860 860 ssi->baudclk_streams & BIT(substream->stream)) { ··· 1059 1059 struct snd_soc_dai *dai) 1060 1060 { 1061 1061 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1062 - struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); 1062 + struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 1063 1063 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 1064 1064 1065 1065 switch (cmd) {
+4 -4
sound/soc/fsl/imx-audmix.c
··· 85 85 dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; 86 86 87 87 /* set DAI configuration */ 88 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt); 88 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); 89 89 if (ret) { 90 90 dev_err(dev, "failed to set cpu dai fmt: %d\n", ret); 91 91 return ret; 92 92 } 93 93 94 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, FSL_SAI_CLK_MAST1, 0, dir); 94 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), FSL_SAI_CLK_MAST1, 0, dir); 95 95 if (ret) { 96 96 dev_err(dev, "failed to set cpu sysclk: %d\n", ret); 97 97 return ret; ··· 101 101 * Per datasheet, AUDMIX expects 8 slots and 32 bits 102 102 * for every slot in TDM mode. 103 103 */ 104 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, BIT(channels) - 1, 104 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), BIT(channels) - 1, 105 105 BIT(channels) - 1, 8, 32); 106 106 if (ret) 107 107 dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret); ··· 125 125 fmt |= SND_SOC_DAIFMT_CBM_CFM; 126 126 127 127 /* set AUDMIX DAI configuration */ 128 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt); 128 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); 129 129 if (ret) 130 130 dev_err(dev, "failed to set AUDMIX DAI fmt: %d\n", ret); 131 131
+2 -2
sound/soc/fsl/imx-mc13783.c
··· 27 27 struct snd_pcm_hw_params *params) 28 28 { 29 29 struct snd_soc_pcm_runtime *rtd = substream->private_data; 30 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 31 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 30 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 31 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 32 32 int ret; 33 33 34 34 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 4, 16);
+1 -1
sound/soc/fsl/imx-sgtl5000.c
··· 30 30 struct device *dev = rtd->card->dev; 31 31 int ret; 32 32 33 - ret = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK, 33 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), SGTL5000_SYSCLK, 34 34 data->clk_frequency, SND_SOC_CLOCK_IN); 35 35 if (ret) { 36 36 dev_err(dev, "could not set codec driver clock params\n");
+5 -5
sound/soc/fsl/mpc5200_dma.c
··· 115 115 struct snd_pcm_substream *substream, int cmd) 116 116 { 117 117 struct snd_soc_pcm_runtime *rtd = substream->private_data; 118 - struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai); 118 + struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 119 119 struct snd_pcm_runtime *runtime = substream->runtime; 120 120 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); 121 121 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; ··· 217 217 { 218 218 struct snd_pcm_runtime *runtime = substream->runtime; 219 219 struct snd_soc_pcm_runtime *rtd = substream->private_data; 220 - struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai); 220 + struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 221 221 struct psc_dma_stream *s; 222 222 int rc; 223 223 ··· 245 245 struct snd_pcm_substream *substream) 246 246 { 247 247 struct snd_soc_pcm_runtime *rtd = substream->private_data; 248 - struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai); 248 + struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 249 249 struct psc_dma_stream *s; 250 250 251 251 dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream); ··· 271 271 struct snd_pcm_substream *substream) 272 272 { 273 273 struct snd_soc_pcm_runtime *rtd = substream->private_data; 274 - struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai); 274 + struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 275 275 struct psc_dma_stream *s; 276 276 dma_addr_t count; 277 277 ··· 298 298 struct snd_soc_pcm_runtime *rtd) 299 299 { 300 300 struct snd_card *card = rtd->card->snd_card; 301 - struct snd_soc_dai *dai = rtd->cpu_dai; 301 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 302 302 struct snd_pcm *pcm = rtd->pcm; 303 303 size_t size = psc_dma_hardware.buffer_bytes_max; 304 304 int rc;
+1 -1
sound/soc/fsl/mpc5200_psc_i2s.c
··· 39 39 struct snd_soc_dai *dai) 40 40 { 41 41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 - struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai); 42 + struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 43 43 u32 mode; 44 44 45 45 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
+2 -2
sound/soc/fsl/mpc8610_hpcd.c
··· 105 105 int ret = 0; 106 106 107 107 /* Tell the codec driver what the serial protocol is. */ 108 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, machine_data->dai_format); 108 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), machine_data->dai_format); 109 109 if (ret < 0) { 110 110 dev_err(dev, "could not set codec driver audio format\n"); 111 111 return ret; ··· 115 115 * Tell the codec driver what the MCLK frequency is, and whether it's 116 116 * a slave or master. 117 117 */ 118 - ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, 118 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), 0, 119 119 machine_data->clk_frequency, 120 120 machine_data->codec_clk_direction); 121 121 if (ret < 0) {
+2 -2
sound/soc/fsl/mx27vis-aic32x4.c
··· 37 37 struct snd_pcm_hw_params *params) 38 38 { 39 39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 41 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 40 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 41 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 42 42 int ret; 43 43 44 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+2 -2
sound/soc/fsl/p1022_ds.c
··· 128 128 int ret = 0; 129 129 130 130 /* Tell the codec driver what the serial protocol is. */ 131 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format); 131 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), mdata->dai_format); 132 132 if (ret < 0) { 133 133 dev_err(dev, "could not set codec driver audio format\n"); 134 134 return ret; ··· 138 138 * Tell the codec driver what the MCLK frequency is, and whether it's 139 139 * a slave or master. 140 140 */ 141 - ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, mdata->clk_frequency, 141 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), 0, mdata->clk_frequency, 142 142 mdata->codec_clk_direction); 143 143 if (ret < 0) { 144 144 dev_err(dev, "could not set codec driver clock params\n");
+2 -2
sound/soc/fsl/p1022_rdk.c
··· 134 134 int ret = 0; 135 135 136 136 /* Tell the codec driver what the serial protocol is. */ 137 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format); 137 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), mdata->dai_format); 138 138 if (ret < 0) { 139 139 dev_err(dev, "could not set codec driver audio format (ret=%i)\n", 140 140 ret); 141 141 return ret; 142 142 } 143 143 144 - ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, mdata->clk_frequency, 144 + ret = snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 0, 0, mdata->clk_frequency, 145 145 mdata->clk_frequency); 146 146 if (ret < 0) { 147 147 dev_err(dev, "could not set codec PLL frequency (ret=%i)\n",
+3 -3
sound/soc/fsl/wm1133-ev1.c
··· 76 76 struct snd_pcm_hw_params *params) 77 77 { 78 78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 80 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 79 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 80 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 81 81 int i, found = 0; 82 82 snd_pcm_format_t format = params_format(params); 83 83 unsigned int rate = params_rate(params); ··· 196 196 197 197 static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) 198 198 { 199 - struct snd_soc_component *component = rtd->codec_dai->component; 199 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 200 200 201 201 /* Headphone jack detection */ 202 202 snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
+54 -6
sound/soc/generic/simple-card-utils.c
··· 213 213 void asoc_simple_shutdown(struct snd_pcm_substream *substream) 214 214 { 215 215 struct snd_soc_pcm_runtime *rtd = substream->private_data; 216 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 217 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 216 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 217 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 218 218 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); 219 219 struct simple_dai_props *dai_props = 220 220 simple_priv_to_props(priv, rtd->num); ··· 249 249 struct snd_pcm_hw_params *params) 250 250 { 251 251 struct snd_soc_pcm_runtime *rtd = substream->private_data; 252 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 253 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 252 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 253 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 254 254 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); 255 255 struct simple_dai_props *dai_props = 256 256 simple_priv_to_props(priv, rtd->num); ··· 331 331 return 0; 332 332 } 333 333 334 + static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd, 335 + struct simple_dai_props *dai_props) 336 + { 337 + struct snd_soc_dai_link *dai_link = rtd->dai_link; 338 + struct snd_soc_component *component; 339 + struct snd_soc_pcm_stream *params; 340 + struct snd_pcm_hardware hw; 341 + int i, ret, stream; 342 + 343 + /* Only codecs should have non_legacy_dai_naming set. */ 344 + for_each_rtd_components(rtd, i, component) { 345 + if (!component->driver->non_legacy_dai_naming) 346 + return 0; 347 + } 348 + 349 + /* Assumes the capabilities are the same for all supported streams */ 350 + for_each_pcm_streams(stream) { 351 + ret = snd_soc_runtime_calc_hw(rtd, &hw, stream); 352 + if (ret == 0) 353 + break; 354 + } 355 + 356 + if (ret < 0) { 357 + dev_err(rtd->dev, "simple-card: no valid dai_link params\n"); 358 + return ret; 359 + } 360 + 361 + params = devm_kzalloc(rtd->dev, sizeof(*params), GFP_KERNEL); 362 + if (!params) 363 + return -ENOMEM; 364 + 365 + params->formats = hw.formats; 366 + params->rates = hw.rates; 367 + params->rate_min = hw.rate_min; 368 + params->rate_max = hw.rate_max; 369 + params->channels_min = hw.channels_min; 370 + params->channels_max = hw.channels_max; 371 + 372 + dai_link->params = params; 373 + dai_link->num_params = 1; 374 + 375 + return 0; 376 + } 377 + 334 378 int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd) 335 379 { 336 380 struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card); 337 381 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num); 338 382 int ret; 339 383 340 - ret = asoc_simple_init_dai(rtd->codec_dai, 384 + ret = asoc_simple_init_dai(asoc_rtd_to_codec(rtd, 0), 341 385 dai_props->codec_dai); 342 386 if (ret < 0) 343 387 return ret; 344 388 345 - ret = asoc_simple_init_dai(rtd->cpu_dai, 389 + ret = asoc_simple_init_dai(asoc_rtd_to_cpu(rtd, 0), 346 390 dai_props->cpu_dai); 391 + if (ret < 0) 392 + return ret; 393 + 394 + ret = asoc_simple_init_dai_link_params(rtd, dai_props); 347 395 if (ret < 0) 348 396 return ret; 349 397
+1 -1
sound/soc/img/img-i2s-in.c
··· 397 397 struct snd_dmaengine_dai_dma_data *dma_data; 398 398 int ret; 399 399 400 - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st); 400 + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), st); 401 401 402 402 ret = snd_hwparams_to_dma_slave_config(st, params, sc); 403 403 if (ret)
+1 -1
sound/soc/img/img-i2s-out.c
··· 403 403 struct snd_dmaengine_dai_dma_data *dma_data; 404 404 int ret; 405 405 406 - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st); 406 + dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), st); 407 407 408 408 ret = snd_hwparams_to_dma_slave_config(st, params, sc); 409 409 if (ret)
+1 -1
sound/soc/intel/atom/sst-atom-controls.c
··· 1333 1333 dai->capture_widget->name); 1334 1334 w = dai->capture_widget; 1335 1335 snd_soc_dapm_widget_for_each_source_path(w, p) { 1336 - if (p->connected && !p->connected(w, p->sink)) 1336 + if (p->connected && !p->connected(w, p->source)) 1337 1337 continue; 1338 1338 1339 1339 if (p->connect && p->source->power &&
+3 -3
sound/soc/intel/atom/sst-mfld-platform-pcm.c
··· 649 649 static int sst_soc_pcm_new(struct snd_soc_component *component, 650 650 struct snd_soc_pcm_runtime *rtd) 651 651 { 652 - struct snd_soc_dai *dai = rtd->cpu_dai; 652 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 653 653 struct snd_pcm *pcm = rtd->pcm; 654 654 655 655 if (dai->driver->playback.channels_min || ··· 741 741 742 742 /* set the SSPs to idle */ 743 743 for_each_card_rtds(drv->soc_card, rtd) { 744 - struct snd_soc_dai *dai = rtd->cpu_dai; 744 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 745 745 746 746 if (dai->active) { 747 747 send_ssp_cmd(dai, dai->name, 0); ··· 762 762 763 763 /* restart SSPs */ 764 764 for_each_card_rtds(drv->soc_card, rtd) { 765 - struct snd_soc_dai *dai = rtd->cpu_dai; 765 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 766 766 767 767 if (dai->active) { 768 768 sst_handle_vb_timer(dai, true);
+1 -1
sound/soc/intel/atom/sst/sst_pci.c
··· 99 99 dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); 100 100 do_release_regions: 101 101 pci_release_regions(pci); 102 - return 0; 102 + return ret; 103 103 } 104 104 105 105 /*
+49 -8
sound/soc/intel/boards/Kconfig
··· 289 289 select SND_SOC_DA7219 290 290 select SND_SOC_MAX98357A 291 291 select SND_SOC_DMIC 292 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 293 292 select SND_SOC_HDAC_HDMI 294 293 295 294 config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON ··· 301 302 tristate "Broxton with DA7219 and MAX98357A in I2S Mode" 302 303 depends on I2C && ACPI 303 304 depends on MFD_INTEL_LPSS || COMPILE_TEST 305 + depends on SND_HDA_CODEC_HDMI 304 306 select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON 305 307 help 306 308 This adds support for ASoC machine driver for Broxton-P platforms ··· 402 402 tristate "GLK with DA7219 and MAX98357A in I2S Mode" 403 403 depends on I2C && ACPI 404 404 depends on MFD_INTEL_LPSS || COMPILE_TEST 405 + depends on SND_HDA_CODEC_HDMI 405 406 select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON 406 407 help 407 408 This adds support for ASoC machine driver for Geminilake platforms ··· 414 413 tristate "GLK with RT5682 and MAX98357A in I2S Mode" 415 414 depends on I2C && ACPI 416 415 depends on MFD_INTEL_LPSS || COMPILE_TEST 416 + depends on SND_HDA_CODEC_HDMI 417 417 select SND_SOC_RT5682 418 418 select SND_SOC_MAX98357A 419 419 select SND_SOC_DMIC 420 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 421 420 select SND_SOC_HDAC_HDMI 422 421 help 423 422 This adds support for ASoC machine driver for Geminilake platforms ··· 431 430 432 431 config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH 433 432 tristate "SKL/KBL/BXT/APL with HDA Codecs" 434 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 433 + depends on SND_HDA_CODEC_HDMI 435 434 select SND_SOC_HDAC_HDMI 436 435 select SND_SOC_DMIC 437 436 # SND_SOC_HDAC_HDA is already selected ··· 449 448 depends on I2C && ACPI 450 449 depends on (SND_SOC_SOF_HDA_LINK && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\ 451 450 (SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST)) 451 + depends on SND_HDA_CODEC_HDMI 452 + select SND_SOC_MAX98373 453 + select SND_SOC_RT1015 452 454 select SND_SOC_RT5682 453 455 select SND_SOC_DMIC 454 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 455 456 select SND_SOC_HDAC_HDMI 456 457 help 457 458 This adds support for ASoC machine driver for SOF platforms 458 459 with rt5682 codec. 459 460 Say Y if you have such a device. 460 461 If unsure select "N". 462 + 463 + config SND_SOC_INTEL_SOF_PCM512x_MACH 464 + tristate "SOF with TI PCM512x codec" 465 + depends on I2C && ACPI 466 + depends on (SND_SOC_SOF_HDA_AUDIO_CODEC && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\ 467 + (SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST)) 468 + depends on SND_HDA_CODEC_HDMI 469 + select SND_SOC_PCM512x_I2C 470 + help 471 + This adds support for ASoC machine driver for SOF platforms 472 + with TI PCM512x I2S audio codec. 473 + Say Y or m if you have such a device. 474 + If unsure select "N". 475 + 461 476 endif ## SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL 462 477 463 478 if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK) ··· 493 476 tristate "CML with RT1011 and RT5682 in I2S Mode" 494 477 depends on I2C && ACPI 495 478 depends on MFD_INTEL_LPSS || COMPILE_TEST 479 + depends on SND_HDA_CODEC_HDMI 496 480 select SND_SOC_RT1011 497 481 select SND_SOC_RT5682 498 482 select SND_SOC_DMIC 499 483 select SND_SOC_HDAC_HDMI 500 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 501 484 help 502 485 This adds support for ASoC machine driver for SOF platform with 503 486 RT1011 + RT5682 I2S codec. ··· 509 492 if SND_SOC_SOF_JASPERLAKE 510 493 511 494 config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH 512 - tristate "SOF with DA7219 and MAX98373 in I2S Mode" 495 + tristate "SOF with DA7219 and MAX98373/MAX98360A in I2S Mode" 513 496 depends on I2C && ACPI 514 497 depends on MFD_INTEL_LPSS || COMPILE_TEST 498 + depends on SND_HDA_CODEC_HDMI 515 499 select SND_SOC_DA7219 516 500 select SND_SOC_MAX98373 517 501 select SND_SOC_DMIC 518 - select SND_HDA_CODEC_HDMI if SND_SOC_SOF_HDA_AUDIO_CODEC 519 502 help 520 503 This adds support for ASoC machine driver for SOF platforms 521 - with DA7219 + MAX98373 I2S audio codec. 504 + with DA7219 + MAX98373/MAX98360A I2S audio codec. 522 505 Say Y if you have such a device. 523 506 If unsure select "N". 524 507 525 508 endif ## SND_SOC_SOF_JASPERLAKE 509 + 510 + if SND_SOC_SOF_INTEL_SOUNDWIRE 511 + 512 + config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH 513 + tristate "SoundWire generic machine driver" 514 + depends on I2C && ACPI 515 + depends on MFD_INTEL_LPSS || COMPILE_TEST 516 + depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST 517 + depends on SOUNDWIRE 518 + depends on SND_HDA_CODEC_HDMI 519 + select SND_SOC_RT700_SDW 520 + select SND_SOC_RT711_SDW 521 + select SND_SOC_RT1308_SDW 522 + select SND_SOC_RT1308 523 + select SND_SOC_RT715_SDW 524 + select SND_SOC_RT5682_SDW 525 + select SND_SOC_DMIC 526 + help 527 + Add support for Intel SoundWire-based platforms connected to 528 + RT700, RT711, RT1308 and RT715 529 + If unsure select "N". 530 + 531 + endif 532 + 526 533 527 534 endif ## SND_SOC_INTEL_MACH
+9 -3
sound/soc/intel/boards/Makefile
··· 7 7 snd-soc-sst-broadwell-objs := broadwell.o 8 8 snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o hda_dsp_common.o 9 9 snd-soc-sst-bxt-rt298-objs := bxt_rt298.o hda_dsp_common.o 10 + snd-soc-sst-sof-pcm512x-objs := sof_pcm512x.o hda_dsp_common.o 10 11 snd-soc-sst-glk-rt5682_max98357a-objs := glk_rt5682_max98357a.o hda_dsp_common.o 11 12 snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o 12 13 snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o ··· 19 18 snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o 20 19 snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o 21 20 snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o 22 - snd-soc-sof_rt5682-objs := sof_rt5682.o hda_dsp_common.o 21 + snd-soc-sof_rt5682-objs := sof_rt5682.o hda_dsp_common.o sof_maxim_common.o 23 22 snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o hda_dsp_common.o 24 23 snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o 25 24 snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o ··· 31 30 snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o 32 31 snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o 33 32 snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o hda_dsp_common.o 34 - 33 + snd-soc-sof-sdw-objs += sof_sdw.o \ 34 + sof_sdw_rt711.o sof_sdw_rt700.o \ 35 + sof_sdw_rt1308.o sof_sdw_rt715.o \ 36 + sof_sdw_rt5682.o \ 37 + sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o 35 38 obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o 36 39 obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 37 40 obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 38 41 obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o 39 42 obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o 40 43 obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o 44 + obj-$(CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH) += snd-soc-sst-sof-pcm512x.o 41 45 obj-$(CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH) += snd-soc-sst-glk-rt5682_max98357a.o 42 46 obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 43 47 obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH) += snd-soc-sst-bdw-rt5650-mach.o ··· 68 62 obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o 69 63 obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o 70 64 obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o 71 - 65 + obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o
+8 -7
sound/soc/intel/boards/bdw-rt5650.c
··· 107 107 struct snd_pcm_hw_params *params) 108 108 { 109 109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 110 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 110 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 111 111 int ret; 112 112 113 113 /* Workaround: set codec PLL to 19.2MHz that PLL source is ··· 166 166 { 167 167 struct bdw_rt5650_priv *bdw_rt5650 = 168 168 snd_soc_card_get_drvdata(rtd->card); 169 - struct snd_soc_component *component = rtd->codec_dai->component; 170 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 169 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 170 + struct snd_soc_component *component = codec_dai->component; 171 171 int ret; 172 172 173 173 /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1. ··· 226 226 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 227 227 SND_SOC_DAILINK_DEF(ssp0_port, 228 228 DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); 229 - #else 230 - SND_SOC_DAILINK_DEF(ssp0_port, 231 - DAILINK_COMP_ARRAY(COMP_DUMMY())); 232 229 #endif 233 230 234 231 static struct snd_soc_dai_link bdw_rt5650_dais[] = { ··· 261 264 .dpcm_playback = 1, 262 265 .dpcm_capture = 1, 263 266 .init = bdw_rt5650_init, 267 + #if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 268 + SND_SOC_DAILINK_REG(dummy, be, dummy), 269 + #else 264 270 SND_SOC_DAILINK_REG(ssp0_port, be, platform), 271 + #endif 265 272 }, 266 273 }; 267 274 ··· 299 298 return -ENOMEM; 300 299 301 300 /* override plaform name, if required */ 302 - mach = (&pdev->dev)->platform_data; 301 + mach = pdev->dev.platform_data; 303 302 ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5650_card, 304 303 mach->mach_params.platform); 305 304
+8 -7
sound/soc/intel/boards/bdw-rt5677.c
··· 157 157 struct snd_pcm_hw_params *params) 158 158 { 159 159 struct snd_soc_pcm_runtime *rtd = substream->private_data; 160 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 160 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 161 161 int ret; 162 162 163 163 ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000, ··· 174 174 struct snd_pcm_hw_params *params) 175 175 { 176 176 struct snd_soc_pcm_runtime *rtd = substream->private_data; 177 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 177 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 178 178 int ret; 179 179 180 180 ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000, ··· 226 226 { 227 227 struct bdw_rt5677_priv *bdw_rt5677 = 228 228 snd_soc_card_get_drvdata(rtd->card); 229 - struct snd_soc_component *component = rtd->codec_dai->component; 229 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 230 230 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 231 231 int ret; 232 232 ··· 298 298 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 299 299 SND_SOC_DAILINK_DEF(ssp0_port, 300 300 DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); 301 - #else 302 - SND_SOC_DAILINK_DEF(ssp0_port, 303 - DAILINK_COMP_ARRAY(COMP_DUMMY())); 304 301 #endif 305 302 306 303 /* Wake on voice interface */ ··· 347 350 .dpcm_playback = 1, 348 351 .dpcm_capture = 1, 349 352 .init = bdw_rt5677_init, 353 + #if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 354 + SND_SOC_DAILINK_REG(dummy, be, dummy), 355 + #else 350 356 SND_SOC_DAILINK_REG(ssp0_port, be, platform), 357 + #endif 351 358 }, 352 359 }; 353 360 ··· 413 412 } 414 413 415 414 /* override plaform name, if required */ 416 - mach = (&pdev->dev)->platform_data; 415 + mach = pdev->dev.platform_data; 417 416 ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card, 418 417 mach->mach_params.platform); 419 418 if (ret)
+7 -6
sound/soc/intel/boards/broadwell.c
··· 70 70 71 71 static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 72 72 { 73 - struct snd_soc_component *component = rtd->codec_dai->component; 73 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 74 74 int ret = 0; 75 75 ret = snd_soc_card_jack_new(rtd->card, "Headset", 76 76 SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset, ··· 104 104 struct snd_pcm_hw_params *params) 105 105 { 106 106 struct snd_soc_pcm_runtime *rtd = substream->private_data; 107 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 107 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 108 108 int ret; 109 109 110 110 ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, ··· 167 167 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 168 168 SND_SOC_DAILINK_DEF(ssp0_port, 169 169 DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); 170 - #else 171 - SND_SOC_DAILINK_DEF(ssp0_port, 172 - DAILINK_COMP_ARRAY(COMP_DUMMY())); 173 170 #endif 174 171 175 172 /* broadwell digital audio interface glue - connects codec <--> CPU */ ··· 223 226 .ops = &broadwell_rt286_ops, 224 227 .dpcm_playback = 1, 225 228 .dpcm_capture = 1, 229 + #if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) 230 + SND_SOC_DAILINK_REG(dummy, codec, dummy), 231 + #else 226 232 SND_SOC_DAILINK_REG(ssp0_port, codec, platform), 233 + #endif 227 234 }, 228 235 }; 229 236 ··· 284 283 broadwell_rt286.dev = &pdev->dev; 285 284 286 285 /* override plaform name, if required */ 287 - mach = (&pdev->dev)->platform_data; 286 + mach = pdev->dev.platform_data; 288 287 ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, 289 288 mach->mach_params.platform); 290 289 if (ret)
+5 -5
sound/soc/intel/boards/bxt_da7219_max98357a.c
··· 179 179 static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) 180 180 { 181 181 int ret; 182 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 183 - struct snd_soc_component *component = rtd->codec_dai->component; 182 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 183 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 184 184 int clk_freq; 185 185 186 186 /* Configure sysclk for codec */ ··· 226 226 static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) 227 227 { 228 228 struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 229 - struct snd_soc_dai *dai = rtd->codec_dai; 229 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 230 230 struct bxt_hdmi_pcm *pcm; 231 231 232 232 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 244 244 static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) 245 245 { 246 246 struct snd_soc_dapm_context *dapm; 247 - struct snd_soc_component *component = rtd->cpu_dai->component; 247 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 248 248 249 249 dapm = snd_soc_component_get_dapm(component); 250 250 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 721 721 } 722 722 723 723 /* override plaform name, if required */ 724 - mach = (&pdev->dev)->platform_data; 724 + mach = pdev->dev.platform_data; 725 725 platform_name = mach->mach_params.platform; 726 726 727 727 ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card,
+5 -5
sound/soc/intel/boards/bxt_rt298.c
··· 155 155 static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) 156 156 { 157 157 struct snd_soc_dapm_context *dapm; 158 - struct snd_soc_component *component = rtd->cpu_dai->component; 158 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 159 159 160 160 dapm = snd_soc_component_get_dapm(component); 161 161 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 165 165 166 166 static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) 167 167 { 168 - struct snd_soc_component *component = rtd->codec_dai->component; 168 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 169 169 int ret = 0; 170 170 171 171 ret = snd_soc_card_jack_new(rtd->card, "Headset", ··· 186 186 static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) 187 187 { 188 188 struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); 189 - struct snd_soc_dai *dai = rtd->codec_dai; 189 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 190 190 struct bxt_hdmi_pcm *pcm; 191 191 192 192 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 225 225 struct snd_pcm_hw_params *params) 226 226 { 227 227 struct snd_soc_pcm_runtime *rtd = substream->private_data; 228 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 228 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 229 229 int ret; 230 230 231 231 ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, ··· 627 627 snd_soc_card_set_drvdata(card, ctx); 628 628 629 629 /* override plaform name, if required */ 630 - mach = (&pdev->dev)->platform_data; 630 + mach = pdev->dev.platform_data; 631 631 platform_name = mach->mach_params.platform; 632 632 633 633 ret = snd_soc_fixup_dai_links_platform_name(card,
+1 -1
sound/soc/intel/boards/byt-max98090.c
··· 89 89 90 90 card->dapm.idle_bias_off = true; 91 91 92 - ret = snd_soc_dai_set_sysclk(runtime->codec_dai, 92 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 93 93 M98090_REG_SYSTEM_CLOCK, 94 94 25000000, SND_SOC_CLOCK_IN); 95 95 if (ret < 0) {
+2 -2
sound/soc/intel/boards/byt-rt5640.c
··· 73 73 struct snd_pcm_hw_params *params) 74 74 { 75 75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 76 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 76 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 77 77 int ret; 78 78 79 79 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, ··· 123 123 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) 124 124 { 125 125 int ret; 126 - struct snd_soc_component *component = runtime->codec_dai->component; 126 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 127 127 struct snd_soc_card *card = runtime->card; 128 128 const struct snd_soc_dapm_route *custom_map; 129 129 int num_routes;
+5 -5
sound/soc/intel/boards/bytcht_cx2072x.c
··· 70 70 static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) 71 71 { 72 72 struct snd_soc_card *card = rtd->card; 73 - struct snd_soc_component *codec = rtd->codec_dai->component; 73 + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; 74 74 int ret; 75 75 76 76 if (devm_acpi_dev_add_driver_gpios(codec->dev, ··· 80 80 card->dapm.idle_bias_off = true; 81 81 82 82 /* set the default PLL rate, the clock is handled by the codec driver */ 83 - ret = snd_soc_dai_set_sysclk(rtd->codec_dai, CX2072X_MCLK_EXTERNAL_PLL, 83 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, 84 84 19200000, SND_SOC_CLOCK_IN); 85 85 if (ret) { 86 86 dev_err(rtd->dev, "Could not set sysclk\n"); ··· 97 97 98 98 snd_soc_component_set_jack(codec, &byt_cht_cx2072x_headset, NULL); 99 99 100 - snd_soc_dai_set_bclk_ratio(rtd->codec_dai, 50); 100 + snd_soc_dai_set_bclk_ratio(asoc_rtd_to_codec(rtd, 0), 50); 101 101 102 102 return ret; 103 103 } ··· 123 123 * with explicit setting to I2S 2ch 24-bit. The word length is set with 124 124 * dai_set_tdm_slot() since there is no other API exposed 125 125 */ 126 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 126 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 127 127 SND_SOC_DAIFMT_I2S | 128 128 SND_SOC_DAIFMT_NB_NF | 129 129 SND_SOC_DAIFMT_CBS_CFS); ··· 132 132 return ret; 133 133 } 134 134 135 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); 135 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); 136 136 if (ret < 0) { 137 137 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 138 138 return ret;
+5 -5
sound/soc/intel/boards/bytcht_da7213.c
··· 78 78 * with explicit setting to I2S 2ch 24-bit. The word length is set with 79 79 * dai_set_tdm_slot() since there is no other API exposed 80 80 */ 81 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 81 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 82 82 SND_SOC_DAIFMT_I2S | 83 83 SND_SOC_DAIFMT_NB_NF | 84 84 SND_SOC_DAIFMT_CBS_CFS); ··· 87 87 return ret; 88 88 } 89 89 90 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); 90 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); 91 91 if (ret < 0) { 92 92 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 93 93 return ret; ··· 106 106 struct snd_pcm_hw_params *params) 107 107 { 108 108 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 109 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 110 110 int ret; 111 111 112 112 ret = snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, ··· 127 127 static int aif1_hw_free(struct snd_pcm_substream *substream) 128 128 { 129 129 struct snd_soc_pcm_runtime *rtd = substream->private_data; 130 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 130 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 131 131 int ret; 132 132 133 133 ret = snd_soc_dai_set_pll(codec_dai, 0, ··· 231 231 int ret_val = 0; 232 232 int i; 233 233 234 - mach = (&pdev->dev)->platform_data; 234 + mach = pdev->dev.platform_data; 235 235 card = &bytcht_da7213_card; 236 236 card->dev = &pdev->dev; 237 237
+4 -4
sound/soc/intel/boards/bytcht_es8316.c
··· 157 157 158 158 static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) 159 159 { 160 - struct snd_soc_component *codec = runtime->codec_dai->component; 160 + struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; 161 161 struct snd_soc_card *card = runtime->card; 162 162 struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); 163 163 const struct snd_soc_dapm_route *custom_map; ··· 212 212 if (ret) 213 213 dev_err(card->dev, "unable to enable MCLK\n"); 214 214 215 - ret = snd_soc_dai_set_sysclk(runtime->codec_dai, 0, 19200000, 215 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000, 216 216 SND_SOC_CLOCK_IN); 217 217 if (ret < 0) { 218 218 dev_err(card->dev, "can't set codec clock %d\n", ret); ··· 262 262 * with explicit setting to I2S 2ch 24-bit. The word length is set with 263 263 * dai_set_tdm_slot() since there is no other API exposed 264 264 */ 265 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 265 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 266 266 SND_SOC_DAIFMT_I2S | 267 267 SND_SOC_DAIFMT_NB_NF | 268 268 SND_SOC_DAIFMT_CBS_CFS ··· 272 272 return ret; 273 273 } 274 274 275 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits); 275 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); 276 276 if (ret < 0) { 277 277 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 278 278 return ret;
+2 -2
sound/soc/intel/boards/bytcht_nocodec.c
··· 58 58 * with explicit setting to I2S 2ch 24-bit. The word length is set with 59 59 * dai_set_tdm_slot() since there is no other API exposed 60 60 */ 61 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 61 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 62 62 SND_SOC_DAIFMT_I2S | 63 63 SND_SOC_DAIFMT_NB_NF | 64 64 SND_SOC_DAIFMT_CBS_CFS); ··· 68 68 return ret; 69 69 } 70 70 71 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); 71 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); 72 72 if (ret < 0) { 73 73 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 74 74 return ret;
+4 -4
sound/soc/intel/boards/bytcr_rt5640.c
··· 381 381 struct snd_pcm_hw_params *params) 382 382 { 383 383 struct snd_soc_pcm_runtime *rtd = substream->private_data; 384 - struct snd_soc_dai *dai = rtd->codec_dai; 384 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 385 385 386 386 return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params)); 387 387 } ··· 805 805 { 806 806 struct snd_soc_card *card = runtime->card; 807 807 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); 808 - struct snd_soc_component *component = runtime->codec_dai->component; 808 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 809 809 const struct snd_soc_dapm_route *custom_map; 810 810 int num_routes; 811 811 int ret; ··· 962 962 * with explicit setting to I2S 2ch. The word length is set with 963 963 * dai_set_tdm_slot() since there is no other API exposed 964 964 */ 965 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 965 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 966 966 SND_SOC_DAIFMT_I2S | 967 967 SND_SOC_DAIFMT_NB_NF | 968 968 SND_SOC_DAIFMT_CBS_CFS); ··· 971 971 return ret; 972 972 } 973 973 974 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits); 974 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); 975 975 if (ret < 0) { 976 976 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 977 977 return ret;
+4 -4
sound/soc/intel/boards/bytcr_rt5651.c
··· 348 348 struct snd_pcm_hw_params *params) 349 349 { 350 350 struct snd_soc_pcm_runtime *rtd = substream->private_data; 351 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 351 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 352 352 snd_pcm_format_t format = params_format(params); 353 353 int rate = params_rate(params); 354 354 int bclk_ratio; ··· 540 540 static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) 541 541 { 542 542 struct snd_soc_card *card = runtime->card; 543 - struct snd_soc_component *codec = runtime->codec_dai->component; 543 + struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; 544 544 struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); 545 545 const struct snd_soc_dapm_route *custom_map; 546 546 int num_routes; ··· 685 685 * with explicit setting to I2S 2ch. The word length is set with 686 686 * dai_set_tdm_slot() since there is no other API exposed 687 687 */ 688 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 688 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 689 689 SND_SOC_DAIFMT_I2S | 690 690 SND_SOC_DAIFMT_NB_NF | 691 691 SND_SOC_DAIFMT_CBS_CFS ··· 696 696 return ret; 697 697 } 698 698 699 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits); 699 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); 700 700 if (ret < 0) { 701 701 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 702 702 return ret;
+4 -4
sound/soc/intel/boards/cht_bsw_max98090_ti.c
··· 113 113 struct snd_pcm_hw_params *params) 114 114 { 115 115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 116 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 116 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 117 117 int ret; 118 118 119 119 ret = snd_soc_dai_set_sysclk(codec_dai, M98090_REG_SYSTEM_CLOCK, ··· 257 257 int ret = 0; 258 258 unsigned int fmt = 0; 259 259 260 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); 260 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); 261 261 if (ret < 0) { 262 262 dev_err(rtd->dev, "can't set cpu_dai slot fmt: %d\n", ret); 263 263 return ret; ··· 266 266 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 267 267 | SND_SOC_DAIFMT_CBS_CFS; 268 268 269 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt); 269 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); 270 270 if (ret < 0) { 271 271 dev_err(rtd->dev, "can't set cpu_dai set fmt: %d\n", ret); 272 272 return ret; ··· 553 553 554 554 /* override plaform name, if required */ 555 555 snd_soc_card_cht.dev = &pdev->dev; 556 - mach = (&pdev->dev)->platform_data; 556 + mach = pdev->dev.platform_data; 557 557 platform_name = mach->mach_params.platform; 558 558 559 559 ret_val = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cht,
+3 -3
sound/soc/intel/boards/cht_bsw_nau8824.c
··· 73 73 struct snd_pcm_hw_params *params) 74 74 { 75 75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 76 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 76 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 77 77 int ret; 78 78 79 79 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0, ··· 96 96 { 97 97 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); 98 98 struct snd_soc_jack *jack = &ctx->jack; 99 - struct snd_soc_dai *codec_dai = runtime->codec_dai; 99 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); 100 100 struct snd_soc_component *component = codec_dai->component; 101 101 int ret, jack_type; 102 102 ··· 259 259 260 260 /* override plaform name, if required */ 261 261 snd_soc_card_cht.dev = &pdev->dev; 262 - mach = (&pdev->dev)->platform_data; 262 + mach = pdev->dev.platform_data; 263 263 platform_name = mach->mach_params.platform; 264 264 265 265 ret_val = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cht,
+8 -8
sound/soc/intel/boards/cht_bsw_rt5645.c
··· 208 208 struct snd_pcm_hw_params *params) 209 209 { 210 210 struct snd_soc_pcm_runtime *rtd = substream->private_data; 211 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 211 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 212 212 int ret; 213 213 214 214 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ ··· 252 252 { 253 253 struct snd_soc_card *card = runtime->card; 254 254 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); 255 - struct snd_soc_component *component = runtime->codec_dai->component; 255 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 256 256 int jack_type; 257 257 int ret; 258 258 ··· 359 359 * with explicit setting to I2S 2ch 16-bit. The word length is set with 360 360 * dai_set_tdm_slot() since there is no other API exposed 361 361 */ 362 - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, 362 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), 363 363 SND_SOC_DAIFMT_I2S | 364 364 SND_SOC_DAIFMT_NB_NF | 365 365 SND_SOC_DAIFMT_CBS_CFS ··· 369 369 return ret; 370 370 } 371 371 372 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, 372 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), 373 373 SND_SOC_DAIFMT_I2S | 374 374 SND_SOC_DAIFMT_NB_NF | 375 375 SND_SOC_DAIFMT_CBS_CFS ··· 379 379 return ret; 380 380 } 381 381 382 - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); 382 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); 383 383 if (ret < 0) { 384 384 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 385 385 return ret; ··· 393 393 /* 394 394 * Default mode for SSP configuration is TDM 4 slot 395 395 */ 396 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, 396 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), 397 397 SND_SOC_DAIFMT_DSP_B | 398 398 SND_SOC_DAIFMT_IB_NF | 399 399 SND_SOC_DAIFMT_CBS_CFS); ··· 403 403 } 404 404 405 405 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ 406 - ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0xF, 0xF, 4, 24); 406 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); 407 407 if (ret < 0) { 408 408 dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); 409 409 return ret; ··· 539 539 if (!drv) 540 540 return -ENOMEM; 541 541 542 - mach = (&pdev->dev)->platform_data; 542 + mach = pdev->dev.platform_data; 543 543 544 544 for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { 545 545 if (acpi_dev_found(snd_soc_cards[i].codec_id) &&
+4 -4
sound/soc/intel/boards/cht_bsw_rt5672.c
··· 144 144 struct snd_pcm_hw_params *params) 145 145 { 146 146 struct snd_soc_pcm_runtime *rtd = substream->private_data; 147 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 147 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 148 148 int ret; 149 149 150 150 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ ··· 176 176 static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) 177 177 { 178 178 int ret; 179 - struct snd_soc_dai *codec_dai = runtime->codec_dai; 179 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); 180 180 struct snd_soc_component *component = codec_dai->component; 181 181 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); 182 182 ··· 255 255 /* 256 256 * Default mode for SSP configuration is TDM 4 slot 257 257 */ 258 - ret = snd_soc_dai_set_fmt(rtd->codec_dai, 258 + ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), 259 259 SND_SOC_DAIFMT_DSP_B | 260 260 SND_SOC_DAIFMT_IB_NF | 261 261 SND_SOC_DAIFMT_CBS_CFS); ··· 265 265 } 266 266 267 267 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ 268 - ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0xF, 0xF, 4, 24); 268 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); 269 269 if (ret < 0) { 270 270 dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); 271 271 return ret;
+6 -7
sound/soc/intel/boards/cml_rt1011_rt5682.c
··· 85 85 static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) 86 86 { 87 87 struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 88 - struct snd_soc_component *component = rtd->codec_dai->component; 88 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 89 89 struct snd_soc_jack *jack; 90 90 int ret; 91 91 ··· 125 125 struct snd_pcm_hw_params *params) 126 126 { 127 127 struct snd_soc_pcm_runtime *rtd = substream->private_data; 128 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 128 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 129 129 int clk_id, clk_freq, pll_out, ret; 130 130 131 131 clk_id = RT5682_PLL1_S_MCLK; ··· 164 164 165 165 srate = params_rate(params); 166 166 167 - for (i = 0; i < rtd->num_codecs; i++) { 168 - codec_dai = rtd->codec_dais[i]; 167 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 169 168 170 169 /* 100 Fs to drive 24 bit data */ 171 170 ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK, ··· 274 275 static int hdmi_init(struct snd_soc_pcm_runtime *rtd) 275 276 { 276 277 struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 277 - struct snd_soc_dai *dai = rtd->codec_dai; 278 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 278 279 struct hdmi_pcm *pcm; 279 280 280 281 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 446 447 const char *platform_name; 447 448 int ret; 448 449 449 - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 450 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 450 451 if (!ctx) 451 452 return -ENOMEM; 452 453 453 454 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 454 - mach = (&pdev->dev)->platform_data; 455 + mach = pdev->dev.platform_data; 455 456 snd_soc_card_cml.dev = &pdev->dev; 456 457 platform_name = mach->mach_params.platform; 457 458
+7 -6
sound/soc/intel/boards/glk_rt5682_max98357a.c
··· 136 136 static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) 137 137 { 138 138 struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 139 - struct snd_soc_component *component = rtd->codec_dai->component; 140 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 139 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 140 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 141 141 struct snd_soc_jack *jack; 142 142 int ret; 143 143 ··· 188 188 struct snd_pcm_hw_params *params) 189 189 { 190 190 struct snd_soc_pcm_runtime *rtd = substream->private_data; 191 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 191 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 192 192 int ret; 193 193 194 194 /* Set valid bitmask & configuration for I2S in 24 bit */ ··· 208 208 static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) 209 209 { 210 210 struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 211 - struct snd_soc_dai *dai = rtd->codec_dai; 211 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 212 212 struct glk_hdmi_pcm *pcm; 213 213 214 214 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 225 225 226 226 static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd) 227 227 { 228 - struct snd_soc_component *component = rtd->cpu_dai->component; 228 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 229 229 struct snd_soc_dapm_context *dapm; 230 230 int ret; 231 231 ··· 409 409 .init = NULL, 410 410 .capture_only = 1, 411 411 .nonatomic = 1, 412 + .dynamic = 1, 412 413 SND_SOC_DAILINK_REG(echoref, dummy, platform), 413 414 }, 414 415 [GLK_DPCM_AUDIO_REF_CP] = { ··· 605 604 snd_soc_card_set_drvdata(card, ctx); 606 605 607 606 /* override plaform name, if required */ 608 - mach = (&pdev->dev)->platform_data; 607 + mach = pdev->dev.platform_data; 609 608 platform_name = mach->mach_params.platform; 610 609 611 610 ret = snd_soc_fixup_dai_links_platform_name(card, platform_name);
+2 -2
sound/soc/intel/boards/haswell.c
··· 56 56 struct snd_pcm_hw_params *params) 57 57 { 58 58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 60 60 int ret; 61 61 62 62 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, ··· 193 193 haswell_rt5640.dev = &pdev->dev; 194 194 195 195 /* override plaform name, if required */ 196 - mach = (&pdev->dev)->platform_data; 196 + mach = pdev->dev.platform_data; 197 197 ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, 198 198 mach->mach_params.platform); 199 199 if (ret)
+4 -4
sound/soc/intel/boards/kbl_da7219_max98357a.c
··· 159 159 static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) 160 160 { 161 161 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 162 - struct snd_soc_component *component = rtd->codec_dai->component; 163 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 162 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 163 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 164 164 struct snd_soc_jack *jack; 165 165 int ret; 166 166 ··· 203 203 static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) 204 204 { 205 205 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 206 - struct snd_soc_dai *dai = rtd->codec_dai; 206 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 207 207 struct kbl_hdmi_pcm *pcm; 208 208 209 209 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 236 236 static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) 237 237 { 238 238 struct snd_soc_dapm_context *dapm; 239 - struct snd_soc_component *component = rtd->cpu_dai->component; 239 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 240 240 241 241 dapm = snd_soc_component_get_dapm(component); 242 242 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
+7 -7
sound/soc/intel/boards/kbl_da7219_max98927.c
··· 176 176 struct snd_pcm_hw_params *params) 177 177 { 178 178 struct snd_soc_pcm_runtime *runtime = substream->private_data; 179 + struct snd_soc_dai *codec_dai; 179 180 int ret, j; 180 181 181 - for (j = 0; j < runtime->num_codecs; j++) { 182 - struct snd_soc_dai *codec_dai = runtime->codec_dais[j]; 182 + for_each_rtd_codec_dais(runtime, j, codec_dai) { 183 183 184 184 if (!strcmp(codec_dai->component->name, MAX98927_DEV0_NAME)) { 185 185 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); ··· 221 221 static int kabylake_ssp0_trigger(struct snd_pcm_substream *substream, int cmd) 222 222 { 223 223 struct snd_soc_pcm_runtime *rtd = substream->private_data; 224 + struct snd_soc_dai *codec_dai; 224 225 int j, ret; 225 226 226 - for (j = 0; j < rtd->num_codecs; j++) { 227 - struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 227 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 228 228 const char *name = codec_dai->component->name; 229 229 struct snd_soc_component *component = codec_dai->component; 230 230 struct snd_soc_dapm_context *dapm = ··· 331 331 static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) 332 332 { 333 333 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 334 - struct snd_soc_component *component = rtd->codec_dai->component; 334 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 335 335 struct snd_soc_jack *jack; 336 336 struct snd_soc_card *card = rtd->card; 337 337 int ret; ··· 381 381 static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) 382 382 { 383 383 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 384 - struct snd_soc_dai *dai = rtd->codec_dai; 384 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 385 385 struct kbl_hdmi_pcm *pcm; 386 386 387 387 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 414 414 static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) 415 415 { 416 416 struct snd_soc_dapm_context *dapm; 417 - struct snd_soc_component *component = rtd->cpu_dai->component; 417 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 418 418 419 419 dapm = snd_soc_component_get_dapm(component); 420 420 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
+3 -3
sound/soc/intel/boards/kbl_rt5660.c
··· 157 157 { 158 158 int ret; 159 159 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 160 - struct snd_soc_component *component = rtd->codec_dai->component; 160 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 161 161 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 162 162 163 163 ret = devm_acpi_dev_add_driver_gpios(component->dev, acpi_rt5660_gpios); ··· 210 210 static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) 211 211 { 212 212 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 213 - struct snd_soc_dai *dai = rtd->codec_dai; 213 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 214 214 struct kbl_hdmi_pcm *pcm; 215 215 216 216 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 244 244 struct snd_pcm_hw_params *params) 245 245 { 246 246 struct snd_soc_pcm_runtime *rtd = substream->private_data; 247 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 247 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 248 248 int ret; 249 249 250 250 ret = snd_soc_dai_set_sysclk(codec_dai,
+6 -6
sound/soc/intel/boards/kbl_rt5663_max98927.c
··· 242 242 { 243 243 int ret; 244 244 struct snd_soc_dapm_context *dapm; 245 - struct snd_soc_component *component = rtd->cpu_dai->component; 245 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 246 246 247 247 dapm = snd_soc_component_get_dapm(component); 248 248 ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 258 258 { 259 259 int ret; 260 260 struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); 261 - struct snd_soc_component *component = rtd->codec_dai->component; 261 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 262 262 struct snd_soc_jack *jack; 263 263 264 264 /* ··· 305 305 static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) 306 306 { 307 307 struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); 308 - struct snd_soc_dai *dai = rtd->codec_dai; 308 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 309 309 struct kbl_hdmi_pcm *pcm; 310 310 311 311 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 431 431 struct snd_pcm_hw_params *params) 432 432 { 433 433 struct snd_soc_pcm_runtime *rtd = substream->private_data; 434 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 434 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 435 435 int ret; 436 436 437 437 /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ ··· 472 472 struct snd_soc_dai *codec_dai; 473 473 int ret = 0, j; 474 474 475 - for_each_rtd_codec_dai(rtd, j, codec_dai) { 475 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 476 476 if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { 477 477 /* 478 478 * Use channel 4 and 5 for the first amp ··· 962 962 kabylake_audio_card->dev = &pdev->dev; 963 963 snd_soc_card_set_drvdata(kabylake_audio_card, ctx); 964 964 965 - mach = (&pdev->dev)->platform_data; 965 + mach = pdev->dev.platform_data; 966 966 if (mach) 967 967 dmic_constraints = mach->mach_params.dmic_num == 2 ? 968 968 &constraints_dmic_2ch : &constraints_dmic_channels;
+6 -6
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
··· 206 206 static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) 207 207 { 208 208 struct snd_soc_dapm_context *dapm; 209 - struct snd_soc_component *component = rtd->cpu_dai->component; 209 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 210 210 int ret; 211 211 212 212 dapm = snd_soc_component_get_dapm(component); ··· 221 221 { 222 222 int ret; 223 223 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 224 - struct snd_soc_component *component = rtd->codec_dai->component; 224 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 225 225 struct snd_soc_jack *jack; 226 226 227 227 /* ··· 255 255 static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) 256 256 { 257 257 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 258 - struct snd_soc_dai *dai = rtd->codec_dai; 258 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 259 259 struct kbl_hdmi_pcm *pcm; 260 260 261 261 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 372 372 struct snd_pcm_hw_params *params) 373 373 { 374 374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 375 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 375 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 376 376 int ret; 377 377 378 378 /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ ··· 399 399 struct snd_soc_dai *codec_dai; 400 400 int ret = 0, j; 401 401 402 - for_each_rtd_codec_dai(rtd, j, codec_dai) { 402 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 403 403 if (!strcmp(codec_dai->component->name, RT5514_DEV_NAME)) { 404 404 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0, 8, 16); 405 405 if (ret < 0) { ··· 772 772 kabylake_audio_card.dev = &pdev->dev; 773 773 snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); 774 774 775 - mach = (&pdev->dev)->platform_data; 775 + mach = pdev->dev.platform_data; 776 776 if (mach) 777 777 dmic_constraints = mach->mach_params.dmic_num == 2 ? 778 778 &constraints_dmic_2ch : &constraints_dmic_channels;
+4
sound/soc/intel/boards/skl_hda_dsp_common.h
··· 49 49 struct snd_soc_component *component; 50 50 struct skl_hda_hdmi_pcm *pcm; 51 51 52 + /* HDMI disabled, do not create controls */ 53 + if (list_empty(&ctx->hdmi_pcm_list)) 54 + return 0; 55 + 52 56 pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm, 53 57 head); 54 58 component = pcm->codec_dai->component;
+21 -6
sound/soc/intel/boards/skl_hda_dsp_generic.c
··· 61 61 { "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" }, 62 62 }; 63 63 64 + SND_SOC_DAILINK_DEF(dummy_codec, 65 + DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai"))); 66 + 64 67 static int skl_hda_card_late_probe(struct snd_soc_card *card) 65 68 { 66 69 return skl_hda_hdmi_jack_init(card); ··· 117 114 { 118 115 struct snd_soc_card *card = &hda_soc_card; 119 116 struct snd_soc_dai_link *dai_link; 120 - u32 codec_count, codec_mask; 117 + u32 codec_count, codec_mask, idisp_mask; 121 118 int i, num_links, num_route; 122 119 123 120 codec_mask = mach_params->codec_mask; 124 121 codec_count = hweight_long(codec_mask); 122 + idisp_mask = codec_mask & IDISP_CODEC_MASK; 125 123 126 - if (codec_count == 1 && codec_mask & IDISP_CODEC_MASK) { 124 + if (!codec_count || codec_count > 2 || 125 + (codec_count == 2 && !idisp_mask)) 126 + return -EINVAL; 127 + 128 + if (codec_mask == idisp_mask) { 129 + /* topology with iDisp as the only HDA codec */ 127 130 num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT; 128 131 num_route = IDISP_ROUTE_COUNT; 129 132 ··· 144 135 skl_hda_be_dai_links[IDISP_DAI_COUNT + 145 136 HDAC_DAI_COUNT + i]; 146 137 } 147 - } else if (codec_count == 2 && codec_mask & IDISP_CODEC_MASK) { 138 + } else { 139 + /* topology with external and iDisp HDA codecs */ 148 140 num_links = ARRAY_SIZE(skl_hda_be_dai_links); 149 141 num_route = ARRAY_SIZE(skl_hda_map); 150 142 card->dapm_widgets = skl_hda_widgets; 151 143 card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets); 152 - } else { 153 - return -EINVAL; 144 + if (!idisp_mask) { 145 + for (i = 0; i < IDISP_DAI_COUNT; i++) { 146 + skl_hda_be_dai_links[i].codecs = dummy_codec; 147 + skl_hda_be_dai_links[i].num_codecs = 148 + ARRAY_SIZE(dummy_codec); 149 + } 150 + } 154 151 } 155 152 156 153 card->num_links = num_links; ··· 182 167 183 168 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 184 169 185 - mach = (&pdev->dev)->platform_data; 170 + mach = pdev->dev.platform_data; 186 171 if (!mach) 187 172 return -EINVAL; 188 173
+7 -7
sound/soc/intel/boards/skl_nau88l25_max98357a.c
··· 157 157 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 158 158 { 159 159 int ret; 160 - struct snd_soc_component *component = rtd->codec_dai->component; 160 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 161 161 162 162 /* 163 163 * Headset buttons map to the google Reference headset. ··· 182 182 static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 183 183 { 184 184 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); 185 - struct snd_soc_dai *dai = rtd->codec_dai; 185 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 186 186 struct skl_hdmi_pcm *pcm; 187 187 188 188 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 200 200 static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 201 201 { 202 202 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); 203 - struct snd_soc_dai *dai = rtd->codec_dai; 203 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 204 204 struct skl_hdmi_pcm *pcm; 205 205 206 206 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 218 218 static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 219 219 { 220 220 struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); 221 - struct snd_soc_dai *dai = rtd->codec_dai; 221 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 222 222 struct skl_hdmi_pcm *pcm; 223 223 224 224 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 236 236 static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 237 237 { 238 238 struct snd_soc_dapm_context *dapm; 239 - struct snd_soc_component *component = rtd->cpu_dai->component; 239 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 240 240 241 241 dapm = snd_soc_component_get_dapm(component); 242 242 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 296 296 struct snd_pcm_hw_params *params) 297 297 { 298 298 struct snd_soc_pcm_runtime *rtd = substream->private_data; 299 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 299 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 300 300 int ret; 301 301 302 302 ret = snd_soc_dai_set_sysclk(codec_dai, ··· 660 660 skylake_audio_card.dev = &pdev->dev; 661 661 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 662 662 663 - mach = (&pdev->dev)->platform_data; 663 + mach = pdev->dev.platform_data; 664 664 if (mach) 665 665 dmic_constraints = mach->mach_params.dmic_num == 2 ? 666 666 &constraints_dmic_2ch : &constraints_dmic_channels;
+10 -9
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
··· 161 161 int ret; 162 162 163 163 /* Slot 1 for left */ 164 - ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[0], 0x01, 0x01, 2, 48); 164 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); 165 165 if (ret < 0) 166 166 return ret; 167 167 168 168 /* Slot 2 for right */ 169 - ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[1], 0x02, 0x02, 2, 48); 169 + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); 170 170 if (ret < 0) 171 171 return ret; 172 172 ··· 176 176 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) 177 177 { 178 178 int ret; 179 - struct snd_soc_component *component = rtd->codec_dai->component; 179 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 180 180 181 181 /* 182 182 * 4 buttons here map to the google Reference headset ··· 201 201 static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) 202 202 { 203 203 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 204 - struct snd_soc_dai *dai = rtd->codec_dai; 204 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 205 205 struct skl_hdmi_pcm *pcm; 206 206 207 207 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 219 219 static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) 220 220 { 221 221 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 222 - struct snd_soc_dai *dai = rtd->codec_dai; 222 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 223 223 struct skl_hdmi_pcm *pcm; 224 224 225 225 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 238 238 static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) 239 239 { 240 240 struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); 241 - struct snd_soc_dai *dai = rtd->codec_dai; 241 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 242 242 struct skl_hdmi_pcm *pcm; 243 243 244 244 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 256 256 static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) 257 257 { 258 258 struct snd_soc_dapm_context *dapm; 259 - struct snd_soc_component *component = rtd->cpu_dai->component; 259 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 260 260 261 261 dapm = snd_soc_component_get_dapm(component); 262 262 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 348 348 struct snd_pcm_hw_params *params) 349 349 { 350 350 struct snd_soc_pcm_runtime *rtd = substream->private_data; 351 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 351 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 352 352 int ret; 353 353 354 354 ret = snd_soc_dai_set_sysclk(codec_dai, ··· 686 686 .codec_conf = ssm4567_codec_conf, 687 687 .num_configs = ARRAY_SIZE(ssm4567_codec_conf), 688 688 .fully_routed = true, 689 + .disable_route_checks = true, 689 690 .late_probe = skylake_card_late_probe, 690 691 }; 691 692 ··· 704 703 skylake_audio_card.dev = &pdev->dev; 705 704 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 706 705 707 - mach = (&pdev->dev)->platform_data; 706 + mach = pdev->dev.platform_data; 708 707 if (mach) 709 708 dmic_constraints = mach->mach_params.dmic_num == 2 ? 710 709 &constraints_dmic_2ch : &constraints_dmic_channels;
+4 -4
sound/soc/intel/boards/skl_rt286.c
··· 112 112 static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) 113 113 { 114 114 struct snd_soc_dapm_context *dapm; 115 - struct snd_soc_component *component = rtd->cpu_dai->component; 115 + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; 116 116 117 117 dapm = snd_soc_component_get_dapm(component); 118 118 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); ··· 122 122 123 123 static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 124 124 { 125 - struct snd_soc_component *component = rtd->codec_dai->component; 125 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 126 126 int ret; 127 127 128 128 ret = snd_soc_card_jack_new(rtd->card, "Headset", ··· 143 143 static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) 144 144 { 145 145 struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); 146 - struct snd_soc_dai *dai = rtd->codec_dai; 146 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 147 147 struct skl_hdmi_pcm *pcm; 148 148 149 149 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 229 229 struct snd_pcm_hw_params *params) 230 230 { 231 231 struct snd_soc_pcm_runtime *rtd = substream->private_data; 232 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 232 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 233 233 int ret; 234 234 235 235 ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000,
+75 -8
sound/soc/intel/boards/sof_da7219_max98373.c
··· 2 2 // Copyright(c) 2019 Intel Corporation. 3 3 4 4 /* 5 - * Intel SOF Machine driver for DA7219 + MAX98373 codec 5 + * Intel SOF Machine driver for DA7219 + MAX98373/MAX98360A codec 6 6 */ 7 7 8 8 #include <linux/input.h> ··· 69 69 SOC_DAPM_PIN_SWITCH("Right Spk"), 70 70 }; 71 71 72 + static const struct snd_kcontrol_new m98360a_controls[] = { 73 + SOC_DAPM_PIN_SWITCH("Headphone Jack"), 74 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 75 + SOC_DAPM_PIN_SWITCH("Spk"), 76 + }; 77 + 78 + /* For MAX98373 amp */ 72 79 static const struct snd_soc_dapm_widget widgets[] = { 73 80 SND_SOC_DAPM_HP("Headphone Jack", NULL), 74 81 SND_SOC_DAPM_MIC("Headset Mic", NULL), 82 + 75 83 SND_SOC_DAPM_SPK("Left Spk", NULL), 76 84 SND_SOC_DAPM_SPK("Right Spk", NULL), 85 + 77 86 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 78 87 platform_clock_control, SND_SOC_DAPM_POST_PMD | 79 88 SND_SOC_DAPM_PRE_PMU), ··· 92 83 { "Headphone Jack", NULL, "HPL" }, 93 84 { "Headphone Jack", NULL, "HPR" }, 94 85 86 + { "MIC", NULL, "Headset Mic" }, 87 + 88 + { "Headphone Jack", NULL, "Platform Clock" }, 89 + { "Headset Mic", NULL, "Platform Clock" }, 90 + 95 91 { "Left Spk", NULL, "Left BE_OUT" }, 96 92 { "Right Spk", NULL, "Right BE_OUT" }, 93 + }; 94 + 95 + /* For MAX98360A amp */ 96 + static const struct snd_soc_dapm_widget max98360a_widgets[] = { 97 + SND_SOC_DAPM_HP("Headphone Jack", NULL), 98 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 99 + 100 + SND_SOC_DAPM_SPK("Spk", NULL), 101 + 102 + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 103 + platform_clock_control, SND_SOC_DAPM_POST_PMD | 104 + SND_SOC_DAPM_PRE_PMU), 105 + }; 106 + 107 + static const struct snd_soc_dapm_route max98360a_map[] = { 108 + { "Headphone Jack", NULL, "HPL" }, 109 + { "Headphone Jack", NULL, "HPR" }, 97 110 98 111 { "MIC", NULL, "Headset Mic" }, 99 112 100 113 { "Headphone Jack", NULL, "Platform Clock" }, 101 114 { "Headset Mic", NULL, "Platform Clock" }, 115 + 116 + {"Spk", NULL, "Speaker"}, 102 117 }; 103 118 104 119 static struct snd_soc_jack headset; 105 120 106 121 static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) 107 122 { 108 - struct snd_soc_component *component = rtd->codec_dai->component; 109 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 123 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 124 + struct snd_soc_component *component = codec_dai->component; 110 125 struct snd_soc_jack *jack; 111 126 int ret; 112 127 ··· 173 140 int ret, j; 174 141 175 142 for (j = 0; j < runtime->num_codecs; j++) { 176 - struct snd_soc_dai *codec_dai = runtime->codec_dais[j]; 143 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, j); 177 144 178 145 if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { 179 146 /* vmon_slot_no = 0 imon_slot_no = 1 for TX slots */ ··· 214 181 static int hdmi_init(struct snd_soc_pcm_runtime *rtd) 215 182 { 216 183 struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 217 - struct snd_soc_dai *dai = rtd->codec_dai; 184 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 218 185 struct hdmi_pcm *pcm; 219 186 220 187 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 256 223 DAILINK_COMP_ARRAY( 257 224 /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, MAX98373_CODEC_DAI), 258 225 /* Right */ COMP_CODEC(MAXIM_DEV1_NAME, MAX98373_CODEC_DAI))); 226 + 227 + SND_SOC_DAILINK_DEF(ssp1_m98360a, 228 + DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi"))); 259 229 260 230 SND_SOC_DAILINK_DEF(dmic_pin, 261 231 DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); ··· 356 320 .late_probe = card_late_probe, 357 321 }; 358 322 323 + static struct snd_soc_card card_da7219_m98360a = { 324 + .name = "da7219max98360a", 325 + .owner = THIS_MODULE, 326 + .dai_link = dais, 327 + .num_links = ARRAY_SIZE(dais), 328 + .controls = m98360a_controls, 329 + .num_controls = ARRAY_SIZE(m98360a_controls), 330 + .dapm_widgets = max98360a_widgets, 331 + .num_dapm_widgets = ARRAY_SIZE(max98360a_widgets), 332 + .dapm_routes = max98360a_map, 333 + .num_dapm_routes = ARRAY_SIZE(max98360a_map), 334 + .fully_routed = true, 335 + .late_probe = card_late_probe, 336 + }; 337 + 359 338 static int audio_probe(struct platform_device *pdev) 360 339 { 361 340 static struct snd_soc_card *card; ··· 378 327 struct card_private *ctx; 379 328 int ret; 380 329 381 - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 330 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 382 331 if (!ctx) 383 332 return -ENOMEM; 333 + 334 + /* By default dais[0] is configured for max98373 */ 335 + if (!strcmp(pdev->name, "sof_da7219_max98360a")) { 336 + dais[0] = (struct snd_soc_dai_link) { 337 + .name = "SSP1-Codec", 338 + .id = 0, 339 + .no_pcm = 1, 340 + .dpcm_playback = 1, 341 + .ignore_pmdown_time = 1, 342 + SND_SOC_DAILINK_REG(ssp1_pin, ssp1_m98360a, platform) }; 343 + } 384 344 385 345 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 386 346 card = (struct snd_soc_card *)pdev->id_entry->driver_data; 387 347 card->dev = &pdev->dev; 388 348 389 - mach = (&pdev->dev)->platform_data; 349 + mach = pdev->dev.platform_data; 390 350 ret = snd_soc_fixup_dai_links_platform_name(card, 391 351 mach->mach_params.platform); 392 352 if (ret) ··· 413 351 .name = "sof_da7219_max98373", 414 352 .driver_data = (kernel_ulong_t)&card_da7219_m98373, 415 353 }, 354 + { 355 + .name = "sof_da7219_max98360a", 356 + .driver_data = (kernel_ulong_t)&card_da7219_m98360a, 357 + }, 416 358 { } 417 359 }; 418 360 419 361 static struct platform_driver audio = { 420 362 .probe = audio_probe, 421 363 .driver = { 422 - .name = "sof_da7219_max98373", 364 + .name = "sof_da7219_max98_360a_373", 423 365 .pm = &snd_soc_pm_ops, 424 366 }, 425 367 .id_table = board_ids, ··· 434 368 MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver"); 435 369 MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); 436 370 MODULE_LICENSE("GPL v2"); 371 + MODULE_ALIAS("platform:sof_da7219_max98360a"); 437 372 MODULE_ALIAS("platform:sof_da7219_max98373");
+80
sound/soc/intel/boards/sof_maxim_common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright(c) 2020 Intel Corporation. All rights reserved. 4 + #include <linux/string.h> 5 + #include <sound/pcm.h> 6 + #include <sound/soc.h> 7 + #include <sound/soc-dai.h> 8 + #include <sound/soc-dapm.h> 9 + #include <uapi/sound/asound.h> 10 + #include "sof_maxim_common.h" 11 + 12 + static const struct snd_soc_dapm_route max_98373_dapm_routes[] = { 13 + /* speaker */ 14 + { "Left Spk", NULL, "Left BE_OUT" }, 15 + { "Right Spk", NULL, "Right BE_OUT" }, 16 + }; 17 + 18 + static struct snd_soc_codec_conf max_98373_codec_conf[] = { 19 + { 20 + .dlc = COMP_CODEC_CONF(MAX_98373_DEV0_NAME), 21 + .name_prefix = "Right", 22 + }, 23 + { 24 + .dlc = COMP_CODEC_CONF(MAX_98373_DEV1_NAME), 25 + .name_prefix = "Left", 26 + }, 27 + }; 28 + 29 + struct snd_soc_dai_link_component max_98373_components[] = { 30 + { /* For Left */ 31 + .name = MAX_98373_DEV0_NAME, 32 + .dai_name = MAX_98373_CODEC_DAI, 33 + }, 34 + { /* For Right */ 35 + .name = MAX_98373_DEV1_NAME, 36 + .dai_name = MAX_98373_CODEC_DAI, 37 + }, 38 + }; 39 + 40 + static int max98373_hw_params(struct snd_pcm_substream *substream, 41 + struct snd_pcm_hw_params *params) 42 + { 43 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 44 + struct snd_soc_dai *codec_dai; 45 + int j; 46 + 47 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 48 + if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { 49 + /* DEV0 tdm slot configuration */ 50 + snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); 51 + } 52 + if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { 53 + /* DEV1 tdm slot configuration */ 54 + snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); 55 + } 56 + } 57 + return 0; 58 + } 59 + 60 + struct snd_soc_ops max_98373_ops = { 61 + .hw_params = max98373_hw_params, 62 + }; 63 + 64 + int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 65 + { 66 + struct snd_soc_card *card = rtd->card; 67 + int ret; 68 + 69 + ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 70 + ARRAY_SIZE(max_98373_dapm_routes)); 71 + if (ret) 72 + dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 73 + return ret; 74 + } 75 + 76 + void sof_max98373_codec_conf(struct snd_soc_card *card) 77 + { 78 + card->codec_conf = max_98373_codec_conf; 79 + card->num_configs = ARRAY_SIZE(max_98373_codec_conf); 80 + }
+24
sound/soc/intel/boards/sof_maxim_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright(c) 2020 Intel Corporation. 4 + */ 5 + 6 + /* 7 + * This file defines data structures used in Machine Driver for Intel 8 + * platforms with Maxim Codecs. 9 + */ 10 + #ifndef __SOF_MAXIM_COMMON_H 11 + #define __SOF_MAXIM_COMMON_H 12 + 13 + #include <sound/soc.h> 14 + 15 + #define MAX_98373_CODEC_DAI "max98373-aif1" 16 + #define MAX_98373_DEV0_NAME "i2c-MX98373:00" 17 + #define MAX_98373_DEV1_NAME "i2c-MX98373:01" 18 + 19 + extern struct snd_soc_dai_link_component max_98373_components[2]; 20 + extern struct snd_soc_ops max_98373_ops; 21 + 22 + int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd); 23 + void sof_max98373_codec_conf(struct snd_soc_card *card); 24 + #endif /* __SOF_MAXIM_COMMON_H */
+448
sound/soc/intel/boards/sof_pcm512x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright(c) 2018-2020 Intel Corporation. 3 + 4 + /* 5 + * Intel SOF Machine Driver for Intel platforms with TI PCM512x codec, 6 + * e.g. Up or Up2 with Hifiberry DAC+ HAT 7 + */ 8 + #include <linux/clk.h> 9 + #include <linux/dmi.h> 10 + #include <linux/i2c.h> 11 + #include <linux/input.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/types.h> 15 + #include <sound/core.h> 16 + #include <sound/jack.h> 17 + #include <sound/pcm.h> 18 + #include <sound/pcm_params.h> 19 + #include <sound/soc.h> 20 + #include <sound/soc-acpi.h> 21 + #include "../../codecs/pcm512x.h" 22 + #include "../common/soc-intel-quirks.h" 23 + #include "hda_dsp_common.h" 24 + 25 + #define NAME_SIZE 32 26 + 27 + #define SOF_PCM512X_SSP_CODEC(quirk) ((quirk) & GENMASK(3, 0)) 28 + #define SOF_PCM512X_SSP_CODEC_MASK (GENMASK(3, 0)) 29 + 30 + #define IDISP_CODEC_MASK 0x4 31 + 32 + /* Default: SSP5 */ 33 + static unsigned long sof_pcm512x_quirk = SOF_PCM512X_SSP_CODEC(5); 34 + 35 + static bool is_legacy_cpu; 36 + 37 + struct sof_hdmi_pcm { 38 + struct list_head head; 39 + struct snd_soc_dai *codec_dai; 40 + int device; 41 + }; 42 + 43 + struct sof_card_private { 44 + struct list_head hdmi_pcm_list; 45 + bool idisp_codec; 46 + }; 47 + 48 + static int sof_pcm512x_quirk_cb(const struct dmi_system_id *id) 49 + { 50 + sof_pcm512x_quirk = (unsigned long)id->driver_data; 51 + return 1; 52 + } 53 + 54 + static const struct dmi_system_id sof_pcm512x_quirk_table[] = { 55 + { 56 + .callback = sof_pcm512x_quirk_cb, 57 + .matches = { 58 + DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 59 + DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"), 60 + }, 61 + .driver_data = (void *)(SOF_PCM512X_SSP_CODEC(2)), 62 + }, 63 + {} 64 + }; 65 + 66 + static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) 67 + { 68 + struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 69 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 70 + struct sof_hdmi_pcm *pcm; 71 + 72 + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 73 + if (!pcm) 74 + return -ENOMEM; 75 + 76 + /* dai_link id is 1:1 mapped to the PCM device */ 77 + pcm->device = rtd->dai_link->id; 78 + pcm->codec_dai = dai; 79 + 80 + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 81 + 82 + return 0; 83 + } 84 + 85 + static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd) 86 + { 87 + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; 88 + 89 + snd_soc_component_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); 90 + snd_soc_component_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); 91 + snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 92 + 0x08, 0x08); 93 + 94 + return 0; 95 + } 96 + 97 + static int aif1_startup(struct snd_pcm_substream *substream) 98 + { 99 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; 101 + 102 + snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 103 + 0x08, 0x08); 104 + 105 + return 0; 106 + } 107 + 108 + static void aif1_shutdown(struct snd_pcm_substream *substream) 109 + { 110 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 111 + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; 112 + 113 + snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 114 + 0x08, 0x00); 115 + } 116 + 117 + static const struct snd_soc_ops sof_pcm512x_ops = { 118 + .startup = aif1_startup, 119 + .shutdown = aif1_shutdown, 120 + }; 121 + 122 + static struct snd_soc_dai_link_component platform_component[] = { 123 + { 124 + /* name might be overridden during probe */ 125 + .name = "0000:00:1f.3" 126 + } 127 + }; 128 + 129 + #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) 130 + static int sof_card_late_probe(struct snd_soc_card *card) 131 + { 132 + struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); 133 + struct sof_hdmi_pcm *pcm; 134 + 135 + /* HDMI is not supported by SOF on Baytrail/CherryTrail */ 136 + if (is_legacy_cpu) 137 + return 0; 138 + 139 + if (list_empty(&ctx->hdmi_pcm_list)) 140 + return -EINVAL; 141 + 142 + if (!ctx->idisp_codec) 143 + return 0; 144 + 145 + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head); 146 + 147 + return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component); 148 + } 149 + #else 150 + static int sof_card_late_probe(struct snd_soc_card *card) 151 + { 152 + return 0; 153 + } 154 + #endif 155 + 156 + static const struct snd_kcontrol_new sof_controls[] = { 157 + SOC_DAPM_PIN_SWITCH("Ext Spk"), 158 + }; 159 + 160 + static const struct snd_soc_dapm_widget sof_widgets[] = { 161 + SND_SOC_DAPM_SPK("Ext Spk", NULL), 162 + }; 163 + 164 + static const struct snd_soc_dapm_widget dmic_widgets[] = { 165 + SND_SOC_DAPM_MIC("SoC DMIC", NULL), 166 + }; 167 + 168 + static const struct snd_soc_dapm_route sof_map[] = { 169 + /* Speaker */ 170 + {"Ext Spk", NULL, "OUTR"}, 171 + {"Ext Spk", NULL, "OUTL"}, 172 + }; 173 + 174 + static const struct snd_soc_dapm_route dmic_map[] = { 175 + /* digital mics */ 176 + {"DMic", NULL, "SoC DMIC"}, 177 + }; 178 + 179 + static int dmic_init(struct snd_soc_pcm_runtime *rtd) 180 + { 181 + struct snd_soc_card *card = rtd->card; 182 + int ret; 183 + 184 + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, 185 + ARRAY_SIZE(dmic_widgets)); 186 + if (ret) { 187 + dev_err(card->dev, "DMic widget addition failed: %d\n", ret); 188 + /* Don't need to add routes if widget addition failed */ 189 + return ret; 190 + } 191 + 192 + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, 193 + ARRAY_SIZE(dmic_map)); 194 + 195 + if (ret) 196 + dev_err(card->dev, "DMic map addition failed: %d\n", ret); 197 + 198 + return ret; 199 + } 200 + 201 + /* sof audio machine driver for pcm512x codec */ 202 + static struct snd_soc_card sof_audio_card_pcm512x = { 203 + .name = "pcm512x", 204 + .owner = THIS_MODULE, 205 + .controls = sof_controls, 206 + .num_controls = ARRAY_SIZE(sof_controls), 207 + .dapm_widgets = sof_widgets, 208 + .num_dapm_widgets = ARRAY_SIZE(sof_widgets), 209 + .dapm_routes = sof_map, 210 + .num_dapm_routes = ARRAY_SIZE(sof_map), 211 + .fully_routed = true, 212 + .late_probe = sof_card_late_probe, 213 + }; 214 + 215 + SND_SOC_DAILINK_DEF(pcm512x_component, 216 + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-104C5122:00", "pcm512x-hifi"))); 217 + SND_SOC_DAILINK_DEF(dmic_component, 218 + DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); 219 + 220 + static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, 221 + int ssp_codec, 222 + int dmic_be_num, 223 + int hdmi_num, 224 + bool idisp_codec) 225 + { 226 + struct snd_soc_dai_link_component *idisp_components; 227 + struct snd_soc_dai_link_component *cpus; 228 + struct snd_soc_dai_link *links; 229 + int i, id = 0; 230 + 231 + links = devm_kcalloc(dev, sof_audio_card_pcm512x.num_links, 232 + sizeof(struct snd_soc_dai_link), GFP_KERNEL); 233 + cpus = devm_kcalloc(dev, sof_audio_card_pcm512x.num_links, 234 + sizeof(struct snd_soc_dai_link_component), GFP_KERNEL); 235 + if (!links || !cpus) 236 + goto devm_err; 237 + 238 + /* codec SSP */ 239 + links[id].name = devm_kasprintf(dev, GFP_KERNEL, 240 + "SSP%d-Codec", ssp_codec); 241 + if (!links[id].name) 242 + goto devm_err; 243 + 244 + links[id].id = id; 245 + links[id].codecs = pcm512x_component; 246 + links[id].num_codecs = ARRAY_SIZE(pcm512x_component); 247 + links[id].platforms = platform_component; 248 + links[id].num_platforms = ARRAY_SIZE(platform_component); 249 + links[id].init = sof_pcm512x_codec_init; 250 + links[id].ops = &sof_pcm512x_ops; 251 + links[id].nonatomic = true; 252 + links[id].dpcm_playback = 1; 253 + /* 254 + * capture only supported with specific versions of the Hifiberry DAC+ 255 + * links[id].dpcm_capture = 1; 256 + */ 257 + links[id].no_pcm = 1; 258 + links[id].cpus = &cpus[id]; 259 + links[id].num_cpus = 1; 260 + if (is_legacy_cpu) { 261 + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 262 + "ssp%d-port", 263 + ssp_codec); 264 + if (!links[id].cpus->dai_name) 265 + goto devm_err; 266 + } else { 267 + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 268 + "SSP%d Pin", 269 + ssp_codec); 270 + if (!links[id].cpus->dai_name) 271 + goto devm_err; 272 + } 273 + id++; 274 + 275 + /* dmic */ 276 + if (dmic_be_num > 0) { 277 + /* at least we have dmic01 */ 278 + links[id].name = "dmic01"; 279 + links[id].cpus = &cpus[id]; 280 + links[id].cpus->dai_name = "DMIC01 Pin"; 281 + links[id].init = dmic_init; 282 + if (dmic_be_num > 1) { 283 + /* set up 2 BE links at most */ 284 + links[id + 1].name = "dmic16k"; 285 + links[id + 1].cpus = &cpus[id + 1]; 286 + links[id + 1].cpus->dai_name = "DMIC16k Pin"; 287 + dmic_be_num = 2; 288 + } 289 + } 290 + 291 + for (i = 0; i < dmic_be_num; i++) { 292 + links[id].id = id; 293 + links[id].num_cpus = 1; 294 + links[id].codecs = dmic_component; 295 + links[id].num_codecs = ARRAY_SIZE(dmic_component); 296 + links[id].platforms = platform_component; 297 + links[id].num_platforms = ARRAY_SIZE(platform_component); 298 + links[id].ignore_suspend = 1; 299 + links[id].dpcm_capture = 1; 300 + links[id].no_pcm = 1; 301 + id++; 302 + } 303 + 304 + /* HDMI */ 305 + if (hdmi_num > 0) { 306 + idisp_components = devm_kcalloc(dev, hdmi_num, 307 + sizeof(struct snd_soc_dai_link_component), 308 + GFP_KERNEL); 309 + if (!idisp_components) 310 + goto devm_err; 311 + } 312 + for (i = 1; i <= hdmi_num; i++) { 313 + links[id].name = devm_kasprintf(dev, GFP_KERNEL, 314 + "iDisp%d", i); 315 + if (!links[id].name) 316 + goto devm_err; 317 + 318 + links[id].id = id; 319 + links[id].cpus = &cpus[id]; 320 + links[id].num_cpus = 1; 321 + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, 322 + "iDisp%d Pin", i); 323 + if (!links[id].cpus->dai_name) 324 + goto devm_err; 325 + 326 + /* 327 + * topology cannot be loaded if codec is missing, so 328 + * use the dummy codec if needed 329 + */ 330 + if (idisp_codec) { 331 + idisp_components[i - 1].name = "ehdaudio0D2"; 332 + idisp_components[i - 1].dai_name = 333 + devm_kasprintf(dev, GFP_KERNEL, 334 + "intel-hdmi-hifi%d", i); 335 + } else { 336 + idisp_components[i - 1].name = "snd-soc-dummy"; 337 + idisp_components[i - 1].dai_name = "snd-soc-dummy-dai"; 338 + } 339 + if (!idisp_components[i - 1].dai_name) 340 + goto devm_err; 341 + 342 + links[id].codecs = &idisp_components[i - 1]; 343 + links[id].num_codecs = 1; 344 + links[id].platforms = platform_component; 345 + links[id].num_platforms = ARRAY_SIZE(platform_component); 346 + links[id].init = sof_hdmi_init; 347 + links[id].dpcm_playback = 1; 348 + links[id].no_pcm = 1; 349 + id++; 350 + } 351 + 352 + return links; 353 + devm_err: 354 + return NULL; 355 + } 356 + 357 + static int sof_audio_probe(struct platform_device *pdev) 358 + { 359 + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; 360 + struct snd_soc_dai_link *dai_links; 361 + struct sof_card_private *ctx; 362 + int dmic_be_num, hdmi_num; 363 + int ret, ssp_codec; 364 + 365 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 366 + if (!ctx) 367 + return -ENOMEM; 368 + 369 + hdmi_num = 0; 370 + if (soc_intel_is_byt() || soc_intel_is_cht()) { 371 + is_legacy_cpu = true; 372 + dmic_be_num = 0; 373 + /* default quirk for legacy cpu */ 374 + sof_pcm512x_quirk = SOF_PCM512X_SSP_CODEC(2); 375 + } else { 376 + dmic_be_num = 2; 377 + #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) 378 + if (mach->mach_params.common_hdmi_codec_drv && 379 + (mach->mach_params.codec_mask & IDISP_CODEC_MASK)) 380 + ctx->idisp_codec = true; 381 + 382 + /* links are always present in topology */ 383 + hdmi_num = 3; 384 + #endif 385 + } 386 + 387 + dmi_check_system(sof_pcm512x_quirk_table); 388 + 389 + dev_dbg(&pdev->dev, "sof_pcm512x_quirk = %lx\n", sof_pcm512x_quirk); 390 + 391 + ssp_codec = sof_pcm512x_quirk & SOF_PCM512X_SSP_CODEC_MASK; 392 + 393 + /* compute number of dai links */ 394 + sof_audio_card_pcm512x.num_links = 1 + dmic_be_num + hdmi_num; 395 + 396 + dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, 397 + dmic_be_num, hdmi_num, 398 + ctx->idisp_codec); 399 + if (!dai_links) 400 + return -ENOMEM; 401 + 402 + sof_audio_card_pcm512x.dai_link = dai_links; 403 + 404 + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 405 + 406 + sof_audio_card_pcm512x.dev = &pdev->dev; 407 + 408 + /* set platform name for each dailink */ 409 + ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_pcm512x, 410 + mach->mach_params.platform); 411 + if (ret) 412 + return ret; 413 + 414 + snd_soc_card_set_drvdata(&sof_audio_card_pcm512x, ctx); 415 + 416 + return devm_snd_soc_register_card(&pdev->dev, 417 + &sof_audio_card_pcm512x); 418 + } 419 + 420 + static int sof_pcm512x_remove(struct platform_device *pdev) 421 + { 422 + struct snd_soc_card *card = platform_get_drvdata(pdev); 423 + struct snd_soc_component *component = NULL; 424 + 425 + for_each_card_components(card, component) { 426 + if (!strcmp(component->name, pcm512x_component[0].name)) { 427 + snd_soc_component_set_jack(component, NULL, NULL); 428 + break; 429 + } 430 + } 431 + 432 + return 0; 433 + } 434 + 435 + static struct platform_driver sof_audio = { 436 + .probe = sof_audio_probe, 437 + .remove = sof_pcm512x_remove, 438 + .driver = { 439 + .name = "sof_pcm512x", 440 + .pm = &snd_soc_pm_ops, 441 + }, 442 + }; 443 + module_platform_driver(sof_audio) 444 + 445 + MODULE_DESCRIPTION("ASoC Intel(R) SOF + PCM512x Machine driver"); 446 + MODULE_AUTHOR("Pierre-Louis Bossart"); 447 + MODULE_LICENSE("GPL v2"); 448 + MODULE_ALIAS("platform:sof_pcm512x");
+128 -9
sound/soc/intel/boards/sof_rt5682.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - // Copyright(c) 2019 Intel Corporation. 2 + // Copyright(c) 2019-2020 Intel Corporation. 3 3 4 4 /* 5 5 * Intel SOF Machine Driver with Realtek rt5682 Codec 6 - * and speaker codec MAX98357A 6 + * and speaker codec MAX98357A or RT1015. 7 7 */ 8 8 #include <linux/i2c.h> 9 9 #include <linux/input.h> ··· 18 18 #include <sound/soc.h> 19 19 #include <sound/rt5682.h> 20 20 #include <sound/soc-acpi.h> 21 + #include "../../codecs/rt1015.h" 21 22 #include "../../codecs/rt5682.h" 22 23 #include "../../codecs/hdac_hdmi.h" 23 24 #include "../common/soc-intel-quirks.h" 24 25 #include "hda_dsp_common.h" 26 + #include "sof_maxim_common.h" 25 27 26 28 #define NAME_SIZE 32 27 29 ··· 41 39 #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10)) 42 40 #define SOF_RT5682_NUM_HDMIDEV(quirk) \ 43 41 ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK) 42 + #define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(13) 43 + #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(14) 44 44 45 45 /* Default: MCLK on, MCLK 19.2M, SSP0 */ 46 46 static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | ··· 124 120 static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) 125 121 { 126 122 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 127 - struct snd_soc_dai *dai = rtd->codec_dai; 123 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 128 124 struct sof_hdmi_pcm *pcm; 129 125 130 126 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); ··· 143 139 static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) 144 140 { 145 141 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 146 - struct snd_soc_component *component = rtd->codec_dai->component; 142 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 147 143 struct snd_soc_jack *jack; 148 144 int ret; 149 145 ··· 211 207 { 212 208 struct snd_soc_pcm_runtime *rtd = substream->private_data; 213 209 struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); 214 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 210 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 215 211 int clk_id, clk_freq, pll_out, ret; 216 212 217 213 if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { ··· 262 258 263 259 static struct snd_soc_ops sof_rt5682_ops = { 264 260 .hw_params = sof_rt5682_hw_params, 261 + }; 262 + 263 + static int sof_rt1015_hw_params(struct snd_pcm_substream *substream, 264 + struct snd_pcm_hw_params *params) 265 + { 266 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 267 + struct snd_soc_card *card = rtd->card; 268 + struct snd_soc_dai *codec_dai; 269 + int i, ret; 270 + 271 + if (!snd_soc_card_get_codec_dai(card, "rt1015-aif")) 272 + return 0; 273 + 274 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 275 + ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, 276 + params_rate(params) * 50, 277 + params_rate(params) * 256); 278 + if (ret < 0) { 279 + dev_err(card->dev, "failed to set pll\n"); 280 + return ret; 281 + } 282 + /* Configure sysclk for codec */ 283 + ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, 284 + params_rate(params) * 256, 285 + SND_SOC_CLOCK_IN); 286 + if (ret < 0) { 287 + dev_err(card->dev, "failed to set sysclk\n"); 288 + return ret; 289 + } 290 + } 291 + 292 + return 0; 293 + } 294 + 295 + static struct snd_soc_ops sof_rt1015_ops = { 296 + .hw_params = sof_rt1015_hw_params, 265 297 }; 266 298 267 299 static struct snd_soc_dai_link_component platform_component[] = { ··· 356 316 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 357 317 SOC_DAPM_PIN_SWITCH("Headset Mic"), 358 318 SOC_DAPM_PIN_SWITCH("Spk"), 319 + SOC_DAPM_PIN_SWITCH("Left Spk"), 320 + SOC_DAPM_PIN_SWITCH("Right Spk"), 321 + 359 322 }; 360 323 361 324 static const struct snd_soc_dapm_widget sof_widgets[] = { 362 325 SND_SOC_DAPM_HP("Headphone Jack", NULL), 363 326 SND_SOC_DAPM_MIC("Headset Mic", NULL), 364 327 SND_SOC_DAPM_SPK("Spk", NULL), 328 + SND_SOC_DAPM_SPK("Left Spk", NULL), 329 + SND_SOC_DAPM_SPK("Right Spk", NULL), 365 330 }; 366 331 367 332 static const struct snd_soc_dapm_widget dmic_widgets[] = { ··· 387 342 { "Spk", NULL, "Speaker" }, 388 343 }; 389 344 345 + static const struct snd_soc_dapm_route speaker_map_lr[] = { 346 + { "Left Spk", NULL, "Left SPO" }, 347 + { "Right Spk", NULL, "Right SPO" }, 348 + }; 349 + 390 350 static const struct snd_soc_dapm_route dmic_map[] = { 391 351 /* digital mics */ 392 352 {"DMic", NULL, "SoC DMIC"}, 393 353 }; 354 + 355 + static int speaker_codec_init_lr(struct snd_soc_pcm_runtime *rtd) 356 + { 357 + return snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr, 358 + ARRAY_SIZE(speaker_map_lr)); 359 + } 394 360 395 361 static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) 396 362 { ··· 438 382 return ret; 439 383 } 440 384 385 + static struct snd_soc_codec_conf rt1015_amp_conf[] = { 386 + { 387 + .dlc = COMP_CODEC_CONF("i2c-10EC1015:00"), 388 + .name_prefix = "Left", 389 + }, 390 + { 391 + .dlc = COMP_CODEC_CONF("i2c-10EC1015:01"), 392 + .name_prefix = "Right", 393 + }, 394 + }; 395 + 441 396 /* sof audio machine driver for rt5682 codec */ 442 397 static struct snd_soc_card sof_audio_card_rt5682 = { 443 398 .name = "rt5682", /* the sof- prefix is added by the core */ ··· 482 415 .name = "MX98357A:00", 483 416 .dai_name = "HiFi", 484 417 } 418 + }; 419 + 420 + static struct snd_soc_dai_link_component rt1015_components[] = { 421 + { 422 + .name = "i2c-10EC1015:00", 423 + .dai_name = "rt1015-aif", 424 + }, 425 + { 426 + .name = "i2c-10EC1015:01", 427 + .dai_name = "rt1015-aif", 428 + }, 485 429 }; 486 430 487 431 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ··· 634 556 goto devm_err; 635 557 636 558 links[id].id = id; 637 - links[id].codecs = max98357a_component; 638 - links[id].num_codecs = ARRAY_SIZE(max98357a_component); 559 + if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { 560 + links[id].codecs = rt1015_components; 561 + links[id].num_codecs = ARRAY_SIZE(rt1015_components); 562 + links[id].init = speaker_codec_init_lr; 563 + links[id].ops = &sof_rt1015_ops; 564 + } else if (sof_rt5682_quirk & 565 + SOF_MAX98373_SPEAKER_AMP_PRESENT) { 566 + links[id].codecs = max_98373_components; 567 + links[id].num_codecs = ARRAY_SIZE(max_98373_components); 568 + links[id].init = max98373_spk_codec_init; 569 + links[id].ops = &max_98373_ops; 570 + } else { 571 + links[id].codecs = max98357a_component; 572 + links[id].num_codecs = ARRAY_SIZE(max98357a_component); 573 + links[id].init = speaker_codec_init; 574 + } 639 575 links[id].platforms = platform_component; 640 576 links[id].num_platforms = ARRAY_SIZE(platform_component); 641 - links[id].init = speaker_codec_init, 642 577 links[id].nonatomic = true; 643 578 links[id].dpcm_playback = 1; 644 579 links[id].no_pcm = 1; ··· 695 604 696 605 dmi_check_system(sof_rt5682_quirk_table); 697 606 698 - mach = (&pdev->dev)->platform_data; 607 + mach = pdev->dev.platform_data; 699 608 700 609 /* A speaker amp might not be present when the quirk claims one is. 701 610 * Detect this via whether the machine driver match includes quirk_data. ··· 753 662 if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) 754 663 sof_audio_card_rt5682.num_links++; 755 664 665 + if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) 666 + sof_max98373_codec_conf(&sof_audio_card_rt5682); 667 + 756 668 dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, 757 669 dmic_be_num, hdmi_num); 758 670 if (!dai_links) 759 671 return -ENOMEM; 760 672 761 673 sof_audio_card_rt5682.dai_link = dai_links; 674 + 675 + if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { 676 + sof_audio_card_rt5682.codec_conf = rt1015_amp_conf; 677 + sof_audio_card_rt5682.num_configs = ARRAY_SIZE(rt1015_amp_conf); 678 + } 762 679 763 680 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 764 681 ··· 813 714 SOF_RT5682_SSP_AMP(1) | 814 715 SOF_RT5682_NUM_HDMIDEV(4)), 815 716 }, 717 + { 718 + .name = "jsl_rt5682_rt1015", 719 + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 720 + SOF_RT5682_MCLK_24MHZ | 721 + SOF_RT5682_SSP_CODEC(0) | 722 + SOF_SPEAKER_AMP_PRESENT | 723 + SOF_RT1015_SPEAKER_AMP_PRESENT | 724 + SOF_RT5682_SSP_AMP(1)), 725 + }, 726 + { 727 + .name = "tgl_max98373_rt5682", 728 + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | 729 + SOF_RT5682_SSP_CODEC(0) | 730 + SOF_SPEAKER_AMP_PRESENT | 731 + SOF_MAX98373_SPEAKER_AMP_PRESENT | 732 + SOF_RT5682_SSP_AMP(1) | 733 + SOF_RT5682_NUM_HDMIDEV(4)), 734 + }, 816 735 { } 817 736 }; 818 737 ··· 852 735 MODULE_LICENSE("GPL v2"); 853 736 MODULE_ALIAS("platform:sof_rt5682"); 854 737 MODULE_ALIAS("platform:tgl_max98357a_rt5682"); 738 + MODULE_ALIAS("platform:jsl_rt5682_rt1015"); 739 + MODULE_ALIAS("platform:tgl_max98373_rt5682");
+962
sound/soc/intel/boards/sof_sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw - ASOC Machine driver for Intel SoundWire platforms 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/dmi.h> 10 + #include <linux/module.h> 11 + #include <linux/soundwire/sdw.h> 12 + #include <linux/soundwire/sdw_type.h> 13 + #include <sound/soc.h> 14 + #include <sound/soc-acpi.h> 15 + #include "sof_sdw_common.h" 16 + 17 + unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1; 18 + 19 + #define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) 20 + 21 + static int sof_sdw_quirk_cb(const struct dmi_system_id *id) 22 + { 23 + sof_sdw_quirk = (unsigned long)id->driver_data; 24 + return 1; 25 + } 26 + 27 + static const struct dmi_system_id sof_sdw_quirk_table[] = { 28 + { 29 + .callback = sof_sdw_quirk_cb, 30 + .matches = { 31 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 32 + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6") 33 + }, 34 + .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | 35 + SOF_RT715_DAI_ID_FIX), 36 + }, 37 + { 38 + /* early version of SKU 09C6 */ 39 + .callback = sof_sdw_quirk_cb, 40 + .matches = { 41 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 42 + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983") 43 + }, 44 + .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | 45 + SOF_RT715_DAI_ID_FIX), 46 + }, 47 + { 48 + .callback = sof_sdw_quirk_cb, 49 + .matches = { 50 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 51 + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"), 52 + }, 53 + .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | 54 + SOF_RT715_DAI_ID_FIX | 55 + SOF_SDW_FOUR_SPK), 56 + }, 57 + { 58 + .callback = sof_sdw_quirk_cb, 59 + .matches = { 60 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 61 + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"), 62 + }, 63 + .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | 64 + SOF_RT715_DAI_ID_FIX | 65 + SOF_SDW_FOUR_SPK), 66 + }, 67 + { 68 + .callback = sof_sdw_quirk_cb, 69 + .matches = { 70 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 71 + DMI_MATCH(DMI_PRODUCT_NAME, 72 + "Tiger Lake Client Platform"), 73 + }, 74 + .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 | 75 + SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | 76 + SOF_SSP_PORT(SOF_I2S_SSP2)), 77 + }, 78 + { 79 + .callback = sof_sdw_quirk_cb, 80 + .matches = { 81 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 82 + DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), 83 + }, 84 + .driver_data = (void *)SOF_SDW_PCH_DMIC, 85 + }, 86 + { 87 + .callback = sof_sdw_quirk_cb, 88 + .matches = { 89 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 90 + DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), 91 + }, 92 + .driver_data = (void *)SOF_SDW_PCH_DMIC, 93 + }, 94 + { 95 + .callback = sof_sdw_quirk_cb, 96 + .matches = { 97 + DMI_MATCH(DMI_SYS_VENDOR, "Google"), 98 + DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"), 99 + }, 100 + .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC), 101 + }, 102 + 103 + {} 104 + }; 105 + 106 + static struct snd_soc_codec_conf codec_conf[] = { 107 + { 108 + .dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"), 109 + .name_prefix = "rt711", 110 + }, 111 + /* rt1308 w/ I2S connection */ 112 + { 113 + .dlc = COMP_CODEC_CONF("i2c-10EC1308:00"), 114 + .name_prefix = "rt1308-1", 115 + }, 116 + /* rt1308 left on link 1 */ 117 + { 118 + .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0"), 119 + .name_prefix = "rt1308-1", 120 + }, 121 + /* two 1308s on link1 with different unique id */ 122 + { 123 + .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:0"), 124 + .name_prefix = "rt1308-1", 125 + }, 126 + { 127 + .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:2"), 128 + .name_prefix = "rt1308-2", 129 + }, 130 + /* rt1308 right on link 2 */ 131 + { 132 + .dlc = COMP_CODEC_CONF("sdw:2:25d:1308:0"), 133 + .name_prefix = "rt1308-2", 134 + }, 135 + { 136 + .dlc = COMP_CODEC_CONF("sdw:3:25d:715:0"), 137 + .name_prefix = "rt715", 138 + }, 139 + { 140 + .dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"), 141 + .name_prefix = "rt5682", 142 + }, 143 + }; 144 + 145 + static struct snd_soc_dai_link_component dmic_component[] = { 146 + { 147 + .name = "dmic-codec", 148 + .dai_name = "dmic-hifi", 149 + } 150 + }; 151 + 152 + static struct snd_soc_dai_link_component platform_component[] = { 153 + { 154 + /* name might be overridden during probe */ 155 + .name = "0000:00:1f.3" 156 + } 157 + }; 158 + 159 + /* these wrappers are only needed to avoid typecast compilation errors */ 160 + static int sdw_startup(struct snd_pcm_substream *substream) 161 + { 162 + return sdw_startup_stream(substream); 163 + } 164 + 165 + static void sdw_shutdown(struct snd_pcm_substream *substream) 166 + { 167 + sdw_shutdown_stream(substream); 168 + } 169 + 170 + static const struct snd_soc_ops sdw_ops = { 171 + .startup = sdw_startup, 172 + .shutdown = sdw_shutdown, 173 + }; 174 + 175 + static struct sof_sdw_codec_info codec_info_list[] = { 176 + { 177 + .id = 0x700, 178 + .direction = {true, true}, 179 + .dai_name = "rt700-aif1", 180 + .init = sof_sdw_rt700_init, 181 + }, 182 + { 183 + .id = 0x711, 184 + .direction = {true, true}, 185 + .dai_name = "rt711-aif1", 186 + .init = sof_sdw_rt711_init, 187 + }, 188 + { 189 + .id = 0x1308, 190 + .acpi_id = "10EC1308", 191 + .direction = {true, false}, 192 + .dai_name = "rt1308-aif", 193 + .ops = &sof_sdw_rt1308_i2s_ops, 194 + .init = sof_sdw_rt1308_init, 195 + }, 196 + { 197 + .id = 0x715, 198 + .direction = {false, true}, 199 + .dai_name = "rt715-aif2", 200 + .init = sof_sdw_rt715_init, 201 + }, 202 + { 203 + .id = 0x5682, 204 + .direction = {true, true}, 205 + .dai_name = "rt5682-sdw", 206 + .init = sof_sdw_rt5682_init, 207 + }, 208 + }; 209 + 210 + static inline int find_codec_info_part(unsigned int part_id) 211 + { 212 + int i; 213 + 214 + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 215 + if (part_id == codec_info_list[i].id) 216 + break; 217 + 218 + if (i == ARRAY_SIZE(codec_info_list)) 219 + return -EINVAL; 220 + 221 + return i; 222 + } 223 + 224 + static inline int find_codec_info_acpi(const u8 *acpi_id) 225 + { 226 + int i; 227 + 228 + if (!acpi_id[0]) 229 + return -EINVAL; 230 + 231 + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 232 + if (!memcmp(codec_info_list[i].acpi_id, acpi_id, 233 + ACPI_ID_LEN)) 234 + break; 235 + 236 + if (i == ARRAY_SIZE(codec_info_list)) 237 + return -EINVAL; 238 + 239 + return i; 240 + } 241 + 242 + /* 243 + * get BE dailink number and CPU DAI number based on sdw link adr. 244 + * Since some sdw slaves may be aggregated, the CPU DAI number 245 + * may be larger than the number of BE dailinks. 246 + */ 247 + static int get_sdw_dailink_info(const struct snd_soc_acpi_link_adr *links, 248 + int *sdw_be_num, int *sdw_cpu_dai_num) 249 + { 250 + const struct snd_soc_acpi_link_adr *link; 251 + bool group_visited[SDW_MAX_GROUPS]; 252 + bool no_aggregation; 253 + int i; 254 + 255 + no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 256 + *sdw_cpu_dai_num = 0; 257 + *sdw_be_num = 0; 258 + 259 + if (!links) 260 + return -EINVAL; 261 + 262 + for (i = 0; i < SDW_MAX_GROUPS; i++) 263 + group_visited[i] = false; 264 + 265 + for (link = links; link->num_adr; link++) { 266 + const struct snd_soc_acpi_endpoint *endpoint; 267 + int part_id, codec_index; 268 + int stream; 269 + u64 adr; 270 + 271 + adr = link->adr_d->adr; 272 + part_id = SDW_PART_ID(adr); 273 + codec_index = find_codec_info_part(part_id); 274 + if (codec_index < 0) 275 + return codec_index; 276 + 277 + endpoint = link->adr_d->endpoints; 278 + 279 + /* count DAI number for playback and capture */ 280 + for_each_pcm_streams(stream) { 281 + if (!codec_info_list[codec_index].direction[stream]) 282 + continue; 283 + 284 + (*sdw_cpu_dai_num)++; 285 + 286 + /* count BE for each non-aggregated slave or group */ 287 + if (!endpoint->aggregated || no_aggregation || 288 + !group_visited[endpoint->group_id]) 289 + (*sdw_be_num)++; 290 + } 291 + 292 + if (endpoint->aggregated) 293 + group_visited[endpoint->group_id] = true; 294 + } 295 + 296 + return 0; 297 + } 298 + 299 + static void init_dai_link(struct snd_soc_dai_link *dai_links, int be_id, 300 + char *name, int playback, int capture, 301 + struct snd_soc_dai_link_component *cpus, 302 + int cpus_num, 303 + struct snd_soc_dai_link_component *codecs, 304 + int codecs_num, 305 + int (*init)(struct snd_soc_pcm_runtime *rtd), 306 + const struct snd_soc_ops *ops) 307 + { 308 + dai_links->id = be_id; 309 + dai_links->name = name; 310 + dai_links->platforms = platform_component; 311 + dai_links->num_platforms = ARRAY_SIZE(platform_component); 312 + dai_links->nonatomic = true; 313 + dai_links->no_pcm = 1; 314 + dai_links->cpus = cpus; 315 + dai_links->num_cpus = cpus_num; 316 + dai_links->codecs = codecs; 317 + dai_links->num_codecs = codecs_num; 318 + dai_links->dpcm_playback = playback; 319 + dai_links->dpcm_capture = capture; 320 + dai_links->init = init; 321 + dai_links->ops = ops; 322 + } 323 + 324 + static bool is_unique_device(const struct snd_soc_acpi_link_adr *link, 325 + unsigned int sdw_version, 326 + unsigned int mfg_id, 327 + unsigned int part_id, 328 + unsigned int class_id, 329 + int index_in_link 330 + ) 331 + { 332 + int i; 333 + 334 + for (i = 0; i < link->num_adr; i++) { 335 + unsigned int sdw1_version, mfg1_id, part1_id, class1_id; 336 + u64 adr; 337 + 338 + /* skip itself */ 339 + if (i == index_in_link) 340 + continue; 341 + 342 + adr = link->adr_d[i].adr; 343 + 344 + sdw1_version = SDW_VERSION(adr); 345 + mfg1_id = SDW_MFG_ID(adr); 346 + part1_id = SDW_PART_ID(adr); 347 + class1_id = SDW_CLASS_ID(adr); 348 + 349 + if (sdw_version == sdw1_version && 350 + mfg_id == mfg1_id && 351 + part_id == part1_id && 352 + class_id == class1_id) 353 + return false; 354 + } 355 + 356 + return true; 357 + } 358 + 359 + static int create_codec_dai_name(struct device *dev, 360 + const struct snd_soc_acpi_link_adr *link, 361 + struct snd_soc_dai_link_component *codec, 362 + int offset) 363 + { 364 + int i; 365 + 366 + for (i = 0; i < link->num_adr; i++) { 367 + unsigned int sdw_version, unique_id, mfg_id; 368 + unsigned int link_id, part_id, class_id; 369 + int codec_index, comp_index; 370 + char *codec_str; 371 + u64 adr; 372 + 373 + adr = link->adr_d[i].adr; 374 + 375 + sdw_version = SDW_VERSION(adr); 376 + link_id = SDW_DISCO_LINK_ID(adr); 377 + unique_id = SDW_UNIQUE_ID(adr); 378 + mfg_id = SDW_MFG_ID(adr); 379 + part_id = SDW_PART_ID(adr); 380 + class_id = SDW_CLASS_ID(adr); 381 + 382 + comp_index = i + offset; 383 + if (is_unique_device(link, sdw_version, mfg_id, part_id, 384 + class_id, i)) { 385 + codec_str = "sdw:%x:%x:%x:%x"; 386 + codec[comp_index].name = 387 + devm_kasprintf(dev, GFP_KERNEL, codec_str, 388 + link_id, mfg_id, part_id, 389 + class_id); 390 + } else { 391 + codec_str = "sdw:%x:%x:%x:%x:%x"; 392 + codec[comp_index].name = 393 + devm_kasprintf(dev, GFP_KERNEL, codec_str, 394 + link_id, mfg_id, part_id, 395 + class_id, unique_id); 396 + } 397 + 398 + if (!codec[comp_index].name) 399 + return -ENOMEM; 400 + 401 + codec_index = find_codec_info_part(part_id); 402 + if (codec_index < 0) 403 + return codec_index; 404 + 405 + codec[comp_index].dai_name = 406 + codec_info_list[codec_index].dai_name; 407 + } 408 + 409 + return 0; 410 + } 411 + 412 + static int set_codec_init_func(const struct snd_soc_acpi_link_adr *link, 413 + struct snd_soc_dai_link *dai_links, 414 + bool playback) 415 + { 416 + int i; 417 + 418 + for (i = 0; i < link->num_adr; i++) { 419 + unsigned int part_id; 420 + int codec_index; 421 + 422 + part_id = SDW_PART_ID(link->adr_d[i].adr); 423 + codec_index = find_codec_info_part(part_id); 424 + 425 + if (codec_index < 0) 426 + return codec_index; 427 + 428 + if (codec_info_list[codec_index].init) 429 + codec_info_list[codec_index].init(link, dai_links, 430 + &codec_info_list[codec_index], 431 + playback); 432 + } 433 + 434 + return 0; 435 + } 436 + 437 + /* 438 + * check endpoint status in slaves and gather link ID for all slaves in 439 + * the same group to generate different CPU DAI. Now only support 440 + * one sdw link with all slaves set with only single group id. 441 + * 442 + * one slave on one sdw link with aggregated = 0 443 + * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI 444 + * 445 + * two or more slaves on one sdw link with aggregated = 0 446 + * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs 447 + * 448 + * multiple links with multiple slaves with aggregated = 1 449 + * one sdw BE DAI <---> 1 .. N CPU DAIs <----> 1 .. N codec DAIs 450 + */ 451 + static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, 452 + struct device *dev, int *cpu_dai_id, int *cpu_dai_num, 453 + int *codec_num, int *group_id, 454 + bool *group_generated) 455 + { 456 + const struct snd_soc_acpi_adr_device *adr_d; 457 + const struct snd_soc_acpi_link_adr *adr_next; 458 + bool no_aggregation; 459 + int index = 0; 460 + 461 + no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; 462 + *codec_num = adr_link->num_adr; 463 + adr_d = adr_link->adr_d; 464 + 465 + /* make sure the link mask has a single bit set */ 466 + if (!is_power_of_2(adr_link->mask)) 467 + return -EINVAL; 468 + 469 + cpu_dai_id[index++] = ffs(adr_link->mask) - 1; 470 + if (!adr_d->endpoints->aggregated || no_aggregation) { 471 + *cpu_dai_num = 1; 472 + *group_id = 0; 473 + return 0; 474 + } 475 + 476 + *group_id = adr_d->endpoints->group_id; 477 + 478 + /* gather other link ID of slaves in the same group */ 479 + for (adr_next = adr_link + 1; adr_next && adr_next->num_adr; 480 + adr_next++) { 481 + const struct snd_soc_acpi_endpoint *endpoint; 482 + 483 + endpoint = adr_next->adr_d->endpoints; 484 + if (!endpoint->aggregated || 485 + endpoint->group_id != *group_id) 486 + continue; 487 + 488 + /* make sure the link mask has a single bit set */ 489 + if (!is_power_of_2(adr_next->mask)) 490 + return -EINVAL; 491 + 492 + if (index >= SDW_MAX_CPU_DAIS) { 493 + dev_err(dev, " cpu_dai_id array overflows"); 494 + return -EINVAL; 495 + } 496 + 497 + cpu_dai_id[index++] = ffs(adr_next->mask) - 1; 498 + *codec_num += adr_next->num_adr; 499 + } 500 + 501 + /* 502 + * indicate CPU DAIs for this group have been generated 503 + * to avoid generating CPU DAIs for this group again. 504 + */ 505 + group_generated[*group_id] = true; 506 + *cpu_dai_num = index; 507 + 508 + return 0; 509 + } 510 + 511 + static int create_sdw_dailink(struct device *dev, int *be_index, 512 + struct snd_soc_dai_link *dai_links, 513 + int sdw_be_num, int sdw_cpu_dai_num, 514 + struct snd_soc_dai_link_component *cpus, 515 + const struct snd_soc_acpi_link_adr *link, 516 + int *cpu_id, bool *group_generated) 517 + { 518 + const struct snd_soc_acpi_link_adr *link_next; 519 + struct snd_soc_dai_link_component *codecs; 520 + int cpu_dai_id[SDW_MAX_CPU_DAIS]; 521 + int cpu_dai_num, cpu_dai_index; 522 + unsigned int part_id, group_id; 523 + int codec_idx = 0; 524 + int i = 0, j = 0; 525 + int codec_index; 526 + int codec_num; 527 + int stream; 528 + int ret; 529 + int k; 530 + 531 + ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num, 532 + &group_id, group_generated); 533 + if (ret) 534 + return ret; 535 + 536 + codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL); 537 + if (!codecs) 538 + return -ENOMEM; 539 + 540 + /* generate codec name on different links in the same group */ 541 + for (link_next = link; link_next && link_next->num_adr && 542 + i < cpu_dai_num; link_next++) { 543 + const struct snd_soc_acpi_endpoint *endpoints; 544 + 545 + endpoints = link_next->adr_d->endpoints; 546 + if (group_id && (!endpoints->aggregated || 547 + endpoints->group_id != group_id)) 548 + continue; 549 + 550 + /* skip the link excluded by this processed group */ 551 + if (cpu_dai_id[i] != ffs(link_next->mask) - 1) 552 + continue; 553 + 554 + ret = create_codec_dai_name(dev, link_next, codecs, codec_idx); 555 + if (ret < 0) 556 + return ret; 557 + 558 + /* check next link to create codec dai in the processed group */ 559 + i++; 560 + codec_idx += link_next->num_adr; 561 + } 562 + 563 + /* find codec info to create BE DAI */ 564 + part_id = SDW_PART_ID(link->adr_d[0].adr); 565 + codec_index = find_codec_info_part(part_id); 566 + if (codec_index < 0) 567 + return codec_index; 568 + 569 + cpu_dai_index = *cpu_id; 570 + for_each_pcm_streams(stream) { 571 + char *name, *cpu_name; 572 + int playback, capture; 573 + static const char * const sdw_stream_name[] = { 574 + "SDW%d-Playback", 575 + "SDW%d-Capture", 576 + }; 577 + 578 + if (!codec_info_list[codec_index].direction[stream]) 579 + continue; 580 + 581 + /* create stream name according to first link id */ 582 + name = devm_kasprintf(dev, GFP_KERNEL, 583 + sdw_stream_name[stream], cpu_dai_id[0]); 584 + if (!name) 585 + return -ENOMEM; 586 + 587 + /* 588 + * generate CPU DAI name base on the sdw link ID and 589 + * PIN ID with offset of 2 according to sdw dai driver. 590 + */ 591 + for (k = 0; k < cpu_dai_num; k++) { 592 + cpu_name = devm_kasprintf(dev, GFP_KERNEL, 593 + "SDW%d Pin%d", cpu_dai_id[k], 594 + j + SDW_INTEL_BIDIR_PDI_BASE); 595 + if (!cpu_name) 596 + return -ENOMEM; 597 + 598 + if (cpu_dai_index >= sdw_cpu_dai_num) { 599 + dev_err(dev, "invalid cpu dai index %d", 600 + cpu_dai_index); 601 + return -EINVAL; 602 + } 603 + 604 + cpus[cpu_dai_index++].dai_name = cpu_name; 605 + } 606 + 607 + if (*be_index >= sdw_be_num) { 608 + dev_err(dev, " invalid be dai index %d", *be_index); 609 + return -EINVAL; 610 + } 611 + 612 + if (*cpu_id >= sdw_cpu_dai_num) { 613 + dev_err(dev, " invalid cpu dai index %d", *cpu_id); 614 + return -EINVAL; 615 + } 616 + 617 + playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); 618 + capture = (stream == SNDRV_PCM_STREAM_CAPTURE); 619 + init_dai_link(dai_links + *be_index, *be_index, name, 620 + playback, capture, 621 + cpus + *cpu_id, cpu_dai_num, 622 + codecs, codec_num, 623 + NULL, &sdw_ops); 624 + 625 + ret = set_codec_init_func(link, dai_links + (*be_index)++, 626 + playback); 627 + if (ret < 0) { 628 + dev_err(dev, "failed to init codec %d", codec_index); 629 + return ret; 630 + } 631 + 632 + *cpu_id += cpu_dai_num; 633 + j++; 634 + } 635 + 636 + return 0; 637 + } 638 + 639 + /* 640 + * DAI link ID of SSP & DMIC & HDMI are based on last 641 + * link ID used by sdw link. Since be_id may be changed 642 + * in init func of sdw codec, it is not equal to be_id 643 + */ 644 + static inline int get_next_be_id(struct snd_soc_dai_link *links, 645 + int be_id) 646 + { 647 + return links[be_id - 1].id + 1; 648 + } 649 + 650 + static int sof_card_dai_links_create(struct device *dev, 651 + struct snd_soc_acpi_mach *mach, 652 + struct snd_soc_card *card) 653 + { 654 + int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num; 655 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 656 + struct snd_soc_dai_link_component *idisp_components; 657 + #endif 658 + struct snd_soc_dai_link_component *ssp_components; 659 + struct snd_soc_acpi_mach_params *mach_params; 660 + const struct snd_soc_acpi_link_adr *adr_link; 661 + struct snd_soc_dai_link_component *cpus; 662 + bool group_generated[SDW_MAX_GROUPS]; 663 + int ssp_codec_index, ssp_mask; 664 + struct snd_soc_dai_link *links; 665 + int num_links, link_id = 0; 666 + char *name, *cpu_name; 667 + int total_cpu_dai_num; 668 + int sdw_cpu_dai_num; 669 + int i, j, be_id = 0; 670 + int cpu_id = 0; 671 + int comp_num; 672 + int ret; 673 + 674 + /* reset amp_num to ensure amp_num++ starts from 0 in each probe */ 675 + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) 676 + codec_info_list[i].amp_num = 0; 677 + 678 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 679 + hdmi_num = sof_sdw_quirk & SOF_SDW_TGL_HDMI ? 680 + SOF_TGL_HDMI_COUNT : SOF_PRE_TGL_HDMI_COUNT; 681 + #endif 682 + 683 + ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); 684 + /* 685 + * on generic tgl platform, I2S or sdw mode is supported 686 + * based on board rework. A ACPI device is registered in 687 + * system only when I2S mode is supported, not sdw mode. 688 + * Here check ACPI ID to confirm I2S is supported. 689 + */ 690 + ssp_codec_index = find_codec_info_acpi(mach->id); 691 + ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0; 692 + comp_num = hdmi_num + ssp_num; 693 + 694 + mach_params = &mach->mach_params; 695 + ret = get_sdw_dailink_info(mach_params->links, 696 + &sdw_be_num, &sdw_cpu_dai_num); 697 + if (ret < 0) { 698 + dev_err(dev, "failed to get sdw link info %d", ret); 699 + return ret; 700 + } 701 + 702 + /* enable dmic01 & dmic16k */ 703 + dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0; 704 + comp_num += dmic_num; 705 + 706 + dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, 707 + dmic_num, hdmi_num); 708 + 709 + /* allocate BE dailinks */ 710 + num_links = comp_num + sdw_be_num; 711 + links = devm_kcalloc(dev, num_links, sizeof(*links), GFP_KERNEL); 712 + 713 + /* allocated CPU DAIs */ 714 + total_cpu_dai_num = comp_num + sdw_cpu_dai_num; 715 + cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), 716 + GFP_KERNEL); 717 + 718 + if (!links || !cpus) 719 + return -ENOMEM; 720 + 721 + /* SDW */ 722 + if (!sdw_be_num) 723 + goto SSP; 724 + 725 + adr_link = mach_params->links; 726 + if (!adr_link) 727 + return -EINVAL; 728 + 729 + /* 730 + * SoundWire Slaves aggregated in the same group may be 731 + * located on different hardware links. Clear array to indicate 732 + * CPU DAIs for this group have not been generated. 733 + */ 734 + for (i = 0; i < SDW_MAX_GROUPS; i++) 735 + group_generated[i] = false; 736 + 737 + /* generate DAI links by each sdw link */ 738 + for (; adr_link->num_adr; adr_link++) { 739 + const struct snd_soc_acpi_endpoint *endpoint; 740 + 741 + endpoint = adr_link->adr_d->endpoints; 742 + if (endpoint->aggregated && !endpoint->group_id) { 743 + dev_err(dev, "invalid group id on link %x", 744 + adr_link->mask); 745 + continue; 746 + } 747 + 748 + /* this group has been generated */ 749 + if (endpoint->aggregated && 750 + group_generated[endpoint->group_id]) 751 + continue; 752 + 753 + ret = create_sdw_dailink(dev, &be_id, links, sdw_be_num, 754 + sdw_cpu_dai_num, cpus, adr_link, 755 + &cpu_id, group_generated); 756 + if (ret < 0) { 757 + dev_err(dev, "failed to create dai link %d", be_id); 758 + return -ENOMEM; 759 + } 760 + } 761 + 762 + /* non-sdw DAI follows sdw DAI */ 763 + link_id = be_id; 764 + 765 + /* get BE ID for non-sdw DAI */ 766 + be_id = get_next_be_id(links, be_id); 767 + 768 + SSP: 769 + /* SSP */ 770 + if (!ssp_num) 771 + goto DMIC; 772 + 773 + for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { 774 + struct sof_sdw_codec_info *info; 775 + int playback, capture; 776 + char *codec_name; 777 + 778 + if (!(ssp_mask & 0x1)) 779 + continue; 780 + 781 + name = devm_kasprintf(dev, GFP_KERNEL, 782 + "SSP%d-Codec", i); 783 + if (!name) 784 + return -ENOMEM; 785 + 786 + cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); 787 + if (!cpu_name) 788 + return -ENOMEM; 789 + 790 + ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), 791 + GFP_KERNEL); 792 + if (!ssp_components) 793 + return -ENOMEM; 794 + 795 + info = &codec_info_list[ssp_codec_index]; 796 + codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", 797 + info->acpi_id, j++); 798 + if (!codec_name) 799 + return -ENOMEM; 800 + 801 + ssp_components->name = codec_name; 802 + ssp_components->dai_name = info->dai_name; 803 + cpus[cpu_id].dai_name = cpu_name; 804 + 805 + playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; 806 + capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; 807 + init_dai_link(links + link_id, be_id, name, 808 + playback, capture, 809 + cpus + cpu_id, 1, 810 + ssp_components, 1, 811 + NULL, info->ops); 812 + 813 + ret = info->init(NULL, links + link_id, info, 0); 814 + if (ret < 0) 815 + return ret; 816 + 817 + INC_ID(be_id, cpu_id, link_id); 818 + } 819 + 820 + DMIC: 821 + /* dmic */ 822 + if (dmic_num > 0) { 823 + cpus[cpu_id].dai_name = "DMIC01 Pin"; 824 + init_dai_link(links + link_id, be_id, "dmic01", 825 + 0, 1, // DMIC only supports capture 826 + cpus + cpu_id, 1, 827 + dmic_component, 1, 828 + sof_sdw_dmic_init, NULL); 829 + INC_ID(be_id, cpu_id, link_id); 830 + 831 + cpus[cpu_id].dai_name = "DMIC16k Pin"; 832 + init_dai_link(links + link_id, be_id, "dmic16k", 833 + 0, 1, // DMIC only supports capture 834 + cpus + cpu_id, 1, 835 + dmic_component, 1, 836 + /* don't call sof_sdw_dmic_init() twice */ 837 + NULL, NULL); 838 + INC_ID(be_id, cpu_id, link_id); 839 + } 840 + 841 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 842 + /* HDMI */ 843 + if (hdmi_num > 0) { 844 + idisp_components = devm_kcalloc(dev, hdmi_num, 845 + sizeof(*idisp_components), 846 + GFP_KERNEL); 847 + if (!idisp_components) 848 + return -ENOMEM; 849 + } 850 + 851 + for (i = 0; i < hdmi_num; i++) { 852 + name = devm_kasprintf(dev, GFP_KERNEL, 853 + "iDisp%d", i + 1); 854 + if (!name) 855 + return -ENOMEM; 856 + 857 + idisp_components[i].name = "ehdaudio0D2"; 858 + idisp_components[i].dai_name = devm_kasprintf(dev, 859 + GFP_KERNEL, 860 + "intel-hdmi-hifi%d", 861 + i + 1); 862 + if (!idisp_components[i].dai_name) 863 + return -ENOMEM; 864 + 865 + cpu_name = devm_kasprintf(dev, GFP_KERNEL, 866 + "iDisp%d Pin", i + 1); 867 + if (!cpu_name) 868 + return -ENOMEM; 869 + 870 + cpus[cpu_id].dai_name = cpu_name; 871 + init_dai_link(links + link_id, be_id, name, 872 + 1, 0, // HDMI only supports playback 873 + cpus + cpu_id, 1, 874 + idisp_components + i, 1, 875 + sof_sdw_hdmi_init, NULL); 876 + INC_ID(be_id, cpu_id, link_id); 877 + } 878 + #endif 879 + 880 + card->dai_link = links; 881 + card->num_links = num_links; 882 + 883 + return 0; 884 + } 885 + 886 + /* SoC card */ 887 + static const char sdw_card_long_name[] = "Intel Soundwire SOF"; 888 + 889 + static struct snd_soc_card card_sof_sdw = { 890 + .name = "soundwire", 891 + .late_probe = sof_sdw_hdmi_card_late_probe, 892 + .codec_conf = codec_conf, 893 + .num_configs = ARRAY_SIZE(codec_conf), 894 + }; 895 + 896 + static int mc_probe(struct platform_device *pdev) 897 + { 898 + struct snd_soc_card *card = &card_sof_sdw; 899 + struct snd_soc_acpi_mach *mach; 900 + struct mc_private *ctx; 901 + int ret; 902 + 903 + dev_dbg(&pdev->dev, "Entry %s\n", __func__); 904 + 905 + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 906 + if (!ctx) 907 + return -ENOMEM; 908 + 909 + dmi_check_system(sof_sdw_quirk_table); 910 + 911 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 912 + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 913 + #endif 914 + 915 + card->dev = &pdev->dev; 916 + 917 + mach = pdev->dev.platform_data; 918 + ret = sof_card_dai_links_create(&pdev->dev, mach, 919 + card); 920 + if (ret < 0) 921 + return ret; 922 + 923 + ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; 924 + 925 + snd_soc_card_set_drvdata(card, ctx); 926 + 927 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 928 + "cfg-spk:%d", 929 + (sof_sdw_quirk & SOF_SDW_FOUR_SPK) ? 4 : 2); 930 + if (!card->components) 931 + return -ENOMEM; 932 + 933 + card->long_name = sdw_card_long_name; 934 + 935 + /* Register the card */ 936 + ret = devm_snd_soc_register_card(&pdev->dev, card); 937 + if (ret) { 938 + dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); 939 + return ret; 940 + } 941 + 942 + platform_set_drvdata(pdev, card); 943 + 944 + return ret; 945 + } 946 + 947 + static struct platform_driver sof_sdw_driver = { 948 + .driver = { 949 + .name = "sof_sdw", 950 + .pm = &snd_soc_pm_ops, 951 + }, 952 + .probe = mc_probe, 953 + }; 954 + 955 + module_platform_driver(sof_sdw_driver); 956 + 957 + MODULE_DESCRIPTION("ASoC SoundWire Generic Machine driver"); 958 + MODULE_AUTHOR("Bard Liao <yung-chuan.liao@linux.intel.com>"); 959 + MODULE_AUTHOR("Rander Wang <rander.wang@linux.intel.com>"); 960 + MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>"); 961 + MODULE_LICENSE("GPL v2"); 962 + MODULE_ALIAS("platform:sof_sdw");
+114
sound/soc/intel/boards/sof_sdw_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * Copyright (c) 2020 Intel Corporation 3 + */ 4 + 5 + /* 6 + * sof_sdw_common.h - prototypes for common helpers 7 + */ 8 + 9 + #ifndef SND_SOC_SOF_SDW_COMMON_H 10 + #define SND_SOC_SOF_SDW_COMMON_H 11 + 12 + #include <linux/bits.h> 13 + #include <linux/types.h> 14 + 15 + #define MAX_NO_PROPS 2 16 + #define MAX_HDMI_NUM 4 17 + #define SDW_DMIC_DAI_ID 4 18 + #define SDW_MAX_CPU_DAIS 16 19 + #define SDW_INTEL_BIDIR_PDI_BASE 2 20 + 21 + /* 8 combinations with 4 links + unused group 0 */ 22 + #define SDW_MAX_GROUPS 9 23 + 24 + enum { 25 + SOF_RT711_JD_SRC_JD1 = 1, 26 + SOF_RT711_JD_SRC_JD2 = 2, 27 + }; 28 + 29 + enum { 30 + SOF_PRE_TGL_HDMI_COUNT = 3, 31 + SOF_TGL_HDMI_COUNT = 4, 32 + }; 33 + 34 + enum { 35 + SOF_I2S_SSP0 = BIT(0), 36 + SOF_I2S_SSP1 = BIT(1), 37 + SOF_I2S_SSP2 = BIT(2), 38 + SOF_I2S_SSP3 = BIT(3), 39 + SOF_I2S_SSP4 = BIT(4), 40 + SOF_I2S_SSP5 = BIT(5), 41 + }; 42 + 43 + #define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(1, 0)) 44 + #define SOF_SDW_FOUR_SPK BIT(2) 45 + #define SOF_SDW_TGL_HDMI BIT(3) 46 + #define SOF_SDW_PCH_DMIC BIT(4) 47 + #define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 5) 48 + #define SOF_SSP_GET_PORT(quirk) (((quirk) >> 5) & GENMASK(5, 0)) 49 + #define SOF_RT715_DAI_ID_FIX BIT(11) 50 + #define SOF_SDW_NO_AGGREGATION BIT(12) 51 + 52 + struct sof_sdw_codec_info { 53 + const int id; 54 + int amp_num; 55 + const u8 acpi_id[ACPI_ID_LEN]; 56 + const bool direction[2]; // playback & capture support 57 + const char *dai_name; 58 + const struct snd_soc_ops *ops; 59 + 60 + int (*init)(const struct snd_soc_acpi_link_adr *link, 61 + struct snd_soc_dai_link *dai_links, 62 + struct sof_sdw_codec_info *info, 63 + bool playback); 64 + }; 65 + 66 + struct mc_private { 67 + struct list_head hdmi_pcm_list; 68 + bool common_hdmi_codec_drv; 69 + struct snd_soc_jack sdw_headset; 70 + }; 71 + 72 + extern unsigned long sof_sdw_quirk; 73 + 74 + /* generic HDMI support */ 75 + int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd); 76 + 77 + int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card); 78 + 79 + /* DMIC support */ 80 + int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); 81 + 82 + /* RT711 support */ 83 + int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, 84 + struct snd_soc_dai_link *dai_links, 85 + struct sof_sdw_codec_info *info, 86 + bool playback); 87 + 88 + /* RT700 support */ 89 + int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link, 90 + struct snd_soc_dai_link *dai_links, 91 + struct sof_sdw_codec_info *info, 92 + bool playback); 93 + 94 + /* RT1308 support */ 95 + extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops; 96 + 97 + int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link, 98 + struct snd_soc_dai_link *dai_links, 99 + struct sof_sdw_codec_info *info, 100 + bool playback); 101 + 102 + /* RT715 support */ 103 + int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link, 104 + struct snd_soc_dai_link *dai_links, 105 + struct sof_sdw_codec_info *info, 106 + bool playback); 107 + 108 + /* RT5682 support */ 109 + int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link, 110 + struct snd_soc_dai_link *dai_links, 111 + struct sof_sdw_codec_info *info, 112 + bool playback); 113 + 114 + #endif
+42
sound/soc/intel/boards/sof_sdw_dmic.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_dmic - Helpers to handle dmic from generic machine driver 6 + */ 7 + 8 + #include <sound/soc.h> 9 + #include <sound/soc-acpi.h> 10 + #include "sof_sdw_common.h" 11 + 12 + static const struct snd_soc_dapm_widget dmic_widgets[] = { 13 + SND_SOC_DAPM_MIC("SoC DMIC", NULL), 14 + }; 15 + 16 + static const struct snd_soc_dapm_route dmic_map[] = { 17 + /* digital mics */ 18 + {"DMic", NULL, "SoC DMIC"}, 19 + }; 20 + 21 + int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd) 22 + { 23 + struct snd_soc_card *card = rtd->card; 24 + int ret; 25 + 26 + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, 27 + ARRAY_SIZE(dmic_widgets)); 28 + if (ret) { 29 + dev_err(card->dev, "DMic widget addition failed: %d\n", ret); 30 + /* Don't need to add routes if widget addition failed */ 31 + return ret; 32 + } 33 + 34 + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, 35 + ARRAY_SIZE(dmic_map)); 36 + 37 + if (ret) 38 + dev_err(card->dev, "DMic map addition failed: %d\n", ret); 39 + 40 + return ret; 41 + } 42 +
+97
sound/soc/intel/boards/sof_sdw_hdmi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_hdmi - Helpers to handle HDMI from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <linux/kernel.h> 11 + #include <linux/list.h> 12 + #include <sound/soc.h> 13 + #include <sound/soc-acpi.h> 14 + #include <sound/jack.h> 15 + #include "sof_sdw_common.h" 16 + #include "../../codecs/hdac_hdmi.h" 17 + #include "hda_dsp_common.h" 18 + 19 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 20 + static struct snd_soc_jack hdmi[MAX_HDMI_NUM]; 21 + 22 + struct hdmi_pcm { 23 + struct list_head head; 24 + struct snd_soc_dai *codec_dai; 25 + int device; 26 + }; 27 + 28 + int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd) 29 + { 30 + struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); 31 + struct snd_soc_dai *dai = rtd->codec_dai; 32 + struct hdmi_pcm *pcm; 33 + 34 + pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); 35 + if (!pcm) 36 + return -ENOMEM; 37 + 38 + /* dai_link id is 1:1 mapped to the PCM device */ 39 + pcm->device = rtd->dai_link->id; 40 + pcm->codec_dai = dai; 41 + 42 + list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); 43 + 44 + return 0; 45 + } 46 + 47 + #define NAME_SIZE 32 48 + int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) 49 + { 50 + struct mc_private *ctx = snd_soc_card_get_drvdata(card); 51 + struct hdmi_pcm *pcm; 52 + struct snd_soc_component *component = NULL; 53 + int err, i = 0; 54 + char jack_name[NAME_SIZE]; 55 + 56 + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, 57 + head); 58 + component = pcm->codec_dai->component; 59 + 60 + if (ctx->common_hdmi_codec_drv) 61 + return hda_dsp_hdmi_build_controls(card, component); 62 + 63 + list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { 64 + component = pcm->codec_dai->component; 65 + snprintf(jack_name, sizeof(jack_name), 66 + "HDMI/DP, pcm=%d Jack", pcm->device); 67 + err = snd_soc_card_jack_new(card, jack_name, 68 + SND_JACK_AVOUT, &hdmi[i], 69 + NULL, 0); 70 + 71 + if (err) 72 + return err; 73 + 74 + err = snd_jack_add_new_kctl(hdmi[i].jack, 75 + jack_name, SND_JACK_AVOUT); 76 + if (err) 77 + dev_warn(component->dev, "failed creating Jack kctl\n"); 78 + 79 + err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, 80 + &hdmi[i]); 81 + if (err < 0) 82 + return err; 83 + 84 + i++; 85 + } 86 + 87 + if (!component) 88 + return -EINVAL; 89 + 90 + return hdac_hdmi_jack_port_init(component, &card->dapm); 91 + } 92 + #else 93 + int hdmi_card_late_probe(struct snd_soc_card *card) 94 + { 95 + return 0; 96 + } 97 + #endif
+151
sound/soc/intel/boards/sof_sdw_rt1308.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_rt1308 - Helpers to handle RT1308 from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <sound/soc.h> 11 + #include <sound/soc-acpi.h> 12 + #include "sof_sdw_common.h" 13 + #include "../../codecs/rt1308.h" 14 + 15 + static const struct snd_soc_dapm_widget rt1308_widgets[] = { 16 + SND_SOC_DAPM_SPK("Speaker", NULL), 17 + }; 18 + 19 + /* 20 + * dapm routes for rt1308 will be registered dynamically according 21 + * to the number of rt1308 used. The first two entries will be registered 22 + * for one codec case, and the last two entries are also registered 23 + * if two 1308s are used. 24 + */ 25 + static const struct snd_soc_dapm_route rt1308_map[] = { 26 + { "Speaker", NULL, "rt1308-1 SPOL" }, 27 + { "Speaker", NULL, "rt1308-1 SPOR" }, 28 + { "Speaker", NULL, "rt1308-2 SPOL" }, 29 + { "Speaker", NULL, "rt1308-2 SPOR" }, 30 + }; 31 + 32 + static const struct snd_kcontrol_new rt1308_controls[] = { 33 + SOC_DAPM_PIN_SWITCH("Speaker"), 34 + }; 35 + 36 + static int first_spk_init(struct snd_soc_pcm_runtime *rtd) 37 + { 38 + struct snd_soc_card *card = rtd->card; 39 + int ret; 40 + 41 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 42 + "%s spk:rt1308", 43 + card->components); 44 + if (!card->components) 45 + return -ENOMEM; 46 + 47 + ret = snd_soc_add_card_controls(card, rt1308_controls, 48 + ARRAY_SIZE(rt1308_controls)); 49 + if (ret) { 50 + dev_err(card->dev, "rt1308 controls addition failed: %d\n", ret); 51 + return ret; 52 + } 53 + 54 + ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_widgets, 55 + ARRAY_SIZE(rt1308_widgets)); 56 + if (ret) { 57 + dev_err(card->dev, "rt1308 widgets addition failed: %d\n", ret); 58 + return ret; 59 + } 60 + 61 + ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map, 2); 62 + if (ret) 63 + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); 64 + 65 + return ret; 66 + } 67 + 68 + static int second_spk_init(struct snd_soc_pcm_runtime *rtd) 69 + { 70 + struct snd_soc_card *card = rtd->card; 71 + int ret; 72 + 73 + ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map + 2, 2); 74 + if (ret) 75 + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); 76 + 77 + return ret; 78 + } 79 + 80 + static int all_spk_init(struct snd_soc_pcm_runtime *rtd) 81 + { 82 + int ret; 83 + 84 + ret = first_spk_init(rtd); 85 + if (ret) 86 + return ret; 87 + 88 + return second_spk_init(rtd); 89 + } 90 + 91 + static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, 92 + struct snd_pcm_hw_params *params) 93 + { 94 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 + struct snd_soc_card *card = rtd->card; 96 + struct snd_soc_dai *codec_dai = rtd->codec_dai; 97 + int clk_id, clk_freq, pll_out; 98 + int err; 99 + 100 + clk_id = RT1308_PLL_S_MCLK; 101 + clk_freq = 38400000; 102 + 103 + pll_out = params_rate(params) * 512; 104 + 105 + /* Set rt1308 pll */ 106 + err = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); 107 + if (err < 0) { 108 + dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", err); 109 + return err; 110 + } 111 + 112 + /* Set rt1308 sysclk */ 113 + err = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, 114 + SND_SOC_CLOCK_IN); 115 + if (err < 0) { 116 + dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", err); 117 + return err; 118 + } 119 + 120 + return 0; 121 + } 122 + 123 + /* machine stream operations */ 124 + struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { 125 + .hw_params = rt1308_i2s_hw_params, 126 + }; 127 + 128 + int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link, 129 + struct snd_soc_dai_link *dai_links, 130 + struct sof_sdw_codec_info *info, 131 + bool playback) 132 + { 133 + info->amp_num++; 134 + if (info->amp_num == 1) 135 + dai_links->init = first_spk_init; 136 + 137 + if (info->amp_num == 2) { 138 + /* 139 + * if two 1308s are in one dai link, the init function 140 + * in this dai link will be first set for the first speaker, 141 + * and it should be reset to initialize all speakers when 142 + * the second speaker is found. 143 + */ 144 + if (dai_links->init) 145 + dai_links->init = all_spk_init; 146 + else 147 + dai_links->init = second_spk_init; 148 + } 149 + 150 + return 0; 151 + }
+126
sound/soc/intel/boards/sof_sdw_rt5682.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_rt5682 - Helpers to handle RT5682 from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <linux/input.h> 11 + #include <linux/soundwire/sdw.h> 12 + #include <linux/soundwire/sdw_type.h> 13 + #include <sound/soc.h> 14 + #include <sound/soc-acpi.h> 15 + #include <sound/jack.h> 16 + #include "sof_sdw_common.h" 17 + 18 + static const struct snd_soc_dapm_widget rt5682_widgets[] = { 19 + SND_SOC_DAPM_HP("Headphone", NULL), 20 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 21 + }; 22 + 23 + static const struct snd_soc_dapm_route rt5682_map[] = { 24 + /*Headphones*/ 25 + { "Headphone", NULL, "rt5682 HPOL" }, 26 + { "Headphone", NULL, "rt5682 HPOR" }, 27 + { "rt5682 IN1P", NULL, "Headset Mic" }, 28 + }; 29 + 30 + static const struct snd_kcontrol_new rt5682_controls[] = { 31 + SOC_DAPM_PIN_SWITCH("Headphone"), 32 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 33 + }; 34 + 35 + static struct snd_soc_jack_pin rt5682_jack_pins[] = { 36 + { 37 + .pin = "Headphone", 38 + .mask = SND_JACK_HEADPHONE, 39 + }, 40 + { 41 + .pin = "Headset Mic", 42 + .mask = SND_JACK_MICROPHONE, 43 + }, 44 + }; 45 + 46 + static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd) 47 + { 48 + struct snd_soc_card *card = rtd->card; 49 + struct mc_private *ctx = snd_soc_card_get_drvdata(card); 50 + struct snd_soc_component *component = rtd->codec_dai->component; 51 + struct snd_soc_jack *jack; 52 + int ret; 53 + 54 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 55 + "%s hs:rt5682", 56 + card->components); 57 + if (!card->components) 58 + return -ENOMEM; 59 + 60 + ret = snd_soc_add_card_controls(card, rt5682_controls, 61 + ARRAY_SIZE(rt5682_controls)); 62 + if (ret) { 63 + dev_err(card->dev, "rt5682 control addition failed: %d\n", ret); 64 + return ret; 65 + } 66 + 67 + ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets, 68 + ARRAY_SIZE(rt5682_widgets)); 69 + if (ret) { 70 + dev_err(card->dev, "rt5682 widgets addition failed: %d\n", ret); 71 + return ret; 72 + } 73 + 74 + ret = snd_soc_dapm_add_routes(&card->dapm, rt5682_map, 75 + ARRAY_SIZE(rt5682_map)); 76 + 77 + if (ret) { 78 + dev_err(card->dev, "rt5682 map addition failed: %d\n", ret); 79 + return ret; 80 + } 81 + 82 + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 83 + SND_JACK_HEADSET | SND_JACK_BTN_0 | 84 + SND_JACK_BTN_1 | SND_JACK_BTN_2 | 85 + SND_JACK_BTN_3, 86 + &ctx->sdw_headset, 87 + rt5682_jack_pins, 88 + ARRAY_SIZE(rt5682_jack_pins)); 89 + if (ret) { 90 + dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", 91 + ret); 92 + return ret; 93 + } 94 + 95 + jack = &ctx->sdw_headset; 96 + 97 + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 98 + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 99 + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 100 + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 101 + 102 + ret = snd_soc_component_set_jack(component, jack, NULL); 103 + 104 + if (ret) 105 + dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", 106 + ret); 107 + 108 + return ret; 109 + } 110 + 111 + int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link, 112 + struct snd_soc_dai_link *dai_links, 113 + struct sof_sdw_codec_info *info, 114 + bool playback) 115 + { 116 + /* 117 + * headset should be initialized once. 118 + * Do it with dai link for playback. 119 + */ 120 + if (!playback) 121 + return 0; 122 + 123 + dai_links->init = rt5682_rtd_init; 124 + 125 + return 0; 126 + }
+125
sound/soc/intel/boards/sof_sdw_rt700.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <linux/input.h> 11 + #include <sound/soc.h> 12 + #include <sound/soc-acpi.h> 13 + #include <sound/jack.h> 14 + #include "sof_sdw_common.h" 15 + 16 + static const struct snd_soc_dapm_widget rt700_widgets[] = { 17 + SND_SOC_DAPM_HP("Headphones", NULL), 18 + SND_SOC_DAPM_MIC("AMIC", NULL), 19 + SND_SOC_DAPM_SPK("Speaker", NULL), 20 + }; 21 + 22 + static const struct snd_soc_dapm_route rt700_map[] = { 23 + /* Headphones */ 24 + { "Headphones", NULL, "HP" }, 25 + { "Speaker", NULL, "SPK" }, 26 + { "MIC2", NULL, "AMIC" }, 27 + }; 28 + 29 + static const struct snd_kcontrol_new rt700_controls[] = { 30 + SOC_DAPM_PIN_SWITCH("Headphones"), 31 + SOC_DAPM_PIN_SWITCH("AMIC"), 32 + SOC_DAPM_PIN_SWITCH("Speaker"), 33 + }; 34 + 35 + static struct snd_soc_jack_pin rt700_jack_pins[] = { 36 + { 37 + .pin = "Headphones", 38 + .mask = SND_JACK_HEADPHONE, 39 + }, 40 + { 41 + .pin = "AMIC", 42 + .mask = SND_JACK_MICROPHONE, 43 + }, 44 + }; 45 + 46 + static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd) 47 + { 48 + struct snd_soc_card *card = rtd->card; 49 + struct mc_private *ctx = snd_soc_card_get_drvdata(card); 50 + struct snd_soc_component *component = rtd->codec_dai->component; 51 + struct snd_soc_jack *jack; 52 + int ret; 53 + 54 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 55 + "%s hs:rt700", 56 + card->components); 57 + if (!card->components) 58 + return -ENOMEM; 59 + 60 + ret = snd_soc_add_card_controls(card, rt700_controls, 61 + ARRAY_SIZE(rt700_controls)); 62 + if (ret) { 63 + dev_err(card->dev, "rt700 controls addition failed: %d\n", ret); 64 + return ret; 65 + } 66 + 67 + ret = snd_soc_dapm_new_controls(&card->dapm, rt700_widgets, 68 + ARRAY_SIZE(rt700_widgets)); 69 + if (ret) { 70 + dev_err(card->dev, "rt700 widgets addition failed: %d\n", ret); 71 + return ret; 72 + } 73 + 74 + ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map, 75 + ARRAY_SIZE(rt700_map)); 76 + 77 + if (ret) { 78 + dev_err(card->dev, "rt700 map addition failed: %d\n", ret); 79 + return ret; 80 + } 81 + 82 + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 83 + SND_JACK_HEADSET | SND_JACK_BTN_0 | 84 + SND_JACK_BTN_1 | SND_JACK_BTN_2 | 85 + SND_JACK_BTN_3, 86 + &ctx->sdw_headset, 87 + rt700_jack_pins, 88 + ARRAY_SIZE(rt700_jack_pins)); 89 + if (ret) { 90 + dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", 91 + ret); 92 + return ret; 93 + } 94 + 95 + jack = &ctx->sdw_headset; 96 + 97 + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_VOLUMEUP); 98 + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_PLAYPAUSE); 99 + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 100 + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 101 + 102 + ret = snd_soc_component_set_jack(component, jack, NULL); 103 + if (ret) 104 + dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", 105 + ret); 106 + 107 + return ret; 108 + } 109 + 110 + int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link, 111 + struct snd_soc_dai_link *dai_links, 112 + struct sof_sdw_codec_info *info, 113 + bool playback) 114 + { 115 + /* 116 + * headset should be initialized once. 117 + * Do it with dai link for playback. 118 + */ 119 + if (!playback) 120 + return 0; 121 + 122 + dai_links->init = rt700_rtd_init; 123 + 124 + return 0; 125 + }
+156
sound/soc/intel/boards/sof_sdw_rt711.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_rt711 - Helpers to handle RT711 from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <linux/input.h> 11 + #include <linux/soundwire/sdw.h> 12 + #include <linux/soundwire/sdw_type.h> 13 + #include <sound/soc.h> 14 + #include <sound/soc-acpi.h> 15 + #include <sound/jack.h> 16 + #include "sof_sdw_common.h" 17 + 18 + /* 19 + * Note this MUST be called before snd_soc_register_card(), so that the props 20 + * are in place before the codec component driver's probe function parses them. 21 + */ 22 + static int rt711_add_codec_device_props(const char *sdw_dev_name) 23 + { 24 + struct property_entry props[MAX_NO_PROPS] = {}; 25 + struct device *sdw_dev; 26 + int ret; 27 + 28 + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name); 29 + if (!sdw_dev) 30 + return -EPROBE_DEFER; 31 + 32 + if (SOF_RT711_JDSRC(sof_sdw_quirk)) { 33 + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", 34 + SOF_RT711_JDSRC(sof_sdw_quirk)); 35 + } 36 + 37 + ret = device_add_properties(sdw_dev, props); 38 + put_device(sdw_dev); 39 + 40 + return ret; 41 + } 42 + 43 + static const struct snd_soc_dapm_widget rt711_widgets[] = { 44 + SND_SOC_DAPM_HP("Headphone", NULL), 45 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 46 + }; 47 + 48 + static const struct snd_soc_dapm_route rt711_map[] = { 49 + /* Headphones */ 50 + { "Headphone", NULL, "rt711 HP" }, 51 + { "rt711 MIC2", NULL, "Headset Mic" }, 52 + }; 53 + 54 + static const struct snd_kcontrol_new rt711_controls[] = { 55 + SOC_DAPM_PIN_SWITCH("Headphone"), 56 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 57 + }; 58 + 59 + static struct snd_soc_jack_pin rt711_jack_pins[] = { 60 + { 61 + .pin = "Headphone", 62 + .mask = SND_JACK_HEADPHONE, 63 + }, 64 + { 65 + .pin = "Headset Mic", 66 + .mask = SND_JACK_MICROPHONE, 67 + }, 68 + }; 69 + 70 + static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd) 71 + { 72 + struct snd_soc_card *card = rtd->card; 73 + struct mc_private *ctx = snd_soc_card_get_drvdata(card); 74 + struct snd_soc_component *component = rtd->codec_dai->component; 75 + struct snd_soc_jack *jack; 76 + int ret; 77 + 78 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 79 + "%s hs:rt711", 80 + card->components); 81 + if (!card->components) 82 + return -ENOMEM; 83 + 84 + ret = snd_soc_add_card_controls(card, rt711_controls, 85 + ARRAY_SIZE(rt711_controls)); 86 + if (ret) { 87 + dev_err(card->dev, "rt711 controls addition failed: %d\n", ret); 88 + return ret; 89 + } 90 + 91 + ret = snd_soc_dapm_new_controls(&card->dapm, rt711_widgets, 92 + ARRAY_SIZE(rt711_widgets)); 93 + if (ret) { 94 + dev_err(card->dev, "rt711 widgets addition failed: %d\n", ret); 95 + return ret; 96 + } 97 + 98 + ret = snd_soc_dapm_add_routes(&card->dapm, rt711_map, 99 + ARRAY_SIZE(rt711_map)); 100 + 101 + if (ret) { 102 + dev_err(card->dev, "rt711 map addition failed: %d\n", ret); 103 + return ret; 104 + } 105 + 106 + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", 107 + SND_JACK_HEADSET | SND_JACK_BTN_0 | 108 + SND_JACK_BTN_1 | SND_JACK_BTN_2 | 109 + SND_JACK_BTN_3, 110 + &ctx->sdw_headset, 111 + rt711_jack_pins, 112 + ARRAY_SIZE(rt711_jack_pins)); 113 + if (ret) { 114 + dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", 115 + ret); 116 + return ret; 117 + } 118 + 119 + jack = &ctx->sdw_headset; 120 + 121 + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_VOLUMEUP); 122 + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_PLAYPAUSE); 123 + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); 124 + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); 125 + 126 + ret = snd_soc_component_set_jack(component, jack, NULL); 127 + 128 + if (ret) 129 + dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", 130 + ret); 131 + 132 + return ret; 133 + } 134 + 135 + int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, 136 + struct snd_soc_dai_link *dai_links, 137 + struct sof_sdw_codec_info *info, 138 + bool playback) 139 + { 140 + int ret; 141 + 142 + /* 143 + * headset should be initialized once. 144 + * Do it with dai link for playback. 145 + */ 146 + if (!playback) 147 + return 0; 148 + 149 + ret = rt711_add_codec_device_props("sdw:0:25d:711:0"); 150 + if (ret < 0) 151 + return ret; 152 + 153 + dai_links->init = rt711_rtd_init; 154 + 155 + return 0; 156 + }
+42
sound/soc/intel/boards/sof_sdw_rt715.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2020 Intel Corporation 3 + 4 + /* 5 + * sof_sdw_rt715 - Helpers to handle RT715 from generic machine driver 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/errno.h> 10 + #include <sound/soc.h> 11 + #include <sound/soc-acpi.h> 12 + #include "sof_sdw_common.h" 13 + 14 + static int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd) 15 + { 16 + struct snd_soc_card *card = rtd->card; 17 + 18 + card->components = devm_kasprintf(card->dev, GFP_KERNEL, 19 + "%s mic:rt715", 20 + card->components); 21 + if (!card->components) 22 + return -ENOMEM; 23 + 24 + return 0; 25 + } 26 + 27 + int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link, 28 + struct snd_soc_dai_link *dai_links, 29 + struct sof_sdw_codec_info *info, 30 + bool playback) 31 + { 32 + /* 33 + * DAI ID is fixed at SDW_DMIC_DAI_ID for 715 to 34 + * keep sdw DMIC and HDMI setting static in UCM 35 + */ 36 + if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX) 37 + dai_links->id = SDW_DMIC_DAI_ID; 38 + 39 + dai_links->init = rt715_rtd_init; 40 + 41 + return 0; 42 + }
+1 -1
sound/soc/intel/common/soc-acpi-intel-bxt-match.c
··· 65 65 }, 66 66 { 67 67 .id = "104C5122", 68 - .drv_name = "bxt-pcm512x", 68 + .drv_name = "sof_pcm512x", 69 69 .sof_fw_filename = "sof-apl.ri", 70 70 .sof_tplg_filename = "sof-apl-pcm512x.tplg", 71 71 },
+7
sound/soc/intel/common/soc-acpi-intel-cht-match.c
··· 174 174 .sof_fw_filename = "sof-cht.ri", 175 175 .sof_tplg_filename = "sof-cht-cx2072x.tplg", 176 176 }, 177 + { 178 + .id = "104C5122", 179 + .drv_name = "sof_pcm512x", 180 + .sof_fw_filename = "sof-cht.ri", 181 + .sof_tplg_filename = "sof-cht-src-50khz-pcm512x.tplg", 182 + }, 183 + 177 184 #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) 178 185 /* 179 186 * This is always last in the table so that it is selected only when
+91 -20
sound/soc/intel/common/soc-acpi-intel-cml-match.c
··· 59 59 }; 60 60 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines); 61 61 62 - static const u64 rt711_0_adr[] = { 63 - 0x000010025D071100 62 + static const struct snd_soc_acpi_endpoint single_endpoint = { 63 + .num = 0, 64 + .aggregated = 0, 65 + .group_position = 0, 66 + .group_id = 0, 64 67 }; 65 68 66 - static const u64 rt1308_1_adr[] = { 67 - 0x000110025D130800 69 + static const struct snd_soc_acpi_endpoint spk_l_endpoint = { 70 + .num = 0, 71 + .aggregated = 1, 72 + .group_position = 0, 73 + .group_id = 1, 68 74 }; 69 75 70 - static const u64 rt1308_2_adr[] = { 71 - 0x000210025D130800 76 + static const struct snd_soc_acpi_endpoint spk_r_endpoint = { 77 + .num = 0, 78 + .aggregated = 1, 79 + .group_position = 1, 80 + .group_id = 1, 72 81 }; 73 82 74 - static const u64 rt715_3_adr[] = { 75 - 0x000310025D071500 83 + static const struct snd_soc_acpi_adr_device rt700_1_adr[] = { 84 + { 85 + .adr = 0x000110025D070000, 86 + .num_endpoints = 1, 87 + .endpoints = &single_endpoint, 88 + } 89 + }; 90 + 91 + static const struct snd_soc_acpi_link_adr cml_rvp[] = { 92 + { 93 + .mask = BIT(1), 94 + .num_adr = ARRAY_SIZE(rt700_1_adr), 95 + .adr_d = rt700_1_adr, 96 + }, 97 + {} 98 + }; 99 + 100 + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { 101 + { 102 + .adr = 0x000010025D071100, 103 + .num_endpoints = 1, 104 + .endpoints = &single_endpoint, 105 + } 106 + }; 107 + 108 + static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { 109 + { 110 + .adr = 0x000110025D130800, 111 + .num_endpoints = 1, 112 + .endpoints = &single_endpoint, 113 + } 114 + }; 115 + 116 + static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = { 117 + { 118 + .adr = 0x000210025D130800, 119 + .num_endpoints = 1, 120 + .endpoints = &single_endpoint, 121 + } 122 + }; 123 + 124 + static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = { 125 + { 126 + .adr = 0x000110025D130800, 127 + .num_endpoints = 1, 128 + .endpoints = &spk_l_endpoint, 129 + } 130 + }; 131 + 132 + static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = { 133 + { 134 + .adr = 0x000210025D130800, 135 + .num_endpoints = 1, 136 + .endpoints = &spk_r_endpoint, 137 + } 138 + }; 139 + 140 + static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { 141 + { 142 + .adr = 0x000310025D071500, 143 + .num_endpoints = 1, 144 + .endpoints = &single_endpoint, 145 + } 76 146 }; 77 147 78 148 static const struct snd_soc_acpi_link_adr cml_3_in_1_default[] = { 79 149 { 80 150 .mask = BIT(0), 81 151 .num_adr = ARRAY_SIZE(rt711_0_adr), 82 - .adr = rt711_0_adr, 152 + .adr_d = rt711_0_adr, 83 153 }, 84 154 { 85 155 .mask = BIT(1), 86 - .num_adr = ARRAY_SIZE(rt1308_1_adr), 87 - .adr = rt1308_1_adr, 156 + .num_adr = ARRAY_SIZE(rt1308_1_group1_adr), 157 + .adr_d = rt1308_1_group1_adr, 88 158 }, 89 159 { 90 160 .mask = BIT(2), 91 - .num_adr = ARRAY_SIZE(rt1308_2_adr), 92 - .adr = rt1308_2_adr, 161 + .num_adr = ARRAY_SIZE(rt1308_2_group1_adr), 162 + .adr_d = rt1308_2_group1_adr, 93 163 }, 94 164 { 95 165 .mask = BIT(3), 96 166 .num_adr = ARRAY_SIZE(rt715_3_adr), 97 - .adr = rt715_3_adr, 167 + .adr_d = rt715_3_adr, 98 168 }, 99 169 {} 100 170 }; ··· 173 103 { 174 104 .mask = BIT(0), 175 105 .num_adr = ARRAY_SIZE(rt711_0_adr), 176 - .adr = rt711_0_adr, 106 + .adr_d = rt711_0_adr, 177 107 }, 178 108 { 179 109 .mask = BIT(1), 180 110 .num_adr = ARRAY_SIZE(rt1308_1_adr), 181 - .adr = rt1308_1_adr, 111 + .adr_d = rt1308_1_adr, 182 112 }, 183 113 { 184 114 .mask = BIT(3), 185 115 .num_adr = ARRAY_SIZE(rt715_3_adr), 186 - .adr = rt715_3_adr, 116 + .adr_d = rt715_3_adr, 187 117 }, 188 118 {} 189 119 }; ··· 192 122 { 193 123 .link_mask = 0xF, /* 4 active links required */ 194 124 .links = cml_3_in_1_default, 195 - .drv_name = "sdw_rt711_rt1308_rt715", 125 + .drv_name = "sof_sdw", 196 126 .sof_fw_filename = "sof-cml.ri", 197 127 .sof_tplg_filename = "sof-cml-rt711-rt1308-rt715.tplg", 198 128 }, ··· 204 134 */ 205 135 .link_mask = 0xF, 206 136 .links = cml_3_in_1_mono_amp, 207 - .drv_name = "sdw_rt711_rt1308_rt715", 137 + .drv_name = "sof_sdw", 208 138 .sof_fw_filename = "sof-cml.ri", 209 139 .sof_tplg_filename = "sof-cml-rt711-rt1308-mono-rt715.tplg", 210 140 }, 211 141 { 212 142 .link_mask = 0x2, /* RT700 connected on Link1 */ 213 - .drv_name = "sdw_rt700", 143 + .links = cml_rvp, 144 + .drv_name = "sof_sdw", 214 145 .sof_fw_filename = "sof-cml.ri", 215 146 .sof_tplg_filename = "sof-cml-rt700.tplg", 216 147 },
+80 -23
sound/soc/intel/common/soc-acpi-intel-icl-match.c
··· 33 33 }; 34 34 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); 35 35 36 - static const u64 rt700_0_adr[] = { 37 - 0x000010025D070000 36 + static const struct snd_soc_acpi_endpoint single_endpoint = { 37 + .num = 0, 38 + .aggregated = 0, 39 + .group_position = 0, 40 + .group_id = 0, 41 + }; 42 + 43 + static const struct snd_soc_acpi_endpoint spk_l_endpoint = { 44 + .num = 0, 45 + .aggregated = 1, 46 + .group_position = 0, 47 + .group_id = 1, 48 + }; 49 + 50 + static const struct snd_soc_acpi_endpoint spk_r_endpoint = { 51 + .num = 0, 52 + .aggregated = 1, 53 + .group_position = 1, 54 + .group_id = 1, 55 + }; 56 + 57 + static const struct snd_soc_acpi_adr_device rt700_0_adr[] = { 58 + { 59 + .adr = 0x000010025D070000, 60 + .num_endpoints = 1, 61 + .endpoints = &single_endpoint, 62 + } 38 63 }; 39 64 40 65 static const struct snd_soc_acpi_link_adr icl_rvp[] = { 41 66 { 42 67 .mask = BIT(0), 43 68 .num_adr = ARRAY_SIZE(rt700_0_adr), 44 - .adr = rt700_0_adr, 69 + .adr_d = rt700_0_adr, 45 70 }, 46 71 {} 47 72 }; 48 73 49 - static const u64 rt711_0_adr[] = { 50 - 0x000010025D071100 74 + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { 75 + { 76 + .adr = 0x000010025D071100, 77 + .num_endpoints = 1, 78 + .endpoints = &single_endpoint, 79 + } 51 80 }; 52 81 53 - static const u64 rt1308_1_adr[] = { 54 - 0x000110025D130800 82 + static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { 83 + { 84 + .adr = 0x000110025D130800, 85 + .num_endpoints = 1, 86 + .endpoints = &single_endpoint, 87 + } 55 88 }; 56 89 57 - static const u64 rt1308_2_adr[] = { 58 - 0x000210025D130800 90 + static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = { 91 + { 92 + .adr = 0x000210025D130800, 93 + .num_endpoints = 1, 94 + .endpoints = &single_endpoint, 95 + } 59 96 }; 60 97 61 - static const u64 rt715_3_adr[] = { 62 - 0x000310025D071500 98 + static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = { 99 + { 100 + .adr = 0x000110025D130800, 101 + .num_endpoints = 1, 102 + .endpoints = &spk_l_endpoint, 103 + } 104 + }; 105 + 106 + static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = { 107 + { 108 + .adr = 0x000210025D130800, 109 + .num_endpoints = 1, 110 + .endpoints = &spk_r_endpoint, 111 + } 112 + }; 113 + 114 + static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { 115 + { 116 + .adr = 0x000310025D071500, 117 + .num_endpoints = 1, 118 + .endpoints = &single_endpoint, 119 + } 63 120 }; 64 121 65 122 static const struct snd_soc_acpi_link_adr icl_3_in_1_default[] = { 66 123 { 67 124 .mask = BIT(0), 68 125 .num_adr = ARRAY_SIZE(rt711_0_adr), 69 - .adr = rt711_0_adr, 126 + .adr_d = rt711_0_adr, 70 127 }, 71 128 { 72 129 .mask = BIT(1), 73 - .num_adr = ARRAY_SIZE(rt1308_1_adr), 74 - .adr = rt1308_1_adr, 130 + .num_adr = ARRAY_SIZE(rt1308_1_group1_adr), 131 + .adr_d = rt1308_1_group1_adr, 75 132 }, 76 133 { 77 134 .mask = BIT(2), 78 - .num_adr = ARRAY_SIZE(rt1308_2_adr), 79 - .adr = rt1308_2_adr, 135 + .num_adr = ARRAY_SIZE(rt1308_2_group1_adr), 136 + .adr_d = rt1308_2_group1_adr, 80 137 }, 81 138 { 82 139 .mask = BIT(3), 83 140 .num_adr = ARRAY_SIZE(rt715_3_adr), 84 - .adr = rt715_3_adr, 141 + .adr_d = rt715_3_adr, 85 142 }, 86 143 {} 87 144 }; ··· 147 90 { 148 91 .mask = BIT(0), 149 92 .num_adr = ARRAY_SIZE(rt711_0_adr), 150 - .adr = rt711_0_adr, 93 + .adr_d = rt711_0_adr, 151 94 }, 152 95 { 153 96 .mask = BIT(1), 154 97 .num_adr = ARRAY_SIZE(rt1308_1_adr), 155 - .adr = rt1308_1_adr, 98 + .adr_d = rt1308_1_adr, 156 99 }, 157 100 { 158 101 .mask = BIT(3), 159 102 .num_adr = ARRAY_SIZE(rt715_3_adr), 160 - .adr = rt715_3_adr, 103 + .adr_d = rt715_3_adr, 161 104 }, 162 105 {} 163 106 }; ··· 166 109 { 167 110 .link_mask = 0xF, /* 4 active links required */ 168 111 .links = icl_3_in_1_default, 169 - .drv_name = "sdw_rt711_rt1308_rt715", 112 + .drv_name = "sof_sdw", 170 113 .sof_fw_filename = "sof-icl.ri", 171 114 .sof_tplg_filename = "sof-icl-rt711-rt1308-rt715.tplg", 172 115 }, 173 116 { 174 117 .link_mask = 0xB, /* 3 active links required */ 175 118 .links = icl_3_in_1_mono_amp, 176 - .drv_name = "sdw_rt711_rt1308_rt715", 119 + .drv_name = "sof_sdw", 177 120 .sof_fw_filename = "sof-icl.ri", 178 121 .sof_tplg_filename = "sof-icl-rt711-rt1308-rt715-mono.tplg", 179 122 }, 180 123 { 181 124 .link_mask = 0x1, /* rt700 connected on link0 */ 182 125 .links = icl_rvp, 183 - .drv_name = "sdw_rt700", 126 + .drv_name = "sof_sdw", 184 127 .sof_fw_filename = "sof-icl.ri", 185 128 .sof_tplg_filename = "sof-icl-rt700.tplg", 186 129 },
+32 -2
sound/soc/intel/common/soc-acpi-intel-jsl-match.c
··· 2 2 /* 3 3 * soc-apci-intel-jsl-match.c - tables and support for JSL ACPI enumeration. 4 4 * 5 - * Copyright (c) 2019, Intel Corporation. 5 + * Copyright (c) 2019-2020, Intel Corporation. 6 6 * 7 7 */ 8 8 9 9 #include <sound/soc-acpi.h> 10 10 #include <sound/soc-acpi-intel-match.h> 11 11 12 + static struct snd_soc_acpi_codecs jsl_7219_98373_codecs = { 13 + .num_codecs = 1, 14 + .codecs = {"MX98373"} 15 + }; 16 + 17 + static struct snd_soc_acpi_codecs rt1015_spk = { 18 + .num_codecs = 1, 19 + .codecs = {"10EC1015"} 20 + }; 21 + 22 + /* 23 + * When adding new entry to the snd_soc_acpi_intel_jsl_machines array, 24 + * use .quirk_data member to distinguish different machine driver, 25 + * and keep ACPI .id field unchanged for the common codec. 26 + */ 12 27 struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { 13 28 { 14 29 .id = "DLGS7219", 15 30 .drv_name = "sof_da7219_max98373", 16 - .machine_quirk = snd_soc_acpi_codec_list, 17 31 .sof_fw_filename = "sof-jsl.ri", 18 32 .sof_tplg_filename = "sof-jsl-da7219.tplg", 33 + .machine_quirk = snd_soc_acpi_codec_list, 34 + .quirk_data = &jsl_7219_98373_codecs, 35 + }, 36 + { 37 + .id = "DLGS7219", 38 + .drv_name = "sof_da7219_max98360a", 39 + .sof_fw_filename = "sof-jsl.ri", 40 + .sof_tplg_filename = "sof-jsl-da7219-mx98360a.tplg", 41 + }, 42 + { 43 + .id = "10EC5682", 44 + .drv_name = "jsl_rt5682_rt1015", 45 + .sof_fw_filename = "sof-jsl.ri", 46 + .machine_quirk = snd_soc_acpi_codec_list, 47 + .quirk_data = &rt1015_spk, 48 + .sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg", 19 49 }, 20 50 {}, 21 51 };
+81 -11
sound/soc/intel/common/soc-acpi-intel-tgl-match.c
··· 14 14 .codecs = {"MX98357A"} 15 15 }; 16 16 17 - static const u64 rt711_0_adr[] = { 18 - 0x000010025D071100 17 + static const struct snd_soc_acpi_endpoint single_endpoint = { 18 + .num = 0, 19 + .aggregated = 0, 20 + .group_position = 0, 21 + .group_id = 0, 19 22 }; 20 23 21 - static const u64 rt1308_1_adr[] = { 22 - 0x000120025D130800, 23 - 0x000122025D130800 24 + static const struct snd_soc_acpi_endpoint spk_l_endpoint = { 25 + .num = 0, 26 + .aggregated = 1, 27 + .group_position = 0, 28 + .group_id = 1, 29 + }; 30 + 31 + static const struct snd_soc_acpi_endpoint spk_r_endpoint = { 32 + .num = 0, 33 + .aggregated = 1, 34 + .group_position = 1, 35 + .group_id = 1, 36 + }; 37 + 38 + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { 39 + { 40 + .adr = 0x000010025D071100, 41 + .num_endpoints = 1, 42 + .endpoints = &single_endpoint, 43 + } 44 + }; 45 + 46 + static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { 47 + { 48 + .adr = 0x000120025D130800, 49 + .num_endpoints = 1, 50 + .endpoints = &spk_l_endpoint, 51 + }, 52 + { 53 + .adr = 0x000122025D130800, 54 + .num_endpoints = 1, 55 + .endpoints = &spk_r_endpoint, 56 + } 57 + }; 58 + 59 + static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = { 60 + { 61 + .adr = 0x000021025D568200, 62 + .num_endpoints = 1, 63 + .endpoints = &single_endpoint, 64 + } 24 65 }; 25 66 26 67 static const struct snd_soc_acpi_link_adr tgl_i2s_rt1308[] = { 27 68 { 28 69 .mask = BIT(0), 29 70 .num_adr = ARRAY_SIZE(rt711_0_adr), 30 - .adr = rt711_0_adr, 71 + .adr_d = rt711_0_adr, 31 72 }, 32 73 {} 33 74 }; ··· 77 36 { 78 37 .mask = BIT(0), 79 38 .num_adr = ARRAY_SIZE(rt711_0_adr), 80 - .adr = rt711_0_adr, 39 + .adr_d = rt711_0_adr, 81 40 }, 82 41 { 83 42 .mask = BIT(1), 84 43 .num_adr = ARRAY_SIZE(rt1308_1_adr), 85 - .adr = rt1308_1_adr, 44 + .adr_d = rt1308_1_adr, 86 45 }, 87 46 {} 47 + }; 48 + 49 + static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { 50 + { 51 + .mask = BIT(0), 52 + .num_adr = ARRAY_SIZE(rt5682_0_adr), 53 + .adr_d = rt5682_0_adr, 54 + }, 55 + {} 56 + }; 57 + 58 + static struct snd_soc_acpi_codecs tgl_max98373_amp = { 59 + .num_codecs = 1, 60 + .codecs = {"MX98373"} 88 61 }; 89 62 90 63 struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = { 91 64 { 92 65 .id = "10EC1308", 93 - .drv_name = "rt711_rt1308", 66 + .drv_name = "sof_sdw", 94 67 .link_mask = 0x1, /* RT711 on SoundWire link0 */ 95 68 .links = tgl_i2s_rt1308, 96 69 .sof_fw_filename = "sof-tgl.ri", 97 - .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", 70 + .sof_tplg_filename = "sof-tgl-rt711-i2s-rt1308.tplg", 98 71 }, 99 72 { 100 73 .id = "10EC5682", ··· 117 62 .quirk_data = &tgl_codecs, 118 63 .sof_fw_filename = "sof-tgl.ri", 119 64 .sof_tplg_filename = "sof-tgl-max98357a-rt5682.tplg", 65 + }, 66 + { 67 + .id = "10EC5682", 68 + .drv_name = "tgl_max98373_rt5682", 69 + .machine_quirk = snd_soc_acpi_codec_list, 70 + .quirk_data = &tgl_max98373_amp, 71 + .sof_fw_filename = "sof-tgl.ri", 72 + .sof_tplg_filename = "sof-tgl-max98373-rt5682.tplg", 120 73 }, 121 74 {}, 122 75 }; ··· 135 72 { 136 73 .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ 137 74 .links = tgl_rvp, 138 - .drv_name = "sdw_rt711_rt1308_rt715", 75 + .drv_name = "sof_sdw", 139 76 .sof_fw_filename = "sof-tgl.ri", 140 77 .sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg", 78 + }, 79 + { 80 + .link_mask = 0x1, /* this will only enable rt5682 for now */ 81 + .links = tgl_chromebook_base, 82 + .drv_name = "sof_sdw", 83 + .sof_fw_filename = "sof-tgl.ri", 84 + .sof_tplg_filename = "sof-tgl-rt5682.tplg", 141 85 }, 142 86 {}, 143 87 };
+13 -13
sound/soc/intel/haswell/sst-haswell-pcm.c
··· 476 476 u8 channels; 477 477 int ret, dai; 478 478 479 - dai = mod_map[rtd->cpu_dai->id].dai_id; 479 + dai = mod_map[asoc_rtd_to_cpu(rtd, 0)->id].dai_id; 480 480 pcm_data = &pdata->pcm[dai][substream->stream]; 481 481 482 482 /* check if we are being called a subsequent time */ ··· 494 494 } 495 495 pcm_data->allocated = false; 496 496 497 - pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, 497 + pcm_data->stream = sst_hsw_stream_new(hsw, asoc_rtd_to_cpu(rtd, 0)->id, 498 498 hsw_notify_pointer, pcm_data); 499 499 if (pcm_data->stream == NULL) { 500 500 dev_err(rtd->dev, "error: failed to create stream\n"); ··· 509 509 path_id = SST_HSW_STREAM_PATH_SSP0_IN; 510 510 511 511 /* DSP stream type depends on DAI ID */ 512 - switch (rtd->cpu_dai->id) { 512 + switch (asoc_rtd_to_cpu(rtd, 0)->id) { 513 513 case 0: 514 514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 515 515 stream_type = SST_HSW_STREAM_TYPE_SYSTEM; ··· 533 533 break; 534 534 default: 535 535 dev_err(rtd->dev, "error: invalid DAI ID %d\n", 536 - rtd->cpu_dai->id); 536 + asoc_rtd_to_cpu(rtd, 0)->id); 537 537 return -EINVAL; 538 538 } 539 539 ··· 595 595 dmab = snd_pcm_get_dma_buf(substream); 596 596 597 597 ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area, 598 - runtime->dma_bytes, rtd->cpu_dai->id); 598 + runtime->dma_bytes, asoc_rtd_to_cpu(rtd, 0)->id); 599 599 if (ret < 0) 600 600 return ret; 601 601 ··· 608 608 pages = runtime->dma_bytes / PAGE_SIZE; 609 609 610 610 ret = sst_hsw_stream_buffer(hsw, pcm_data->stream, 611 - pdata->dmab[rtd->cpu_dai->id][substream->stream].addr, 611 + pdata->dmab[asoc_rtd_to_cpu(rtd, 0)->id][substream->stream].addr, 612 612 pages, runtime->dma_bytes, 0, 613 613 snd_sgbuf_get_addr(dmab, 0) >> PAGE_SHIFT); 614 614 if (ret < 0) { ··· 661 661 snd_pcm_uframes_t pos; 662 662 int dai; 663 663 664 - dai = mod_map[rtd->cpu_dai->id].dai_id; 664 + dai = mod_map[asoc_rtd_to_cpu(rtd, 0)->id].dai_id; 665 665 pcm_data = &pdata->pcm[dai][substream->stream]; 666 666 sst_stream = pcm_data->stream; 667 667 ··· 770 770 u32 position; 771 771 int dai; 772 772 773 - dai = mod_map[rtd->cpu_dai->id].dai_id; 773 + dai = mod_map[asoc_rtd_to_cpu(rtd, 0)->id].dai_id; 774 774 pcm_data = &pdata->pcm[dai][substream->stream]; 775 775 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); 776 776 ··· 791 791 struct sst_hsw *hsw = pdata->hsw; 792 792 int dai; 793 793 794 - dai = mod_map[rtd->cpu_dai->id].dai_id; 794 + dai = mod_map[asoc_rtd_to_cpu(rtd, 0)->id].dai_id; 795 795 pcm_data = &pdata->pcm[dai][substream->stream]; 796 796 797 797 mutex_lock(&pcm_data->mutex); ··· 801 801 802 802 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware); 803 803 804 - pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, 804 + pcm_data->stream = sst_hsw_stream_new(hsw, asoc_rtd_to_cpu(rtd, 0)->id, 805 805 hsw_notify_pointer, pcm_data); 806 806 if (pcm_data->stream == NULL) { 807 807 dev_err(rtd->dev, "error: failed to create stream\n"); ··· 824 824 struct sst_hsw *hsw = pdata->hsw; 825 825 int ret, dai; 826 826 827 - dai = mod_map[rtd->cpu_dai->id].dai_id; 827 + dai = mod_map[asoc_rtd_to_cpu(rtd, 0)->id].dai_id; 828 828 pcm_data = &pdata->pcm[dai][substream->stream]; 829 829 830 830 mutex_lock(&pcm_data->mutex); ··· 923 923 hsw_pcm_hardware.buffer_bytes_max); 924 924 } 925 925 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) 926 - priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm; 926 + priv_data->pcm[asoc_rtd_to_cpu(rtd, 0)->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm; 927 927 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) 928 - priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm; 928 + priv_data->pcm[asoc_rtd_to_cpu(rtd, 0)->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm; 929 929 930 930 return 0; 931 931 }
-3
sound/soc/intel/skylake/bxt-sst.c
··· 17 17 #include "skl.h" 18 18 19 19 #define BXT_BASEFW_TIMEOUT 3000 20 - #define BXT_INIT_TIMEOUT 300 21 20 #define BXT_ROM_INIT_TIMEOUT 70 22 21 #define BXT_IPC_PURGE_FW 0x01004000 23 22 ··· 36 37 37 38 /* Delay before scheduling D0i3 entry */ 38 39 #define BXT_D0I3_DELAY 5000 39 - 40 - #define BXT_FW_ROM_INIT_RETRY 3 41 40 42 41 static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 43 42 {
+28 -7
sound/soc/intel/skylake/cnl-sst.c
··· 57 57 ctx->dsp_ops.stream_tag = stream_tag; 58 58 memcpy(ctx->dmab.area, fwdata, fwsize); 59 59 60 + ret = skl_dsp_core_power_up(ctx, SKL_DSP_CORE0_MASK); 61 + if (ret < 0) { 62 + dev_err(ctx->dev, "dsp core0 power up failed\n"); 63 + ret = -EIO; 64 + goto base_fw_load_failed; 65 + } 66 + 60 67 /* purge FW request */ 61 68 sst_dsp_shim_write(ctx, CNL_ADSP_REG_HIPCIDR, 62 69 CNL_ADSP_REG_HIPCIDR_BUSY | (CNL_IPC_PURGE | 63 70 ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID))); 64 71 65 - ret = cnl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); 72 + ret = skl_dsp_start_core(ctx, SKL_DSP_CORE0_MASK); 66 73 if (ret < 0) { 67 - dev_err(ctx->dev, "dsp boot core failed ret: %d\n", ret); 74 + dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); 68 75 ret = -EIO; 76 + goto base_fw_load_failed; 77 + } 78 + 79 + ret = sst_dsp_register_poll(ctx, CNL_ADSP_REG_HIPCIDA, 80 + CNL_ADSP_REG_HIPCIDA_DONE, 81 + CNL_ADSP_REG_HIPCIDA_DONE, 82 + BXT_INIT_TIMEOUT, "HIPCIDA Done"); 83 + if (ret < 0) { 84 + dev_err(ctx->dev, "timeout for purge request: %d\n", ret); 69 85 goto base_fw_load_failed; 70 86 } 71 87 ··· 125 109 { 126 110 struct firmware stripped_fw; 127 111 struct skl_dev *cnl = ctx->thread_context; 128 - int ret; 112 + int ret, i; 129 113 130 114 if (!ctx->fw) { 131 115 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); ··· 147 131 stripped_fw.size = ctx->fw->size; 148 132 skl_dsp_strip_extended_manifest(&stripped_fw); 149 133 150 - ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 151 - if (ret < 0) { 152 - dev_err(ctx->dev, "prepare firmware failed: %d\n", ret); 153 - goto cnl_load_base_firmware_failed; 134 + for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) { 135 + ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 136 + if (!ret) 137 + break; 138 + dev_dbg(ctx->dev, "prepare firmware failed: %d\n", ret); 154 139 } 140 + 141 + if (ret < 0) 142 + goto cnl_load_base_firmware_failed; 155 143 156 144 ret = sst_transfer_fw_host_dma(ctx); 157 145 if (ret < 0) { ··· 178 158 return 0; 179 159 180 160 cnl_load_base_firmware_failed: 161 + dev_err(ctx->dev, "firmware load failed: %d\n", ret); 181 162 release_firmware(ctx->fw); 182 163 ctx->fw = NULL; 183 164
+2 -1
sound/soc/intel/skylake/skl-nhlt.c
··· 182 182 { 183 183 struct device *dev = &skl->pci->dev; 184 184 185 - sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr); 185 + if (skl->nhlt) 186 + sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr); 186 187 } 187 188 188 189 /*
+7 -13
sound/soc/intel/skylake/skl-pcm.c
··· 112 112 struct snd_soc_dapm_widget *w; 113 113 struct skl_dev *skl = bus_to_skl(bus); 114 114 115 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 116 - w = dai->playback_widget; 117 - else 118 - w = dai->capture_widget; 115 + w = snd_soc_dai_get_widget(dai, substream->stream); 119 116 120 117 if (w->ignore_suspend && enable) 121 118 skl->supend_active++; ··· 472 475 if (!mconfig) 473 476 return -EIO; 474 477 475 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 476 - w = dai->playback_widget; 477 - else 478 - w = dai->capture_widget; 478 + w = snd_soc_dai_get_widget(dai, substream->stream); 479 479 480 480 switch (cmd) { 481 481 case SNDRV_PCM_TRIGGER_RESUME: ··· 545 551 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 546 552 struct hdac_ext_stream *link_dev; 547 553 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 548 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 554 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 549 555 struct skl_pipe_params p_params = {0}; 550 556 struct hdac_ext_link *link; 551 557 int stream_tag; ··· 644 650 645 651 link_dev->link_prepared = 0; 646 652 647 - link = snd_hdac_ext_bus_get_link(bus, rtd->codec_dai->component->name); 653 + link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name); 648 654 if (!link) 649 655 return -EINVAL; 650 656 ··· 1074 1080 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1075 1081 struct snd_soc_dai_link *dai_link = rtd->dai_link; 1076 1082 1077 - dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__, 1083 + dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__, 1078 1084 dai_link->cpus->dai_name); 1079 1085 1080 1086 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw); ··· 1226 1232 u64 nsec) 1227 1233 { 1228 1234 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 1229 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 1235 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 1230 1236 u64 codec_frames, codec_nsecs; 1231 1237 1232 1238 if (!codec_dai->driver->ops->delay) ··· 1281 1287 static int skl_platform_soc_new(struct snd_soc_component *component, 1282 1288 struct snd_soc_pcm_runtime *rtd) 1283 1289 { 1284 - struct snd_soc_dai *dai = rtd->cpu_dai; 1290 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 1285 1291 struct hdac_bus *bus = dev_get_drvdata(dai->dev); 1286 1292 struct snd_pcm *pcm = rtd->pcm; 1287 1293 unsigned int size;
+2
sound/soc/intel/skylake/skl-sst-dsp.h
··· 67 67 68 68 #define SKL_FW_INIT 0x1 69 69 #define SKL_FW_RFW_START 0xf 70 + #define BXT_FW_ROM_INIT_RETRY 3 71 + #define BXT_INIT_TIMEOUT 300 70 72 71 73 #define SKL_ADSPIC_IPC 1 72 74 #define SKL_ADSPIS_IPC 1
+15 -18
sound/soc/intel/skylake/skl.c
··· 130 130 struct hdac_ext_link *hlink; 131 131 int ret; 132 132 133 + snd_hdac_set_codec_wakeup(bus, true); 133 134 skl_enable_miscbdcge(bus->dev, false); 134 135 ret = snd_hdac_bus_init_chip(bus, full_reset); 135 136 ··· 139 138 writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); 140 139 141 140 skl_enable_miscbdcge(bus->dev, true); 141 + snd_hdac_set_codec_wakeup(bus, false); 142 142 143 143 return ret; 144 144 } ··· 361 359 struct pci_dev *pci = to_pci_dev(dev); 362 360 struct hdac_bus *bus = pci_get_drvdata(pci); 363 361 struct skl_dev *skl = bus_to_skl(bus); 364 - struct hdac_ext_link *hlink = NULL; 362 + struct hdac_ext_link *hlink; 365 363 int ret; 366 364 367 365 /* ··· 483 481 static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl, 484 482 struct snd_soc_acpi_mach *machines) 485 483 { 486 - struct hdac_bus *bus = skl_to_bus(skl); 487 484 struct snd_soc_acpi_mach *mach; 488 - 489 - /* check if we have any codecs detected on bus */ 490 - if (bus->codec_mask == 0) 491 - return NULL; 492 485 493 486 /* point to common table */ 494 487 mach = snd_soc_acpi_intel_hda_machines; ··· 632 635 { 633 636 struct platform_device_info pdevinfo = {NULL}; 634 637 struct skl_clk_pdata *clk_pdata; 638 + 639 + if (!skl->nhlt) 640 + return 0; 635 641 636 642 clk_pdata = devm_kzalloc(&skl->pci->dev, sizeof(*clk_pdata), 637 643 GFP_KERNEL); ··· 794 794 { 795 795 struct skl_dev *skl = container_of(work, struct skl_dev, probe_work); 796 796 struct hdac_bus *bus = skl_to_bus(skl); 797 - struct hdac_ext_link *hlink = NULL; 797 + struct hdac_ext_link *hlink; 798 798 int err; 799 799 800 800 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { ··· 802 802 if (err < 0) 803 803 return; 804 804 } 805 + 806 + skl_init_pci(skl); 807 + skl_dum_set(bus); 805 808 806 809 err = skl_init_chip(bus, true); 807 810 if (err < 0) { ··· 921 918 return -ENXIO; 922 919 } 923 920 924 - snd_hdac_bus_reset_link(bus, true); 925 - 926 921 snd_hdac_bus_parse_capabilities(bus); 927 922 928 923 /* check if PPCAP exists */ ··· 968 967 if (err < 0) 969 968 return err; 970 969 971 - /* initialize chip */ 972 - skl_init_pci(skl); 973 - skl_dum_set(bus); 974 - 975 - return skl_init_chip(bus, true); 970 + return 0; 976 971 } 977 972 978 973 static int skl_probe(struct pci_dev *pci, ··· 1061 1064 if (bus->mlcap) 1062 1065 snd_hdac_ext_bus_get_ml_capabilities(bus); 1063 1066 1064 - snd_hdac_bus_stop_chip(bus); 1065 - 1066 1067 /* create device for soc dmic */ 1067 1068 err = skl_dmic_device_register(skl); 1068 1069 if (err < 0) { ··· 1077 1082 out_clk_free: 1078 1083 skl_clock_device_unregister(skl); 1079 1084 out_nhlt_free: 1080 - intel_nhlt_free(skl->nhlt); 1085 + if (skl->nhlt) 1086 + intel_nhlt_free(skl->nhlt); 1081 1087 out_free: 1082 1088 skl_free(bus); 1083 1089 ··· 1127 1131 skl_dmic_device_unregister(skl); 1128 1132 skl_clock_device_unregister(skl); 1129 1133 skl_nhlt_remove_sysfs(skl); 1130 - intel_nhlt_free(skl->nhlt); 1134 + if (skl->nhlt) 1135 + intel_nhlt_free(skl->nhlt); 1131 1136 skl_free(bus); 1132 1137 dev_set_drvdata(&pci->dev, NULL); 1133 1138 }
+49 -29
sound/soc/jz4740/jz4740-i2s.c
··· 49 49 50 50 #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 51 51 #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 52 - #define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24 53 - #define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16 54 - #define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \ 55 - (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) 56 - #define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \ 57 - (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) 52 + #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24 53 + #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16 58 54 59 55 #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) 60 56 #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) ··· 79 83 #define JZ_AIC_I2S_STATUS_BUSY BIT(2) 80 84 81 85 #define JZ_AIC_CLK_DIV_MASK 0xf 82 - #define I2SDIV_DV_SHIFT 8 86 + #define I2SDIV_DV_SHIFT 0 83 87 #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) 84 88 #define I2SDIV_IDV_SHIFT 8 85 89 #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT) 86 90 87 91 enum jz47xx_i2s_version { 88 92 JZ_I2S_JZ4740, 93 + JZ_I2S_JZ4760, 94 + JZ_I2S_JZ4770, 89 95 JZ_I2S_JZ4780, 96 + }; 97 + 98 + struct i2s_soc_info { 99 + enum jz47xx_i2s_version version; 100 + struct snd_soc_dai_driver *dai; 90 101 }; 91 102 92 103 struct jz4740_i2s { ··· 107 104 struct snd_dmaengine_dai_dma_data playback_dma_data; 108 105 struct snd_dmaengine_dai_dma_data capture_dma_data; 109 106 110 - enum jz47xx_i2s_version version; 107 + const struct i2s_soc_info *soc_info; 111 108 }; 112 109 113 110 static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, ··· 287 284 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; 288 285 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; 289 286 290 - if (i2s->version >= JZ_I2S_JZ4780) { 287 + if (i2s->soc_info->version >= JZ_I2S_JZ4770) { 291 288 div_reg &= ~I2SDIV_IDV_MASK; 292 289 div_reg |= (div - 1) << I2SDIV_IDV_SHIFT; 293 290 } else { ··· 401 398 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, 402 399 &i2s->capture_dma_data); 403 400 404 - if (i2s->version >= JZ_I2S_JZ4780) { 405 - conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 406 - (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 401 + if (i2s->soc_info->version >= JZ_I2S_JZ4760) { 402 + conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 403 + (8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 407 404 JZ_AIC_CONF_OVERFLOW_PLAY_LAST | 408 405 JZ_AIC_CONF_I2S | 409 406 JZ_AIC_CONF_INTERNAL_CODEC; ··· 460 457 .ops = &jz4740_i2s_dai_ops, 461 458 }; 462 459 463 - static struct snd_soc_dai_driver jz4780_i2s_dai = { 460 + static const struct i2s_soc_info jz4740_i2s_soc_info = { 461 + .version = JZ_I2S_JZ4740, 462 + .dai = &jz4740_i2s_dai, 463 + }; 464 + 465 + static const struct i2s_soc_info jz4760_i2s_soc_info = { 466 + .version = JZ_I2S_JZ4760, 467 + .dai = &jz4740_i2s_dai, 468 + }; 469 + 470 + static struct snd_soc_dai_driver jz4770_i2s_dai = { 464 471 .probe = jz4740_i2s_dai_probe, 465 472 .remove = jz4740_i2s_dai_remove, 466 473 .playback = { ··· 488 475 .ops = &jz4740_i2s_dai_ops, 489 476 }; 490 477 478 + static const struct i2s_soc_info jz4770_i2s_soc_info = { 479 + .version = JZ_I2S_JZ4770, 480 + .dai = &jz4770_i2s_dai, 481 + }; 482 + 483 + static const struct i2s_soc_info jz4780_i2s_soc_info = { 484 + .version = JZ_I2S_JZ4780, 485 + .dai = &jz4770_i2s_dai, 486 + }; 487 + 491 488 static const struct snd_soc_component_driver jz4740_i2s_component = { 492 489 .name = "jz4740-i2s", 493 490 .suspend = jz4740_i2s_suspend, ··· 506 483 507 484 #ifdef CONFIG_OF 508 485 static const struct of_device_id jz4740_of_matches[] = { 509 - { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 }, 510 - { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, 486 + { .compatible = "ingenic,jz4740-i2s", .data = &jz4740_i2s_soc_info }, 487 + { .compatible = "ingenic,jz4760-i2s", .data = &jz4760_i2s_soc_info }, 488 + { .compatible = "ingenic,jz4770-i2s", .data = &jz4770_i2s_soc_info }, 489 + { .compatible = "ingenic,jz4780-i2s", .data = &jz4780_i2s_soc_info }, 511 490 { /* sentinel */ } 512 491 }; 513 492 MODULE_DEVICE_TABLE(of, jz4740_of_matches); ··· 517 492 518 493 static int jz4740_i2s_dev_probe(struct platform_device *pdev) 519 494 { 495 + struct device *dev = &pdev->dev; 520 496 struct jz4740_i2s *i2s; 521 497 struct resource *mem; 522 498 int ret; 523 499 524 - i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 500 + i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL); 525 501 if (!i2s) 526 502 return -ENOMEM; 527 503 528 - i2s->version = 529 - (enum jz47xx_i2s_version)of_device_get_match_data(&pdev->dev); 504 + i2s->soc_info = device_get_match_data(dev); 530 505 531 506 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 532 - i2s->base = devm_ioremap_resource(&pdev->dev, mem); 507 + i2s->base = devm_ioremap_resource(dev, mem); 533 508 if (IS_ERR(i2s->base)) 534 509 return PTR_ERR(i2s->base); 535 510 536 511 i2s->phys_base = mem->start; 537 512 538 - i2s->clk_aic = devm_clk_get(&pdev->dev, "aic"); 513 + i2s->clk_aic = devm_clk_get(dev, "aic"); 539 514 if (IS_ERR(i2s->clk_aic)) 540 515 return PTR_ERR(i2s->clk_aic); 541 516 542 - i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s"); 517 + i2s->clk_i2s = devm_clk_get(dev, "i2s"); 543 518 if (IS_ERR(i2s->clk_i2s)) 544 519 return PTR_ERR(i2s->clk_i2s); 545 520 546 521 platform_set_drvdata(pdev, i2s); 547 522 548 - if (i2s->version == JZ_I2S_JZ4780) 549 - ret = devm_snd_soc_register_component(&pdev->dev, 550 - &jz4740_i2s_component, &jz4780_i2s_dai, 1); 551 - else 552 - ret = devm_snd_soc_register_component(&pdev->dev, 553 - &jz4740_i2s_component, &jz4740_i2s_dai, 1); 554 - 523 + ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component, 524 + i2s->soc_info->dai, 1); 555 525 if (ret) 556 526 return ret; 557 527 558 - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 528 + return devm_snd_dmaengine_pcm_register(dev, NULL, 559 529 SND_DMAENGINE_PCM_FLAG_COMPAT); 560 530 } 561 531
+1 -1
sound/soc/kirkwood/armada-370-db.c
··· 19 19 struct snd_pcm_hw_params *params) 20 20 { 21 21 struct snd_soc_pcm_runtime *rtd = substream->private_data; 22 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 22 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 23 23 unsigned int freq; 24 24 25 25 switch (params_rate(params)) {
+1 -1
sound/soc/kirkwood/kirkwood-dma.c
··· 20 20 static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) 21 21 { 22 22 struct snd_soc_pcm_runtime *soc_runtime = subs->private_data; 23 - return snd_soc_dai_get_drvdata(soc_runtime->cpu_dai); 23 + return snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(soc_runtime, 0)); 24 24 } 25 25 26 26 static const struct snd_pcm_hardware kirkwood_dma_snd_hw = {
+5 -5
sound/soc/mediatek/common/mtk-afe-fe-dai.c
··· 40 40 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 41 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 42 42 struct snd_pcm_runtime *runtime = substream->runtime; 43 - int memif_num = rtd->cpu_dai->id; 43 + int memif_num = asoc_rtd_to_cpu(rtd, 0)->id; 44 44 struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; 45 45 const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware; 46 46 int ret; ··· 100 100 { 101 101 struct snd_soc_pcm_runtime *rtd = substream->private_data; 102 102 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 103 - struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 103 + struct mtk_base_afe_memif *memif = &afe->memif[asoc_rtd_to_cpu(rtd, 0)->id]; 104 104 int irq_id; 105 105 106 106 irq_id = memif->irq_usage; ··· 122 122 { 123 123 struct snd_soc_pcm_runtime *rtd = substream->private_data; 124 124 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 125 - int id = rtd->cpu_dai->id; 125 + int id = asoc_rtd_to_cpu(rtd, 0)->id; 126 126 struct mtk_base_afe_memif *memif = &afe->memif[id]; 127 127 int ret; 128 128 unsigned int channels = params_channels(params); ··· 199 199 struct snd_soc_pcm_runtime *rtd = substream->private_data; 200 200 struct snd_pcm_runtime * const runtime = substream->runtime; 201 201 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 202 - int id = rtd->cpu_dai->id; 202 + int id = asoc_rtd_to_cpu(rtd, 0)->id; 203 203 struct mtk_base_afe_memif *memif = &afe->memif[id]; 204 204 struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage]; 205 205 const struct mtk_base_irq_data *irq_data = irqs->irq_data; ··· 265 265 { 266 266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 267 267 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 268 - int id = rtd->cpu_dai->id; 268 + int id = asoc_rtd_to_cpu(rtd, 0)->id; 269 269 int pbuf_size; 270 270 271 271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+1 -1
sound/soc/mediatek/common/mtk-afe-platform-driver.c
··· 82 82 { 83 83 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 84 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 85 - struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 85 + struct mtk_base_afe_memif *memif = &afe->memif[asoc_rtd_to_cpu(rtd, 0)->id]; 86 86 const struct mtk_base_memif_data *memif_data = memif->data; 87 87 struct regmap *regmap = afe->regmap; 88 88 struct device *dev = afe->dev;
+1 -1
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
··· 497 497 struct snd_soc_pcm_runtime *rtd = substream->private_data; 498 498 int fs; 499 499 500 - if (rtd->cpu_dai->id != MT2701_MEMIF_ULBT) 500 + if (asoc_rtd_to_cpu(rtd, 0)->id != MT2701_MEMIF_ULBT) 501 501 fs = mt2701_afe_i2s_fs(rate); 502 502 else 503 503 fs = (rate == 16000 ? 1 : 0);
+2 -2
sound/soc/mediatek/mt2701/mt2701-cs42448.c
··· 128 128 struct snd_pcm_hw_params *params) 129 129 { 130 130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 132 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 131 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 132 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 133 133 unsigned int mclk_rate; 134 134 unsigned int rate = params_rate(params); 135 135 unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
+2 -2
sound/soc/mediatek/mt2701/mt2701-wm8960.c
··· 25 25 struct snd_pcm_hw_params *params) 26 26 { 27 27 struct snd_soc_pcm_runtime *rtd = substream->private_data; 28 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 29 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 28 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 29 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 30 30 unsigned int mclk_rate; 31 31 unsigned int rate = params_rate(params); 32 32 unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
+1 -1
sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
··· 143 143 struct snd_soc_component *component = 144 144 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 145 145 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 146 - int id = rtd->cpu_dai->id; 146 + int id = asoc_rtd_to_cpu(rtd, 0)->id; 147 147 148 148 return mt6797_rate_transform(afe->dev, rate, id); 149 149 }
+1 -1
sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
··· 485 485 struct snd_soc_pcm_runtime *rtd = substream->private_data; 486 486 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 487 487 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 488 - struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 488 + struct mtk_base_afe_memif *memif = &afe->memif[asoc_rtd_to_cpu(rtd, 0)->id]; 489 489 int fs; 490 490 491 491 if (memif->data->id == MT8173_AFE_MEMIF_DAI ||
+2 -2
sound/soc/mediatek/mt8173/mt8173-max98090.c
··· 53 53 struct snd_pcm_hw_params *params) 54 54 { 55 55 struct snd_soc_pcm_runtime *rtd = substream->private_data; 56 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 56 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 57 57 58 58 return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256, 59 59 SND_SOC_CLOCK_IN); ··· 67 67 { 68 68 int ret; 69 69 struct snd_soc_card *card = runtime->card; 70 - struct snd_soc_component *component = runtime->codec_dai->component; 70 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 71 71 72 72 /* enable jack detection */ 73 73 ret = snd_soc_card_jack_new(card, "Headphone", SND_JACK_HEADPHONE,
+2 -2
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
··· 47 47 struct snd_soc_dai *codec_dai; 48 48 int i, ret; 49 49 50 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 50 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 51 51 /* pll from mclk 12.288M */ 52 52 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, 53 53 params_rate(params) * 512); ··· 73 73 static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime) 74 74 { 75 75 struct snd_soc_card *card = runtime->card; 76 - struct snd_soc_component *component = runtime->codec_dais[0]->component; 76 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 77 77 int ret; 78 78 79 79 rt5645_sel_asrc_clk_src(component,
+3 -3
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
··· 51 51 struct snd_soc_dai *codec_dai; 52 52 int i, ret; 53 53 54 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 54 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 55 55 /* pll from mclk 12.288M */ 56 56 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS, 57 57 params_rate(params) * 512); ··· 77 77 static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime) 78 78 { 79 79 struct snd_soc_card *card = runtime->card; 80 - struct snd_soc_component *component = runtime->codec_dais[0]->component; 81 - struct snd_soc_component *component_sub = runtime->codec_dais[1]->component; 80 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 81 + struct snd_soc_component *component_sub = asoc_rtd_to_codec(runtime, 1)->component; 82 82 int ret; 83 83 84 84 rt5645_sel_asrc_clk_src(component,
+19 -4
sound/soc/mediatek/mt8173/mt8173-rt5650.c
··· 11 11 #include <linux/of_gpio.h> 12 12 #include <sound/soc.h> 13 13 #include <sound/jack.h> 14 + #include <sound/hdmi-codec.h> 14 15 #include "../../codecs/rt5645.h" 15 16 16 17 #define MCLK_FOR_CODECS 12288000 ··· 78 77 break; 79 78 } 80 79 81 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 80 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 82 81 /* pll from mclk */ 83 82 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, mclk_clock, 84 83 params_rate(params) * 512); ··· 99 98 .hw_params = mt8173_rt5650_hw_params, 100 99 }; 101 100 102 - static struct snd_soc_jack mt8173_rt5650_jack; 101 + static struct snd_soc_jack mt8173_rt5650_jack, mt8173_rt5650_hdmi_jack; 103 102 104 103 static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime) 105 104 { 106 105 struct snd_soc_card *card = runtime->card; 107 - struct snd_soc_component *component = runtime->codec_dais[0]->component; 108 - const char *codec_capture_dai = runtime->codec_dais[1]->name; 106 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 107 + const char *codec_capture_dai = asoc_rtd_to_codec(runtime, 1)->name; 109 108 int ret; 110 109 111 110 rt5645_sel_asrc_clk_src(component, ··· 143 142 &mt8173_rt5650_jack, 144 143 &mt8173_rt5650_jack, 145 144 &mt8173_rt5650_jack); 145 + } 146 + 147 + static int mt8173_rt5650_hdmi_init(struct snd_soc_pcm_runtime *rtd) 148 + { 149 + int ret; 150 + 151 + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, 152 + &mt8173_rt5650_hdmi_jack, NULL, 0); 153 + if (ret) 154 + return ret; 155 + 156 + return hdmi_codec_set_jack_detect(asoc_rtd_to_codec(rtd, 0)->component, 157 + &mt8173_rt5650_hdmi_jack); 146 158 } 147 159 148 160 enum { ··· 236 222 .name = "HDMI BE", 237 223 .no_pcm = 1, 238 224 .dpcm_playback = 1, 225 + .init = mt8173_rt5650_hdmi_init, 239 226 SND_SOC_DAILINK_REG(hdmi_be), 240 227 }, 241 228 };
+1 -1
sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
··· 146 146 struct snd_soc_component *component = 147 147 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 148 148 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 149 - int id = rtd->cpu_dai->id; 149 + int id = asoc_rtd_to_cpu(rtd, 0)->id; 150 150 151 151 return mt8183_rate_transform(afe->dev, rate, id); 152 152 }
+94 -23
sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
··· 16 16 #include "../../codecs/da7219-aad.h" 17 17 #include "../../codecs/da7219.h" 18 18 19 - static struct snd_soc_jack headset_jack; 19 + struct mt8183_da7219_max98357_priv { 20 + struct snd_soc_jack headset_jack; 21 + }; 20 22 21 23 static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream, 22 24 struct snd_pcm_hw_params *params) ··· 28 26 unsigned int mclk_fs_ratio = 128; 29 27 unsigned int mclk_fs = rate * mclk_fs_ratio; 30 28 31 - return snd_soc_dai_set_sysclk(rtd->cpu_dai, 29 + return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 32 30 0, mclk_fs, SND_SOC_CLOCK_OUT); 33 31 } 34 32 ··· 40 38 struct snd_pcm_hw_params *params) 41 39 { 42 40 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 + struct snd_soc_dai *codec_dai; 43 42 unsigned int rate = params_rate(params); 44 43 unsigned int mclk_fs_ratio = 256; 45 44 unsigned int mclk_fs = rate * mclk_fs_ratio; 46 45 unsigned int freq; 47 46 int ret = 0, j; 48 47 49 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, 48 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, 50 49 mclk_fs, SND_SOC_CLOCK_OUT); 51 50 if (ret < 0) 52 51 dev_err(rtd->dev, "failed to set cpu dai sysclk\n"); 53 52 54 - for (j = 0; j < rtd->num_codecs; j++) { 55 - struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 53 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 56 54 57 55 if (!strcmp(codec_dai->component->name, "da7219.5-001a")) { 58 56 ret = snd_soc_dai_set_sysclk(codec_dai, ··· 82 80 static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream) 83 81 { 84 82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 83 + struct snd_soc_dai *codec_dai; 85 84 int ret = 0, j; 86 85 87 - for (j = 0; j < rtd->num_codecs; j++) { 88 - struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 86 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 89 87 90 88 if (!strcmp(codec_dai->component->name, "da7219.5-001a")) { 91 89 ret = snd_soc_dai_set_pll(codec_dai, ··· 117 115 118 116 return 0; 119 117 } 118 + 119 + static int 120 + mt8183_da7219_max98357_bt_sco_startup( 121 + struct snd_pcm_substream *substream) 122 + { 123 + static const unsigned int rates[] = { 124 + 8000, 16000 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 + 1, 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 = 1; 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_da7219_max98357_bt_sco_ops = { 156 + .startup = mt8183_da7219_max98357_bt_sco_startup, 157 + }; 120 158 121 159 /* FE */ 122 160 SND_SOC_DAILINK_DEFS(playback1, ··· 264 222 SND_SOC_DPCM_TRIGGER_PRE}, 265 223 .dynamic = 1, 266 224 .dpcm_playback = 1, 225 + .ops = &mt8183_da7219_max98357_bt_sco_ops, 267 226 SND_SOC_DAILINK_REG(playback2), 268 227 }, 269 228 { ··· 283 240 SND_SOC_DPCM_TRIGGER_PRE}, 284 241 .dynamic = 1, 285 242 .dpcm_capture = 1, 243 + .ops = &mt8183_da7219_max98357_bt_sco_ops, 286 244 SND_SOC_DAILINK_REG(capture1), 287 245 }, 288 246 { ··· 395 351 { 396 352 .name = "TDM", 397 353 .no_pcm = 1, 354 + .dai_fmt = SND_SOC_DAIFMT_I2S | 355 + SND_SOC_DAIFMT_IB_IF | 356 + SND_SOC_DAIFMT_CBM_CFM, 398 357 .dpcm_playback = 1, 399 358 .ignore_suspend = 1, 359 + .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, 400 360 SND_SOC_DAILINK_REG(tdm), 401 361 }, 402 362 }; ··· 420 372 }, 421 373 }; 422 374 375 + static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = { 376 + SOC_DAPM_PIN_SWITCH("Speakers"), 377 + }; 378 + 379 + static const 380 + struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = { 381 + SND_SOC_DAPM_SPK("Speakers", NULL), 382 + SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL", 383 + "aud_tdm_out_on", "aud_tdm_out_off"), 384 + }; 385 + 386 + static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = { 387 + {"Speakers", NULL, "Speaker"}, 388 + {"I2S Playback", NULL, "TDM_OUT_PINCTRL"}, 389 + }; 390 + 423 391 static struct snd_soc_card mt8183_da7219_max98357_card = { 424 392 .name = "mt8183_da7219_max98357", 425 393 .owner = THIS_MODULE, 394 + .controls = mt8183_da7219_max98357_snd_controls, 395 + .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), 396 + .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, 397 + .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), 398 + .dapm_routes = mt8183_da7219_max98357_dapm_routes, 399 + .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), 426 400 .dai_link = mt8183_da7219_max98357_dai_links, 427 401 .num_links = ARRAY_SIZE(mt8183_da7219_max98357_dai_links), 428 402 .aux_dev = &mt8183_da7219_max98357_headset_dev, ··· 457 387 mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) 458 388 { 459 389 int ret; 390 + struct mt8183_da7219_max98357_priv *priv = 391 + snd_soc_card_get_drvdata(component->card); 460 392 461 393 /* Enable Headset and 4 Buttons Jack detection */ 462 394 ret = snd_soc_card_jack_new(&mt8183_da7219_max98357_card, ··· 466 394 SND_JACK_HEADSET | 467 395 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 468 396 SND_JACK_BTN_2 | SND_JACK_BTN_3, 469 - &headset_jack, 397 + &priv->headset_jack, 470 398 NULL, 0); 471 399 if (ret) 472 400 return ret; 473 401 474 - da7219_aad_jack_det(component, &headset_jack); 402 + da7219_aad_jack_det(component, &priv->headset_jack); 475 403 476 404 return ret; 477 405 } ··· 481 409 struct snd_soc_card *card = &mt8183_da7219_max98357_card; 482 410 struct device_node *platform_node; 483 411 struct snd_soc_dai_link *dai_link; 484 - struct pinctrl *default_pins; 412 + struct mt8183_da7219_max98357_priv *priv; 413 + struct pinctrl *pinctrl; 485 414 int ret, i; 486 415 487 416 card->dev = &pdev->dev; ··· 509 436 return -EINVAL; 510 437 } 511 438 512 - ret = devm_snd_soc_register_card(&pdev->dev, card); 513 - if (ret) { 514 - dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 439 + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 440 + if (!priv) 441 + return -ENOMEM; 442 + 443 + snd_soc_card_set_drvdata(card, priv); 444 + 445 + pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 446 + if (IS_ERR(pinctrl)) { 447 + ret = PTR_ERR(pinctrl); 448 + dev_err(&pdev->dev, "%s failed to select default state %d\n", 515 449 __func__, ret); 516 450 return ret; 517 451 } 518 452 519 - default_pins = 520 - devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT); 521 - if (IS_ERR(default_pins)) { 522 - dev_err(&pdev->dev, "%s set pins failed\n", 523 - __func__); 524 - return PTR_ERR(default_pins); 525 - } 526 - 527 - return ret; 453 + return devm_snd_soc_register_card(&pdev->dev, card); 528 454 } 529 455 530 456 #ifdef CONFIG_OF ··· 550 478 MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>"); 551 479 MODULE_LICENSE("GPL v2"); 552 480 MODULE_ALIAS("mt8183_da7219_max98357 soc card"); 553 -
+1 -1
sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
··· 41 41 unsigned int mclk_fs_ratio = 128; 42 42 unsigned int mclk_fs = rate * mclk_fs_ratio; 43 43 44 - return snd_soc_dai_set_sysclk(rtd->cpu_dai, 44 + return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 45 45 0, mclk_fs, SND_SOC_CLOCK_OUT); 46 46 } 47 47
+41
sound/soc/meson/Kconfig
··· 2 2 menu "ASoC support for Amlogic platforms" 3 3 depends on ARCH_MESON || COMPILE_TEST 4 4 5 + config SND_MESON_AIU 6 + tristate "Amlogic AIU" 7 + select SND_MESON_CODEC_GLUE 8 + select SND_PCM_IEC958 9 + imply SND_SOC_MESON_T9015 10 + imply SND_SOC_HDMI_CODEC if DRM_MESON_DW_HDMI 11 + help 12 + Select Y or M to add support for the Audio output subsystem found 13 + in the Amlogic Meson8, Meson8b and GX SoC families 14 + 5 15 config SND_MESON_AXG_FIFO 6 16 tristate 7 17 select REGMAP_MMIO ··· 60 50 config SND_MESON_AXG_SOUND_CARD 61 51 tristate "Amlogic AXG Sound Card Support" 62 52 select SND_MESON_AXG_TDM_INTERFACE 53 + select SND_MESON_CARD_UTILS 63 54 imply SND_MESON_AXG_FRDDR 64 55 imply SND_MESON_AXG_TODDR 65 56 imply SND_MESON_AXG_TDMIN ··· 96 85 Select Y or M to add support for PDM input embedded 97 86 in the Amlogic AXG SoC family 98 87 88 + config SND_MESON_CARD_UTILS 89 + tristate 90 + 91 + config SND_MESON_CODEC_GLUE 92 + tristate 93 + 94 + config SND_MESON_GX_SOUND_CARD 95 + tristate "Amlogic GX Sound Card Support" 96 + select SND_MESON_CARD_UTILS 97 + imply SND_MESON_AIU 98 + help 99 + Select Y or M to add support for the GXBB/GXL SoC sound card 100 + 101 + config SND_MESON_G12A_TOACODEC 102 + tristate "Amlogic G12A To Internal DAC Control Support" 103 + select SND_MESON_CODEC_GLUE 104 + select REGMAP_MMIO 105 + imply SND_SOC_MESON_T9015 106 + help 107 + Select Y or M to add support for the internal audio DAC on the 108 + g12a SoC family 109 + 99 110 config SND_MESON_G12A_TOHDMITX 100 111 tristate "Amlogic G12A To HDMI TX Control Support" 101 112 select REGMAP_MMIO 113 + select SND_MESON_CODEC_GLUE 102 114 imply SND_SOC_HDMI_CODEC 103 115 help 104 116 Select Y or M to add support for HDMI audio on the g12a SoC 105 117 family 118 + 119 + config SND_SOC_MESON_T9015 120 + tristate "Amlogic T9015 DAC" 121 + select REGMAP_MMIO 122 + help 123 + Say Y or M if you want to add support for the internal DAC found 124 + on GXL, G12 and SM1 SoC family. 106 125 endmenu
+19
sound/soc/meson/Makefile
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 2 3 + snd-soc-meson-aiu-objs := aiu.o 4 + snd-soc-meson-aiu-objs += aiu-acodec-ctrl.o 5 + snd-soc-meson-aiu-objs += aiu-codec-ctrl.o 6 + snd-soc-meson-aiu-objs += aiu-encoder-i2s.o 7 + snd-soc-meson-aiu-objs += aiu-encoder-spdif.o 8 + snd-soc-meson-aiu-objs += aiu-fifo.o 9 + snd-soc-meson-aiu-objs += aiu-fifo-i2s.o 10 + snd-soc-meson-aiu-objs += aiu-fifo-spdif.o 3 11 snd-soc-meson-axg-fifo-objs := axg-fifo.o 4 12 snd-soc-meson-axg-frddr-objs := axg-frddr.o 5 13 snd-soc-meson-axg-toddr-objs := axg-toddr.o ··· 19 11 snd-soc-meson-axg-spdifin-objs := axg-spdifin.o 20 12 snd-soc-meson-axg-spdifout-objs := axg-spdifout.o 21 13 snd-soc-meson-axg-pdm-objs := axg-pdm.o 14 + snd-soc-meson-card-utils-objs := meson-card-utils.o 15 + snd-soc-meson-codec-glue-objs := meson-codec-glue.o 16 + snd-soc-meson-gx-sound-card-objs := gx-card.o 17 + snd-soc-meson-g12a-toacodec-objs := g12a-toacodec.o 22 18 snd-soc-meson-g12a-tohdmitx-objs := g12a-tohdmitx.o 19 + snd-soc-meson-t9015-objs := t9015.o 23 20 21 + obj-$(CONFIG_SND_MESON_AIU) += snd-soc-meson-aiu.o 24 22 obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o 25 23 obj-$(CONFIG_SND_MESON_AXG_FRDDR) += snd-soc-meson-axg-frddr.o 26 24 obj-$(CONFIG_SND_MESON_AXG_TODDR) += snd-soc-meson-axg-toddr.o ··· 38 24 obj-$(CONFIG_SND_MESON_AXG_SPDIFIN) += snd-soc-meson-axg-spdifin.o 39 25 obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o 40 26 obj-$(CONFIG_SND_MESON_AXG_PDM) += snd-soc-meson-axg-pdm.o 27 + obj-$(CONFIG_SND_MESON_CARD_UTILS) += snd-soc-meson-card-utils.o 28 + obj-$(CONFIG_SND_MESON_CODEC_GLUE) += snd-soc-meson-codec-glue.o 29 + obj-$(CONFIG_SND_MESON_GX_SOUND_CARD) += snd-soc-meson-gx-sound-card.o 30 + obj-$(CONFIG_SND_MESON_G12A_TOACODEC) += snd-soc-meson-g12a-toacodec.o 41 31 obj-$(CONFIG_SND_MESON_G12A_TOHDMITX) += snd-soc-meson-g12a-tohdmitx.o 32 + obj-$(CONFIG_SND_SOC_MESON_T9015) += snd-soc-meson-t9015.o
+203
sound/soc/meson/aiu-acodec-ctrl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <sound/pcm_params.h> 8 + #include <sound/soc.h> 9 + #include <sound/soc-dai.h> 10 + 11 + #include <dt-bindings/sound/meson-aiu.h> 12 + #include "aiu.h" 13 + #include "meson-codec-glue.h" 14 + 15 + #define CTRL_DIN_EN 15 16 + #define CTRL_CLK_INV BIT(14) 17 + #define CTRL_LRCLK_INV BIT(13) 18 + #define CTRL_I2S_IN_BCLK_SRC BIT(11) 19 + #define CTRL_DIN_LRCLK_SRC_SHIFT 6 20 + #define CTRL_DIN_LRCLK_SRC (0x3 << CTRL_DIN_LRCLK_SRC_SHIFT) 21 + #define CTRL_BCLK_MCLK_SRC GENMASK(5, 4) 22 + #define CTRL_DIN_SKEW GENMASK(3, 2) 23 + #define CTRL_I2S_OUT_LANE_SRC 0 24 + 25 + #define AIU_ACODEC_OUT_CHMAX 2 26 + 27 + static const char * const aiu_acodec_ctrl_mux_texts[] = { 28 + "DISABLED", "I2S", "PCM", 29 + }; 30 + 31 + static int aiu_acodec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol, 32 + struct snd_ctl_elem_value *ucontrol) 33 + { 34 + struct snd_soc_component *component = 35 + snd_soc_dapm_kcontrol_component(kcontrol); 36 + struct snd_soc_dapm_context *dapm = 37 + snd_soc_dapm_kcontrol_dapm(kcontrol); 38 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 39 + unsigned int mux, changed; 40 + 41 + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); 42 + changed = snd_soc_component_test_bits(component, e->reg, 43 + CTRL_DIN_LRCLK_SRC, 44 + FIELD_PREP(CTRL_DIN_LRCLK_SRC, 45 + mux)); 46 + 47 + if (!changed) 48 + return 0; 49 + 50 + /* Force disconnect of the mux while updating */ 51 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 52 + 53 + snd_soc_component_update_bits(component, e->reg, 54 + CTRL_DIN_LRCLK_SRC | 55 + CTRL_BCLK_MCLK_SRC, 56 + FIELD_PREP(CTRL_DIN_LRCLK_SRC, mux) | 57 + FIELD_PREP(CTRL_BCLK_MCLK_SRC, mux)); 58 + 59 + snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); 60 + 61 + return 0; 62 + } 63 + 64 + static SOC_ENUM_SINGLE_DECL(aiu_acodec_ctrl_mux_enum, AIU_ACODEC_CTRL, 65 + CTRL_DIN_LRCLK_SRC_SHIFT, 66 + aiu_acodec_ctrl_mux_texts); 67 + 68 + static const struct snd_kcontrol_new aiu_acodec_ctrl_mux = 69 + SOC_DAPM_ENUM_EXT("ACodec Source", aiu_acodec_ctrl_mux_enum, 70 + snd_soc_dapm_get_enum_double, 71 + aiu_acodec_ctrl_mux_put_enum); 72 + 73 + static const struct snd_kcontrol_new aiu_acodec_ctrl_out_enable = 74 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", AIU_ACODEC_CTRL, 75 + CTRL_DIN_EN, 1, 0); 76 + 77 + static const struct snd_soc_dapm_widget aiu_acodec_ctrl_widgets[] = { 78 + SND_SOC_DAPM_MUX("ACODEC SRC", SND_SOC_NOPM, 0, 0, 79 + &aiu_acodec_ctrl_mux), 80 + SND_SOC_DAPM_SWITCH("ACODEC OUT EN", SND_SOC_NOPM, 0, 0, 81 + &aiu_acodec_ctrl_out_enable), 82 + }; 83 + 84 + static int aiu_acodec_ctrl_input_hw_params(struct snd_pcm_substream *substream, 85 + struct snd_pcm_hw_params *params, 86 + struct snd_soc_dai *dai) 87 + { 88 + struct meson_codec_glue_input *data; 89 + int ret; 90 + 91 + ret = meson_codec_glue_input_hw_params(substream, params, dai); 92 + if (ret) 93 + return ret; 94 + 95 + /* The glue will provide 1 lane out of the 4 to the output */ 96 + data = meson_codec_glue_input_get_data(dai); 97 + data->params.channels_min = min_t(unsigned int, AIU_ACODEC_OUT_CHMAX, 98 + data->params.channels_min); 99 + data->params.channels_max = min_t(unsigned int, AIU_ACODEC_OUT_CHMAX, 100 + data->params.channels_max); 101 + 102 + return 0; 103 + } 104 + 105 + static const struct snd_soc_dai_ops aiu_acodec_ctrl_input_ops = { 106 + .hw_params = aiu_acodec_ctrl_input_hw_params, 107 + .set_fmt = meson_codec_glue_input_set_fmt, 108 + }; 109 + 110 + static const struct snd_soc_dai_ops aiu_acodec_ctrl_output_ops = { 111 + .startup = meson_codec_glue_output_startup, 112 + }; 113 + 114 + #define AIU_ACODEC_CTRL_FORMATS \ 115 + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 116 + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ 117 + SNDRV_PCM_FMTBIT_S32_LE) 118 + 119 + #define AIU_ACODEC_STREAM(xname, xsuffix, xchmax) \ 120 + { \ 121 + .stream_name = xname " " xsuffix, \ 122 + .channels_min = 1, \ 123 + .channels_max = (xchmax), \ 124 + .rate_min = 5512, \ 125 + .rate_max = 192000, \ 126 + .formats = AIU_ACODEC_CTRL_FORMATS, \ 127 + } 128 + 129 + #define AIU_ACODEC_INPUT(xname) { \ 130 + .name = "ACODEC CTRL " xname, \ 131 + .playback = AIU_ACODEC_STREAM(xname, "Playback", 8), \ 132 + .ops = &aiu_acodec_ctrl_input_ops, \ 133 + .probe = meson_codec_glue_input_dai_probe, \ 134 + .remove = meson_codec_glue_input_dai_remove, \ 135 + } 136 + 137 + #define AIU_ACODEC_OUTPUT(xname) { \ 138 + .name = "ACODEC CTRL " xname, \ 139 + .capture = AIU_ACODEC_STREAM(xname, "Capture", AIU_ACODEC_OUT_CHMAX), \ 140 + .ops = &aiu_acodec_ctrl_output_ops, \ 141 + } 142 + 143 + static struct snd_soc_dai_driver aiu_acodec_ctrl_dai_drv[] = { 144 + [CTRL_I2S] = AIU_ACODEC_INPUT("ACODEC I2S IN"), 145 + [CTRL_PCM] = AIU_ACODEC_INPUT("ACODEC PCM IN"), 146 + [CTRL_OUT] = AIU_ACODEC_OUTPUT("ACODEC OUT"), 147 + }; 148 + 149 + static const struct snd_soc_dapm_route aiu_acodec_ctrl_routes[] = { 150 + { "ACODEC SRC", "I2S", "ACODEC I2S IN Playback" }, 151 + { "ACODEC SRC", "PCM", "ACODEC PCM IN Playback" }, 152 + { "ACODEC OUT EN", "Switch", "ACODEC SRC" }, 153 + { "ACODEC OUT Capture", NULL, "ACODEC OUT EN" }, 154 + }; 155 + 156 + static const struct snd_kcontrol_new aiu_acodec_ctrl_controls[] = { 157 + SOC_SINGLE("ACODEC I2S Lane Select", AIU_ACODEC_CTRL, 158 + CTRL_I2S_OUT_LANE_SRC, 3, 0), 159 + }; 160 + 161 + static int aiu_acodec_of_xlate_dai_name(struct snd_soc_component *component, 162 + struct of_phandle_args *args, 163 + const char **dai_name) 164 + { 165 + return aiu_of_xlate_dai_name(component, args, dai_name, AIU_ACODEC); 166 + } 167 + 168 + static int aiu_acodec_ctrl_component_probe(struct snd_soc_component *component) 169 + { 170 + /* 171 + * NOTE: Din Skew setting 172 + * According to the documentation, the following update adds one delay 173 + * to the din line. Without this, the output saturates. This happens 174 + * regardless of the link format (i2s or left_j) so it is not clear what 175 + * it actually does but it seems to be required 176 + */ 177 + snd_soc_component_update_bits(component, AIU_ACODEC_CTRL, 178 + CTRL_DIN_SKEW, 179 + FIELD_PREP(CTRL_DIN_SKEW, 2)); 180 + 181 + return 0; 182 + } 183 + 184 + static const struct snd_soc_component_driver aiu_acodec_ctrl_component = { 185 + .name = "AIU Internal DAC Codec Control", 186 + .probe = aiu_acodec_ctrl_component_probe, 187 + .controls = aiu_acodec_ctrl_controls, 188 + .num_controls = ARRAY_SIZE(aiu_acodec_ctrl_controls), 189 + .dapm_widgets = aiu_acodec_ctrl_widgets, 190 + .num_dapm_widgets = ARRAY_SIZE(aiu_acodec_ctrl_widgets), 191 + .dapm_routes = aiu_acodec_ctrl_routes, 192 + .num_dapm_routes = ARRAY_SIZE(aiu_acodec_ctrl_routes), 193 + .of_xlate_dai_name = aiu_acodec_of_xlate_dai_name, 194 + .endianness = 1, 195 + .non_legacy_dai_naming = 1, 196 + }; 197 + 198 + int aiu_acodec_ctrl_register_component(struct device *dev) 199 + { 200 + return snd_soc_register_component(dev, &aiu_acodec_ctrl_component, 201 + aiu_acodec_ctrl_dai_drv, 202 + ARRAY_SIZE(aiu_acodec_ctrl_dai_drv)); 203 + }
+151
sound/soc/meson/aiu-codec-ctrl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <sound/pcm_params.h> 8 + #include <sound/soc.h> 9 + #include <sound/soc-dai.h> 10 + 11 + #include <dt-bindings/sound/meson-aiu.h> 12 + #include "aiu.h" 13 + #include "meson-codec-glue.h" 14 + 15 + #define CTRL_CLK_SEL GENMASK(1, 0) 16 + #define CTRL_DATA_SEL_SHIFT 4 17 + #define CTRL_DATA_SEL (0x3 << CTRL_DATA_SEL_SHIFT) 18 + 19 + static const char * const aiu_codec_ctrl_mux_texts[] = { 20 + "DISABLED", "PCM", "I2S", 21 + }; 22 + 23 + static int aiu_codec_ctrl_mux_put_enum(struct snd_kcontrol *kcontrol, 24 + struct snd_ctl_elem_value *ucontrol) 25 + { 26 + struct snd_soc_component *component = 27 + snd_soc_dapm_kcontrol_component(kcontrol); 28 + struct snd_soc_dapm_context *dapm = 29 + snd_soc_dapm_kcontrol_dapm(kcontrol); 30 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 31 + unsigned int mux, changed; 32 + 33 + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); 34 + changed = snd_soc_component_test_bits(component, e->reg, 35 + CTRL_DATA_SEL, 36 + FIELD_PREP(CTRL_DATA_SEL, mux)); 37 + 38 + if (!changed) 39 + return 0; 40 + 41 + /* Force disconnect of the mux while updating */ 42 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 43 + 44 + /* Reset the source first */ 45 + snd_soc_component_update_bits(component, e->reg, 46 + CTRL_CLK_SEL | 47 + CTRL_DATA_SEL, 48 + FIELD_PREP(CTRL_CLK_SEL, 0) | 49 + FIELD_PREP(CTRL_DATA_SEL, 0)); 50 + 51 + /* Set the appropriate source */ 52 + snd_soc_component_update_bits(component, e->reg, 53 + CTRL_CLK_SEL | 54 + CTRL_DATA_SEL, 55 + FIELD_PREP(CTRL_CLK_SEL, mux) | 56 + FIELD_PREP(CTRL_DATA_SEL, mux)); 57 + 58 + snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); 59 + 60 + return 0; 61 + } 62 + 63 + static SOC_ENUM_SINGLE_DECL(aiu_hdmi_ctrl_mux_enum, AIU_HDMI_CLK_DATA_CTRL, 64 + CTRL_DATA_SEL_SHIFT, 65 + aiu_codec_ctrl_mux_texts); 66 + 67 + static const struct snd_kcontrol_new aiu_hdmi_ctrl_mux = 68 + SOC_DAPM_ENUM_EXT("HDMI Source", aiu_hdmi_ctrl_mux_enum, 69 + snd_soc_dapm_get_enum_double, 70 + aiu_codec_ctrl_mux_put_enum); 71 + 72 + static const struct snd_soc_dapm_widget aiu_hdmi_ctrl_widgets[] = { 73 + SND_SOC_DAPM_MUX("HDMI CTRL SRC", SND_SOC_NOPM, 0, 0, 74 + &aiu_hdmi_ctrl_mux), 75 + }; 76 + 77 + static const struct snd_soc_dai_ops aiu_codec_ctrl_input_ops = { 78 + .hw_params = meson_codec_glue_input_hw_params, 79 + .set_fmt = meson_codec_glue_input_set_fmt, 80 + }; 81 + 82 + static const struct snd_soc_dai_ops aiu_codec_ctrl_output_ops = { 83 + .startup = meson_codec_glue_output_startup, 84 + }; 85 + 86 + #define AIU_CODEC_CTRL_FORMATS \ 87 + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 88 + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ 89 + SNDRV_PCM_FMTBIT_S32_LE) 90 + 91 + #define AIU_CODEC_CTRL_STREAM(xname, xsuffix) \ 92 + { \ 93 + .stream_name = xname " " xsuffix, \ 94 + .channels_min = 1, \ 95 + .channels_max = 8, \ 96 + .rate_min = 5512, \ 97 + .rate_max = 192000, \ 98 + .formats = AIU_CODEC_CTRL_FORMATS, \ 99 + } 100 + 101 + #define AIU_CODEC_CTRL_INPUT(xname) { \ 102 + .name = "CODEC CTRL " xname, \ 103 + .playback = AIU_CODEC_CTRL_STREAM(xname, "Playback"), \ 104 + .ops = &aiu_codec_ctrl_input_ops, \ 105 + .probe = meson_codec_glue_input_dai_probe, \ 106 + .remove = meson_codec_glue_input_dai_remove, \ 107 + } 108 + 109 + #define AIU_CODEC_CTRL_OUTPUT(xname) { \ 110 + .name = "CODEC CTRL " xname, \ 111 + .capture = AIU_CODEC_CTRL_STREAM(xname, "Capture"), \ 112 + .ops = &aiu_codec_ctrl_output_ops, \ 113 + } 114 + 115 + static struct snd_soc_dai_driver aiu_hdmi_ctrl_dai_drv[] = { 116 + [CTRL_I2S] = AIU_CODEC_CTRL_INPUT("HDMI I2S IN"), 117 + [CTRL_PCM] = AIU_CODEC_CTRL_INPUT("HDMI PCM IN"), 118 + [CTRL_OUT] = AIU_CODEC_CTRL_OUTPUT("HDMI OUT"), 119 + }; 120 + 121 + static const struct snd_soc_dapm_route aiu_hdmi_ctrl_routes[] = { 122 + { "HDMI CTRL SRC", "I2S", "HDMI I2S IN Playback" }, 123 + { "HDMI CTRL SRC", "PCM", "HDMI PCM IN Playback" }, 124 + { "HDMI OUT Capture", NULL, "HDMI CTRL SRC" }, 125 + }; 126 + 127 + static int aiu_hdmi_of_xlate_dai_name(struct snd_soc_component *component, 128 + struct of_phandle_args *args, 129 + const char **dai_name) 130 + { 131 + return aiu_of_xlate_dai_name(component, args, dai_name, AIU_HDMI); 132 + } 133 + 134 + static const struct snd_soc_component_driver aiu_hdmi_ctrl_component = { 135 + .name = "AIU HDMI Codec Control", 136 + .dapm_widgets = aiu_hdmi_ctrl_widgets, 137 + .num_dapm_widgets = ARRAY_SIZE(aiu_hdmi_ctrl_widgets), 138 + .dapm_routes = aiu_hdmi_ctrl_routes, 139 + .num_dapm_routes = ARRAY_SIZE(aiu_hdmi_ctrl_routes), 140 + .of_xlate_dai_name = aiu_hdmi_of_xlate_dai_name, 141 + .endianness = 1, 142 + .non_legacy_dai_naming = 1, 143 + }; 144 + 145 + int aiu_hdmi_ctrl_register_component(struct device *dev) 146 + { 147 + return snd_soc_register_component(dev, &aiu_hdmi_ctrl_component, 148 + aiu_hdmi_ctrl_dai_drv, 149 + ARRAY_SIZE(aiu_hdmi_ctrl_dai_drv)); 150 + } 151 +
+365
sound/soc/meson/aiu-encoder-i2s.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <sound/pcm_params.h> 9 + #include <sound/soc.h> 10 + #include <sound/soc-dai.h> 11 + 12 + #include "aiu.h" 13 + 14 + #define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0) 15 + #define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5) 16 + #define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9) 17 + #define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11) 18 + #define AIU_RST_SOFT_I2S_FAST BIT(0) 19 + 20 + #define AIU_I2S_DAC_CFG_MSB_FIRST BIT(2) 21 + #define AIU_I2S_MISC_HOLD_EN BIT(2) 22 + #define AIU_CLK_CTRL_I2S_DIV_EN BIT(0) 23 + #define AIU_CLK_CTRL_I2S_DIV GENMASK(3, 2) 24 + #define AIU_CLK_CTRL_AOCLK_INVERT BIT(6) 25 + #define AIU_CLK_CTRL_LRCLK_INVERT BIT(7) 26 + #define AIU_CLK_CTRL_LRCLK_SKEW GENMASK(9, 8) 27 + #define AIU_CLK_CTRL_MORE_HDMI_AMCLK BIT(6) 28 + #define AIU_CLK_CTRL_MORE_I2S_DIV GENMASK(5, 0) 29 + #define AIU_CODEC_DAC_LRCLK_CTRL_DIV GENMASK(11, 0) 30 + 31 + static void aiu_encoder_i2s_divider_enable(struct snd_soc_component *component, 32 + bool enable) 33 + { 34 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 35 + AIU_CLK_CTRL_I2S_DIV_EN, 36 + enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0); 37 + } 38 + 39 + static void aiu_encoder_i2s_hold(struct snd_soc_component *component, 40 + bool enable) 41 + { 42 + snd_soc_component_update_bits(component, AIU_I2S_MISC, 43 + AIU_I2S_MISC_HOLD_EN, 44 + enable ? AIU_I2S_MISC_HOLD_EN : 0); 45 + } 46 + 47 + static int aiu_encoder_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 48 + struct snd_soc_dai *dai) 49 + { 50 + struct snd_soc_component *component = dai->component; 51 + 52 + switch (cmd) { 53 + case SNDRV_PCM_TRIGGER_START: 54 + case SNDRV_PCM_TRIGGER_RESUME: 55 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 56 + aiu_encoder_i2s_hold(component, false); 57 + return 0; 58 + 59 + case SNDRV_PCM_TRIGGER_STOP: 60 + case SNDRV_PCM_TRIGGER_SUSPEND: 61 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 62 + aiu_encoder_i2s_hold(component, true); 63 + return 0; 64 + 65 + default: 66 + return -EINVAL; 67 + } 68 + } 69 + 70 + static int aiu_encoder_i2s_setup_desc(struct snd_soc_component *component, 71 + struct snd_pcm_hw_params *params) 72 + { 73 + /* Always operate in split (classic interleaved) mode */ 74 + unsigned int desc = AIU_I2S_SOURCE_DESC_MODE_SPLIT; 75 + unsigned int val; 76 + 77 + /* Reset required to update the pipeline */ 78 + snd_soc_component_write(component, AIU_RST_SOFT, AIU_RST_SOFT_I2S_FAST); 79 + snd_soc_component_read(component, AIU_I2S_SYNC, &val); 80 + 81 + switch (params_physical_width(params)) { 82 + case 16: /* Nothing to do */ 83 + break; 84 + 85 + case 32: 86 + desc |= (AIU_I2S_SOURCE_DESC_MODE_24BIT | 87 + AIU_I2S_SOURCE_DESC_MODE_32BIT); 88 + break; 89 + 90 + default: 91 + return -EINVAL; 92 + } 93 + 94 + switch (params_channels(params)) { 95 + case 2: /* Nothing to do */ 96 + break; 97 + case 8: 98 + desc |= AIU_I2S_SOURCE_DESC_MODE_8CH; 99 + break; 100 + default: 101 + return -EINVAL; 102 + } 103 + 104 + snd_soc_component_update_bits(component, AIU_I2S_SOURCE_DESC, 105 + AIU_I2S_SOURCE_DESC_MODE_8CH | 106 + AIU_I2S_SOURCE_DESC_MODE_24BIT | 107 + AIU_I2S_SOURCE_DESC_MODE_32BIT | 108 + AIU_I2S_SOURCE_DESC_MODE_SPLIT, 109 + desc); 110 + 111 + return 0; 112 + } 113 + 114 + static int aiu_encoder_i2s_set_legacy_div(struct snd_soc_component *component, 115 + struct snd_pcm_hw_params *params, 116 + unsigned int bs) 117 + { 118 + switch (bs) { 119 + case 1: 120 + case 2: 121 + case 4: 122 + case 8: 123 + /* These are the only valid legacy dividers */ 124 + break; 125 + 126 + default: 127 + dev_err(component->dev, "Unsupported i2s divider: %u\n", bs); 128 + return -EINVAL; 129 + } 130 + 131 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 132 + AIU_CLK_CTRL_I2S_DIV, 133 + FIELD_PREP(AIU_CLK_CTRL_I2S_DIV, 134 + __ffs(bs))); 135 + 136 + snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, 137 + AIU_CLK_CTRL_MORE_I2S_DIV, 138 + FIELD_PREP(AIU_CLK_CTRL_MORE_I2S_DIV, 139 + 0)); 140 + 141 + return 0; 142 + } 143 + 144 + static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *component, 145 + struct snd_pcm_hw_params *params, 146 + unsigned int bs) 147 + { 148 + /* 149 + * NOTE: this HW is odd. 150 + * In most configuration, the i2s divider is 'mclk / blck'. 151 + * However, in 16 bits - 8ch mode, this factor needs to be 152 + * increased by 50% to get the correct output rate. 153 + * No idea why ! 154 + */ 155 + if (params_width(params) == 16 && params_channels(params) == 8) { 156 + if (bs % 2) { 157 + dev_err(component->dev, 158 + "Cannot increase i2s divider by 50%%\n"); 159 + return -EINVAL; 160 + } 161 + bs += bs / 2; 162 + } 163 + 164 + /* Use CLK_MORE for mclk to bclk divider */ 165 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 166 + AIU_CLK_CTRL_I2S_DIV, 167 + FIELD_PREP(AIU_CLK_CTRL_I2S_DIV, 0)); 168 + 169 + snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, 170 + AIU_CLK_CTRL_MORE_I2S_DIV, 171 + FIELD_PREP(AIU_CLK_CTRL_MORE_I2S_DIV, 172 + bs - 1)); 173 + 174 + return 0; 175 + } 176 + 177 + static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component, 178 + struct snd_pcm_hw_params *params) 179 + { 180 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 181 + unsigned int srate = params_rate(params); 182 + unsigned int fs, bs; 183 + int ret; 184 + 185 + /* Get the oversampling factor */ 186 + fs = DIV_ROUND_CLOSEST(clk_get_rate(aiu->i2s.clks[MCLK].clk), srate); 187 + 188 + if (fs % 64) 189 + return -EINVAL; 190 + 191 + /* Send data MSB first */ 192 + snd_soc_component_update_bits(component, AIU_I2S_DAC_CFG, 193 + AIU_I2S_DAC_CFG_MSB_FIRST, 194 + AIU_I2S_DAC_CFG_MSB_FIRST); 195 + 196 + /* Set bclk to lrlck ratio */ 197 + snd_soc_component_update_bits(component, AIU_CODEC_DAC_LRCLK_CTRL, 198 + AIU_CODEC_DAC_LRCLK_CTRL_DIV, 199 + FIELD_PREP(AIU_CODEC_DAC_LRCLK_CTRL_DIV, 200 + 64 - 1)); 201 + 202 + bs = fs / 64; 203 + 204 + if (aiu->platform->has_clk_ctrl_more_i2s_div) 205 + ret = aiu_encoder_i2s_set_more_div(component, params, bs); 206 + else 207 + ret = aiu_encoder_i2s_set_legacy_div(component, params, bs); 208 + 209 + if (ret) 210 + return ret; 211 + 212 + /* Make sure amclk is used for HDMI i2s as well */ 213 + snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, 214 + AIU_CLK_CTRL_MORE_HDMI_AMCLK, 215 + AIU_CLK_CTRL_MORE_HDMI_AMCLK); 216 + 217 + return 0; 218 + } 219 + 220 + static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream, 221 + struct snd_pcm_hw_params *params, 222 + struct snd_soc_dai *dai) 223 + { 224 + struct snd_soc_component *component = dai->component; 225 + int ret; 226 + 227 + /* Disable the clock while changing the settings */ 228 + aiu_encoder_i2s_divider_enable(component, false); 229 + 230 + ret = aiu_encoder_i2s_setup_desc(component, params); 231 + if (ret) { 232 + dev_err(dai->dev, "setting i2s desc failed\n"); 233 + return ret; 234 + } 235 + 236 + ret = aiu_encoder_i2s_set_clocks(component, params); 237 + if (ret) { 238 + dev_err(dai->dev, "setting i2s clocks failed\n"); 239 + return ret; 240 + } 241 + 242 + aiu_encoder_i2s_divider_enable(component, true); 243 + 244 + return 0; 245 + } 246 + 247 + static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream, 248 + struct snd_soc_dai *dai) 249 + { 250 + struct snd_soc_component *component = dai->component; 251 + 252 + aiu_encoder_i2s_divider_enable(component, false); 253 + 254 + return 0; 255 + } 256 + 257 + static int aiu_encoder_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 258 + { 259 + struct snd_soc_component *component = dai->component; 260 + unsigned int inv = fmt & SND_SOC_DAIFMT_INV_MASK; 261 + unsigned int val = 0; 262 + unsigned int skew; 263 + 264 + /* Only CPU Master / Codec Slave supported ATM */ 265 + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) 266 + return -EINVAL; 267 + 268 + if (inv == SND_SOC_DAIFMT_NB_IF || 269 + inv == SND_SOC_DAIFMT_IB_IF) 270 + val |= AIU_CLK_CTRL_LRCLK_INVERT; 271 + 272 + if (inv == SND_SOC_DAIFMT_IB_NF || 273 + inv == SND_SOC_DAIFMT_IB_IF) 274 + val |= AIU_CLK_CTRL_AOCLK_INVERT; 275 + 276 + /* Signal skew */ 277 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 278 + case SND_SOC_DAIFMT_I2S: 279 + /* Invert sample clock for i2s */ 280 + val ^= AIU_CLK_CTRL_LRCLK_INVERT; 281 + skew = 1; 282 + break; 283 + case SND_SOC_DAIFMT_LEFT_J: 284 + skew = 0; 285 + break; 286 + default: 287 + return -EINVAL; 288 + } 289 + 290 + val |= FIELD_PREP(AIU_CLK_CTRL_LRCLK_SKEW, skew); 291 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 292 + AIU_CLK_CTRL_LRCLK_INVERT | 293 + AIU_CLK_CTRL_AOCLK_INVERT | 294 + AIU_CLK_CTRL_LRCLK_SKEW, 295 + val); 296 + 297 + return 0; 298 + } 299 + 300 + static int aiu_encoder_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 301 + unsigned int freq, int dir) 302 + { 303 + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); 304 + int ret; 305 + 306 + if (WARN_ON(clk_id != 0)) 307 + return -EINVAL; 308 + 309 + if (dir == SND_SOC_CLOCK_IN) 310 + return 0; 311 + 312 + ret = clk_set_rate(aiu->i2s.clks[MCLK].clk, freq); 313 + if (ret) 314 + dev_err(dai->dev, "Failed to set sysclk to %uHz", freq); 315 + 316 + return ret; 317 + } 318 + 319 + static const unsigned int hw_channels[] = {2, 8}; 320 + static const struct snd_pcm_hw_constraint_list hw_channel_constraints = { 321 + .list = hw_channels, 322 + .count = ARRAY_SIZE(hw_channels), 323 + .mask = 0, 324 + }; 325 + 326 + static int aiu_encoder_i2s_startup(struct snd_pcm_substream *substream, 327 + struct snd_soc_dai *dai) 328 + { 329 + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); 330 + int ret; 331 + 332 + /* Make sure the encoder gets either 2 or 8 channels */ 333 + ret = snd_pcm_hw_constraint_list(substream->runtime, 0, 334 + SNDRV_PCM_HW_PARAM_CHANNELS, 335 + &hw_channel_constraints); 336 + if (ret) { 337 + dev_err(dai->dev, "adding channels constraints failed\n"); 338 + return ret; 339 + } 340 + 341 + ret = clk_bulk_prepare_enable(aiu->i2s.clk_num, aiu->i2s.clks); 342 + if (ret) 343 + dev_err(dai->dev, "failed to enable i2s clocks\n"); 344 + 345 + return ret; 346 + } 347 + 348 + static void aiu_encoder_i2s_shutdown(struct snd_pcm_substream *substream, 349 + struct snd_soc_dai *dai) 350 + { 351 + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); 352 + 353 + clk_bulk_disable_unprepare(aiu->i2s.clk_num, aiu->i2s.clks); 354 + } 355 + 356 + const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = { 357 + .trigger = aiu_encoder_i2s_trigger, 358 + .hw_params = aiu_encoder_i2s_hw_params, 359 + .hw_free = aiu_encoder_i2s_hw_free, 360 + .set_fmt = aiu_encoder_i2s_set_fmt, 361 + .set_sysclk = aiu_encoder_i2s_set_sysclk, 362 + .startup = aiu_encoder_i2s_startup, 363 + .shutdown = aiu_encoder_i2s_shutdown, 364 + }; 365 +
+209
sound/soc/meson/aiu-encoder-spdif.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <sound/pcm_params.h> 9 + #include <sound/pcm_iec958.h> 10 + #include <sound/soc.h> 11 + #include <sound/soc-dai.h> 12 + 13 + #include "aiu.h" 14 + 15 + #define AIU_958_MISC_NON_PCM BIT(0) 16 + #define AIU_958_MISC_MODE_16BITS BIT(1) 17 + #define AIU_958_MISC_16BITS_ALIGN GENMASK(6, 5) 18 + #define AIU_958_MISC_MODE_32BITS BIT(7) 19 + #define AIU_958_MISC_U_FROM_STREAM BIT(12) 20 + #define AIU_958_MISC_FORCE_LR BIT(13) 21 + #define AIU_958_CTRL_HOLD_EN BIT(0) 22 + #define AIU_CLK_CTRL_958_DIV_EN BIT(1) 23 + #define AIU_CLK_CTRL_958_DIV GENMASK(5, 4) 24 + #define AIU_CLK_CTRL_958_DIV_MORE BIT(12) 25 + 26 + #define AIU_CS_WORD_LEN 4 27 + #define AIU_958_INTERNAL_DIV 2 28 + 29 + static void 30 + aiu_encoder_spdif_divider_enable(struct snd_soc_component *component, 31 + bool enable) 32 + { 33 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 34 + AIU_CLK_CTRL_958_DIV_EN, 35 + enable ? AIU_CLK_CTRL_958_DIV_EN : 0); 36 + } 37 + 38 + static void aiu_encoder_spdif_hold(struct snd_soc_component *component, 39 + bool enable) 40 + { 41 + snd_soc_component_update_bits(component, AIU_958_CTRL, 42 + AIU_958_CTRL_HOLD_EN, 43 + enable ? AIU_958_CTRL_HOLD_EN : 0); 44 + } 45 + 46 + static int 47 + aiu_encoder_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 48 + struct snd_soc_dai *dai) 49 + { 50 + struct snd_soc_component *component = dai->component; 51 + 52 + switch (cmd) { 53 + case SNDRV_PCM_TRIGGER_START: 54 + case SNDRV_PCM_TRIGGER_RESUME: 55 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 56 + aiu_encoder_spdif_hold(component, false); 57 + return 0; 58 + 59 + case SNDRV_PCM_TRIGGER_STOP: 60 + case SNDRV_PCM_TRIGGER_SUSPEND: 61 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 62 + aiu_encoder_spdif_hold(component, true); 63 + return 0; 64 + 65 + default: 66 + return -EINVAL; 67 + } 68 + } 69 + 70 + static int aiu_encoder_spdif_setup_cs_word(struct snd_soc_component *component, 71 + struct snd_pcm_hw_params *params) 72 + { 73 + u8 cs[AIU_CS_WORD_LEN]; 74 + unsigned int val; 75 + int ret; 76 + 77 + ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, 78 + AIU_CS_WORD_LEN); 79 + if (ret < 0) 80 + return ret; 81 + 82 + /* Write the 1st half word */ 83 + val = cs[1] | cs[0] << 8; 84 + snd_soc_component_write(component, AIU_958_CHSTAT_L0, val); 85 + snd_soc_component_write(component, AIU_958_CHSTAT_R0, val); 86 + 87 + /* Write the 2nd half word */ 88 + val = cs[3] | cs[2] << 8; 89 + snd_soc_component_write(component, AIU_958_CHSTAT_L1, val); 90 + snd_soc_component_write(component, AIU_958_CHSTAT_R1, val); 91 + 92 + return 0; 93 + } 94 + 95 + static int aiu_encoder_spdif_hw_params(struct snd_pcm_substream *substream, 96 + struct snd_pcm_hw_params *params, 97 + struct snd_soc_dai *dai) 98 + { 99 + struct snd_soc_component *component = dai->component; 100 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 101 + unsigned int val = 0, mrate; 102 + int ret; 103 + 104 + /* Disable the clock while changing the settings */ 105 + aiu_encoder_spdif_divider_enable(component, false); 106 + 107 + switch (params_physical_width(params)) { 108 + case 16: 109 + val |= AIU_958_MISC_MODE_16BITS; 110 + val |= FIELD_PREP(AIU_958_MISC_16BITS_ALIGN, 2); 111 + break; 112 + case 32: 113 + val |= AIU_958_MISC_MODE_32BITS; 114 + break; 115 + default: 116 + dev_err(dai->dev, "Unsupport physical width\n"); 117 + return -EINVAL; 118 + } 119 + 120 + snd_soc_component_update_bits(component, AIU_958_MISC, 121 + AIU_958_MISC_NON_PCM | 122 + AIU_958_MISC_MODE_16BITS | 123 + AIU_958_MISC_16BITS_ALIGN | 124 + AIU_958_MISC_MODE_32BITS | 125 + AIU_958_MISC_FORCE_LR | 126 + AIU_958_MISC_U_FROM_STREAM, 127 + val); 128 + 129 + /* Set the stream channel status word */ 130 + ret = aiu_encoder_spdif_setup_cs_word(component, params); 131 + if (ret) { 132 + dev_err(dai->dev, "failed to set channel status word\n"); 133 + return ret; 134 + } 135 + 136 + snd_soc_component_update_bits(component, AIU_CLK_CTRL, 137 + AIU_CLK_CTRL_958_DIV | 138 + AIU_CLK_CTRL_958_DIV_MORE, 139 + FIELD_PREP(AIU_CLK_CTRL_958_DIV, 140 + __ffs(AIU_958_INTERNAL_DIV))); 141 + 142 + /* 2 * 32bits per subframe * 2 channels = 128 */ 143 + mrate = params_rate(params) * 128 * AIU_958_INTERNAL_DIV; 144 + ret = clk_set_rate(aiu->spdif.clks[MCLK].clk, mrate); 145 + if (ret) { 146 + dev_err(dai->dev, "failed to set mclk rate\n"); 147 + return ret; 148 + } 149 + 150 + aiu_encoder_spdif_divider_enable(component, true); 151 + 152 + return 0; 153 + } 154 + 155 + static int aiu_encoder_spdif_hw_free(struct snd_pcm_substream *substream, 156 + struct snd_soc_dai *dai) 157 + { 158 + struct snd_soc_component *component = dai->component; 159 + 160 + aiu_encoder_spdif_divider_enable(component, false); 161 + 162 + return 0; 163 + } 164 + 165 + static int aiu_encoder_spdif_startup(struct snd_pcm_substream *substream, 166 + struct snd_soc_dai *dai) 167 + { 168 + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); 169 + int ret; 170 + 171 + /* 172 + * NOTE: Make sure the spdif block is on its own divider. 173 + * 174 + * The spdif can be clocked by the i2s master clock or its own 175 + * clock. We should (in theory) change the source depending on the 176 + * origin of the data. 177 + * 178 + * However, considering the clocking scheme used on these platforms, 179 + * the master clocks will pick the same PLL source when they are 180 + * playing from the same FIFO. The clock should be in sync so, it 181 + * should not be necessary to reparent the spdif master clock. 182 + */ 183 + ret = clk_set_parent(aiu->spdif.clks[MCLK].clk, 184 + aiu->spdif_mclk); 185 + if (ret) 186 + return ret; 187 + 188 + ret = clk_bulk_prepare_enable(aiu->spdif.clk_num, aiu->spdif.clks); 189 + if (ret) 190 + dev_err(dai->dev, "failed to enable spdif clocks\n"); 191 + 192 + return ret; 193 + } 194 + 195 + static void aiu_encoder_spdif_shutdown(struct snd_pcm_substream *substream, 196 + struct snd_soc_dai *dai) 197 + { 198 + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); 199 + 200 + clk_bulk_disable_unprepare(aiu->spdif.clk_num, aiu->spdif.clks); 201 + } 202 + 203 + const struct snd_soc_dai_ops aiu_encoder_spdif_dai_ops = { 204 + .trigger = aiu_encoder_spdif_trigger, 205 + .hw_params = aiu_encoder_spdif_hw_params, 206 + .hw_free = aiu_encoder_spdif_hw_free, 207 + .startup = aiu_encoder_spdif_startup, 208 + .shutdown = aiu_encoder_spdif_shutdown, 209 + };
+153
sound/soc/meson/aiu-fifo-i2s.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <sound/pcm_params.h> 9 + #include <sound/soc.h> 10 + #include <sound/soc-dai.h> 11 + 12 + #include "aiu.h" 13 + #include "aiu-fifo.h" 14 + 15 + #define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0) 16 + #define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5) 17 + #define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9) 18 + #define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11) 19 + #define AIU_MEM_I2S_MASKS_IRQ_BLOCK GENMASK(31, 16) 20 + #define AIU_MEM_I2S_CONTROL_MODE_16BIT BIT(6) 21 + #define AIU_MEM_I2S_BUF_CNTL_INIT BIT(0) 22 + #define AIU_RST_SOFT_I2S_FAST BIT(0) 23 + 24 + #define AIU_FIFO_I2S_BLOCK 256 25 + 26 + static struct snd_pcm_hardware fifo_i2s_pcm = { 27 + .info = (SNDRV_PCM_INFO_INTERLEAVED | 28 + SNDRV_PCM_INFO_MMAP | 29 + SNDRV_PCM_INFO_MMAP_VALID | 30 + SNDRV_PCM_INFO_PAUSE), 31 + .formats = AIU_FORMATS, 32 + .rate_min = 5512, 33 + .rate_max = 192000, 34 + .channels_min = 2, 35 + .channels_max = 8, 36 + .period_bytes_min = AIU_FIFO_I2S_BLOCK, 37 + .period_bytes_max = AIU_FIFO_I2S_BLOCK * USHRT_MAX, 38 + .periods_min = 2, 39 + .periods_max = UINT_MAX, 40 + 41 + /* No real justification for this */ 42 + .buffer_bytes_max = 1 * 1024 * 1024, 43 + }; 44 + 45 + static int aiu_fifo_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 46 + struct snd_soc_dai *dai) 47 + { 48 + struct snd_soc_component *component = dai->component; 49 + unsigned int val; 50 + 51 + switch (cmd) { 52 + case SNDRV_PCM_TRIGGER_START: 53 + case SNDRV_PCM_TRIGGER_RESUME: 54 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 55 + snd_soc_component_write(component, AIU_RST_SOFT, 56 + AIU_RST_SOFT_I2S_FAST); 57 + snd_soc_component_read(component, AIU_I2S_SYNC, &val); 58 + break; 59 + } 60 + 61 + return aiu_fifo_trigger(substream, cmd, dai); 62 + } 63 + 64 + static int aiu_fifo_i2s_prepare(struct snd_pcm_substream *substream, 65 + struct snd_soc_dai *dai) 66 + { 67 + struct snd_soc_component *component = dai->component; 68 + int ret; 69 + 70 + ret = aiu_fifo_prepare(substream, dai); 71 + if (ret) 72 + return ret; 73 + 74 + snd_soc_component_update_bits(component, 75 + AIU_MEM_I2S_BUF_CNTL, 76 + AIU_MEM_I2S_BUF_CNTL_INIT, 77 + AIU_MEM_I2S_BUF_CNTL_INIT); 78 + snd_soc_component_update_bits(component, 79 + AIU_MEM_I2S_BUF_CNTL, 80 + AIU_MEM_I2S_BUF_CNTL_INIT, 0); 81 + 82 + return 0; 83 + } 84 + 85 + static int aiu_fifo_i2s_hw_params(struct snd_pcm_substream *substream, 86 + struct snd_pcm_hw_params *params, 87 + struct snd_soc_dai *dai) 88 + { 89 + struct snd_soc_component *component = dai->component; 90 + struct aiu_fifo *fifo = dai->playback_dma_data; 91 + unsigned int val; 92 + int ret; 93 + 94 + ret = aiu_fifo_hw_params(substream, params, dai); 95 + if (ret) 96 + return ret; 97 + 98 + switch (params_physical_width(params)) { 99 + case 16: 100 + val = AIU_MEM_I2S_CONTROL_MODE_16BIT; 101 + break; 102 + case 32: 103 + val = 0; 104 + break; 105 + default: 106 + dev_err(dai->dev, "Unsupported physical width %u\n", 107 + params_physical_width(params)); 108 + return -EINVAL; 109 + } 110 + 111 + snd_soc_component_update_bits(component, AIU_MEM_I2S_CONTROL, 112 + AIU_MEM_I2S_CONTROL_MODE_16BIT, 113 + val); 114 + 115 + /* Setup the irq periodicity */ 116 + val = params_period_bytes(params) / fifo->fifo_block; 117 + val = FIELD_PREP(AIU_MEM_I2S_MASKS_IRQ_BLOCK, val); 118 + snd_soc_component_update_bits(component, AIU_MEM_I2S_MASKS, 119 + AIU_MEM_I2S_MASKS_IRQ_BLOCK, val); 120 + 121 + return 0; 122 + } 123 + 124 + const struct snd_soc_dai_ops aiu_fifo_i2s_dai_ops = { 125 + .trigger = aiu_fifo_i2s_trigger, 126 + .prepare = aiu_fifo_i2s_prepare, 127 + .hw_params = aiu_fifo_i2s_hw_params, 128 + .hw_free = aiu_fifo_hw_free, 129 + .startup = aiu_fifo_startup, 130 + .shutdown = aiu_fifo_shutdown, 131 + }; 132 + 133 + int aiu_fifo_i2s_dai_probe(struct snd_soc_dai *dai) 134 + { 135 + struct snd_soc_component *component = dai->component; 136 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 137 + struct aiu_fifo *fifo; 138 + int ret; 139 + 140 + ret = aiu_fifo_dai_probe(dai); 141 + if (ret) 142 + return ret; 143 + 144 + fifo = dai->playback_dma_data; 145 + 146 + fifo->pcm = &fifo_i2s_pcm; 147 + fifo->mem_offset = AIU_MEM_I2S_START; 148 + fifo->fifo_block = AIU_FIFO_I2S_BLOCK; 149 + fifo->pclk = aiu->i2s.clks[PCLK].clk; 150 + fifo->irq = aiu->i2s.irq; 151 + 152 + return 0; 153 + }
+186
sound/soc/meson/aiu-fifo-spdif.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/clk.h> 7 + #include <sound/pcm_params.h> 8 + #include <sound/soc.h> 9 + #include <sound/soc-dai.h> 10 + 11 + #include "aiu.h" 12 + #include "aiu-fifo.h" 13 + 14 + #define AIU_IEC958_DCU_FF_CTRL_EN BIT(0) 15 + #define AIU_IEC958_DCU_FF_CTRL_AUTO_DISABLE BIT(1) 16 + #define AIU_IEC958_DCU_FF_CTRL_IRQ_MODE GENMASK(3, 2) 17 + #define AIU_IEC958_DCU_FF_CTRL_IRQ_OUT_THD BIT(2) 18 + #define AIU_IEC958_DCU_FF_CTRL_IRQ_FRAME_READ BIT(3) 19 + #define AIU_IEC958_DCU_FF_CTRL_SYNC_HEAD_EN BIT(4) 20 + #define AIU_IEC958_DCU_FF_CTRL_BYTE_SEEK BIT(5) 21 + #define AIU_IEC958_DCU_FF_CTRL_CONTINUE BIT(6) 22 + #define AIU_MEM_IEC958_CONTROL_ENDIAN GENMASK(5, 3) 23 + #define AIU_MEM_IEC958_CONTROL_RD_DDR BIT(6) 24 + #define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7) 25 + #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8) 26 + #define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0) 27 + 28 + #define AIU_FIFO_SPDIF_BLOCK 8 29 + 30 + static struct snd_pcm_hardware fifo_spdif_pcm = { 31 + .info = (SNDRV_PCM_INFO_INTERLEAVED | 32 + SNDRV_PCM_INFO_MMAP | 33 + SNDRV_PCM_INFO_MMAP_VALID | 34 + SNDRV_PCM_INFO_PAUSE), 35 + .formats = AIU_FORMATS, 36 + .rate_min = 5512, 37 + .rate_max = 192000, 38 + .channels_min = 2, 39 + .channels_max = 2, 40 + .period_bytes_min = AIU_FIFO_SPDIF_BLOCK, 41 + .period_bytes_max = AIU_FIFO_SPDIF_BLOCK * USHRT_MAX, 42 + .periods_min = 2, 43 + .periods_max = UINT_MAX, 44 + 45 + /* No real justification for this */ 46 + .buffer_bytes_max = 1 * 1024 * 1024, 47 + }; 48 + 49 + static void fifo_spdif_dcu_enable(struct snd_soc_component *component, 50 + bool enable) 51 + { 52 + snd_soc_component_update_bits(component, AIU_IEC958_DCU_FF_CTRL, 53 + AIU_IEC958_DCU_FF_CTRL_EN, 54 + enable ? AIU_IEC958_DCU_FF_CTRL_EN : 0); 55 + } 56 + 57 + static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 58 + struct snd_soc_dai *dai) 59 + { 60 + struct snd_soc_component *component = dai->component; 61 + int ret; 62 + 63 + ret = aiu_fifo_trigger(substream, cmd, dai); 64 + if (ret) 65 + return ret; 66 + 67 + switch (cmd) { 68 + case SNDRV_PCM_TRIGGER_START: 69 + case SNDRV_PCM_TRIGGER_RESUME: 70 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 71 + fifo_spdif_dcu_enable(component, true); 72 + break; 73 + case SNDRV_PCM_TRIGGER_SUSPEND: 74 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 75 + case SNDRV_PCM_TRIGGER_STOP: 76 + fifo_spdif_dcu_enable(component, false); 77 + break; 78 + default: 79 + return -EINVAL; 80 + } 81 + 82 + return 0; 83 + } 84 + 85 + static int fifo_spdif_prepare(struct snd_pcm_substream *substream, 86 + struct snd_soc_dai *dai) 87 + { 88 + struct snd_soc_component *component = dai->component; 89 + int ret; 90 + 91 + ret = aiu_fifo_prepare(substream, dai); 92 + if (ret) 93 + return ret; 94 + 95 + snd_soc_component_update_bits(component, 96 + AIU_MEM_IEC958_BUF_CNTL, 97 + AIU_MEM_IEC958_BUF_CNTL_INIT, 98 + AIU_MEM_IEC958_BUF_CNTL_INIT); 99 + snd_soc_component_update_bits(component, 100 + AIU_MEM_IEC958_BUF_CNTL, 101 + AIU_MEM_IEC958_BUF_CNTL_INIT, 0); 102 + 103 + return 0; 104 + } 105 + 106 + static int fifo_spdif_hw_params(struct snd_pcm_substream *substream, 107 + struct snd_pcm_hw_params *params, 108 + struct snd_soc_dai *dai) 109 + { 110 + struct snd_soc_component *component = dai->component; 111 + unsigned int val; 112 + int ret; 113 + 114 + ret = aiu_fifo_hw_params(substream, params, dai); 115 + if (ret) 116 + return ret; 117 + 118 + val = AIU_MEM_IEC958_CONTROL_RD_DDR | 119 + AIU_MEM_IEC958_CONTROL_MODE_LINEAR; 120 + 121 + switch (params_physical_width(params)) { 122 + case 16: 123 + val |= AIU_MEM_IEC958_CONTROL_MODE_16BIT; 124 + break; 125 + case 32: 126 + break; 127 + default: 128 + dev_err(dai->dev, "Unsupported physical width %u\n", 129 + params_physical_width(params)); 130 + return -EINVAL; 131 + } 132 + 133 + snd_soc_component_update_bits(component, AIU_MEM_IEC958_CONTROL, 134 + AIU_MEM_IEC958_CONTROL_ENDIAN | 135 + AIU_MEM_IEC958_CONTROL_RD_DDR | 136 + AIU_MEM_IEC958_CONTROL_MODE_LINEAR | 137 + AIU_MEM_IEC958_CONTROL_MODE_16BIT, 138 + val); 139 + 140 + /* Number bytes read by the FIFO between each IRQ */ 141 + snd_soc_component_write(component, AIU_IEC958_BPF, 142 + params_period_bytes(params)); 143 + 144 + /* 145 + * AUTO_DISABLE and SYNC_HEAD are enabled by default but 146 + * this should be disabled in PCM (uncompressed) mode 147 + */ 148 + snd_soc_component_update_bits(component, AIU_IEC958_DCU_FF_CTRL, 149 + AIU_IEC958_DCU_FF_CTRL_AUTO_DISABLE | 150 + AIU_IEC958_DCU_FF_CTRL_IRQ_MODE | 151 + AIU_IEC958_DCU_FF_CTRL_SYNC_HEAD_EN, 152 + AIU_IEC958_DCU_FF_CTRL_IRQ_FRAME_READ); 153 + 154 + return 0; 155 + } 156 + 157 + const struct snd_soc_dai_ops aiu_fifo_spdif_dai_ops = { 158 + .trigger = fifo_spdif_trigger, 159 + .prepare = fifo_spdif_prepare, 160 + .hw_params = fifo_spdif_hw_params, 161 + .hw_free = aiu_fifo_hw_free, 162 + .startup = aiu_fifo_startup, 163 + .shutdown = aiu_fifo_shutdown, 164 + }; 165 + 166 + int aiu_fifo_spdif_dai_probe(struct snd_soc_dai *dai) 167 + { 168 + struct snd_soc_component *component = dai->component; 169 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 170 + struct aiu_fifo *fifo; 171 + int ret; 172 + 173 + ret = aiu_fifo_dai_probe(dai); 174 + if (ret) 175 + return ret; 176 + 177 + fifo = dai->playback_dma_data; 178 + 179 + fifo->pcm = &fifo_spdif_pcm; 180 + fifo->mem_offset = AIU_MEM_IEC958_START; 181 + fifo->fifo_block = 1; 182 + fifo->pclk = aiu->spdif.clks[PCLK].clk; 183 + fifo->irq = aiu->spdif.irq; 184 + 185 + return 0; 186 + }
+223
sound/soc/meson/aiu-fifo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <sound/pcm_params.h> 9 + #include <sound/soc.h> 10 + #include <sound/soc-dai.h> 11 + 12 + #include "aiu-fifo.h" 13 + 14 + #define AIU_MEM_START 0x00 15 + #define AIU_MEM_RD 0x04 16 + #define AIU_MEM_END 0x08 17 + #define AIU_MEM_MASKS 0x0c 18 + #define AIU_MEM_MASK_CH_RD GENMASK(7, 0) 19 + #define AIU_MEM_MASK_CH_MEM GENMASK(15, 8) 20 + #define AIU_MEM_CONTROL 0x10 21 + #define AIU_MEM_CONTROL_INIT BIT(0) 22 + #define AIU_MEM_CONTROL_FILL_EN BIT(1) 23 + #define AIU_MEM_CONTROL_EMPTY_EN BIT(2) 24 + 25 + static struct snd_soc_dai *aiu_fifo_dai(struct snd_pcm_substream *ss) 26 + { 27 + struct snd_soc_pcm_runtime *rtd = ss->private_data; 28 + 29 + return asoc_rtd_to_cpu(rtd, 0); 30 + } 31 + 32 + snd_pcm_uframes_t aiu_fifo_pointer(struct snd_soc_component *component, 33 + struct snd_pcm_substream *substream) 34 + { 35 + struct snd_soc_dai *dai = aiu_fifo_dai(substream); 36 + struct aiu_fifo *fifo = dai->playback_dma_data; 37 + struct snd_pcm_runtime *runtime = substream->runtime; 38 + unsigned int addr; 39 + 40 + snd_soc_component_read(component, fifo->mem_offset + AIU_MEM_RD, 41 + &addr); 42 + 43 + return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr); 44 + } 45 + 46 + static void aiu_fifo_enable(struct snd_soc_dai *dai, bool enable) 47 + { 48 + struct snd_soc_component *component = dai->component; 49 + struct aiu_fifo *fifo = dai->playback_dma_data; 50 + unsigned int en_mask = (AIU_MEM_CONTROL_FILL_EN | 51 + AIU_MEM_CONTROL_EMPTY_EN); 52 + 53 + snd_soc_component_update_bits(component, 54 + fifo->mem_offset + AIU_MEM_CONTROL, 55 + en_mask, enable ? en_mask : 0); 56 + } 57 + 58 + int aiu_fifo_trigger(struct snd_pcm_substream *substream, int cmd, 59 + struct snd_soc_dai *dai) 60 + { 61 + switch (cmd) { 62 + case SNDRV_PCM_TRIGGER_START: 63 + case SNDRV_PCM_TRIGGER_RESUME: 64 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 65 + aiu_fifo_enable(dai, true); 66 + break; 67 + case SNDRV_PCM_TRIGGER_SUSPEND: 68 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 69 + case SNDRV_PCM_TRIGGER_STOP: 70 + aiu_fifo_enable(dai, false); 71 + break; 72 + default: 73 + return -EINVAL; 74 + } 75 + 76 + return 0; 77 + } 78 + 79 + int aiu_fifo_prepare(struct snd_pcm_substream *substream, 80 + struct snd_soc_dai *dai) 81 + { 82 + struct snd_soc_component *component = dai->component; 83 + struct aiu_fifo *fifo = dai->playback_dma_data; 84 + 85 + snd_soc_component_update_bits(component, 86 + fifo->mem_offset + AIU_MEM_CONTROL, 87 + AIU_MEM_CONTROL_INIT, 88 + AIU_MEM_CONTROL_INIT); 89 + snd_soc_component_update_bits(component, 90 + fifo->mem_offset + AIU_MEM_CONTROL, 91 + AIU_MEM_CONTROL_INIT, 0); 92 + return 0; 93 + } 94 + 95 + int aiu_fifo_hw_params(struct snd_pcm_substream *substream, 96 + struct snd_pcm_hw_params *params, 97 + struct snd_soc_dai *dai) 98 + { 99 + struct snd_pcm_runtime *runtime = substream->runtime; 100 + struct snd_soc_component *component = dai->component; 101 + struct aiu_fifo *fifo = dai->playback_dma_data; 102 + dma_addr_t end; 103 + int ret; 104 + 105 + ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 106 + if (ret < 0) 107 + return ret; 108 + 109 + /* Setup the fifo boundaries */ 110 + end = runtime->dma_addr + runtime->dma_bytes - fifo->fifo_block; 111 + snd_soc_component_write(component, fifo->mem_offset + AIU_MEM_START, 112 + runtime->dma_addr); 113 + snd_soc_component_write(component, fifo->mem_offset + AIU_MEM_RD, 114 + runtime->dma_addr); 115 + snd_soc_component_write(component, fifo->mem_offset + AIU_MEM_END, 116 + end); 117 + 118 + /* Setup the fifo to read all the memory - no skip */ 119 + snd_soc_component_update_bits(component, 120 + fifo->mem_offset + AIU_MEM_MASKS, 121 + AIU_MEM_MASK_CH_RD | AIU_MEM_MASK_CH_MEM, 122 + FIELD_PREP(AIU_MEM_MASK_CH_RD, 0xff) | 123 + FIELD_PREP(AIU_MEM_MASK_CH_MEM, 0xff)); 124 + 125 + return 0; 126 + } 127 + 128 + int aiu_fifo_hw_free(struct snd_pcm_substream *substream, 129 + struct snd_soc_dai *dai) 130 + { 131 + return snd_pcm_lib_free_pages(substream); 132 + } 133 + 134 + static irqreturn_t aiu_fifo_isr(int irq, void *dev_id) 135 + { 136 + struct snd_pcm_substream *playback = dev_id; 137 + 138 + snd_pcm_period_elapsed(playback); 139 + 140 + return IRQ_HANDLED; 141 + } 142 + 143 + int aiu_fifo_startup(struct snd_pcm_substream *substream, 144 + struct snd_soc_dai *dai) 145 + { 146 + struct aiu_fifo *fifo = dai->playback_dma_data; 147 + int ret; 148 + 149 + snd_soc_set_runtime_hwparams(substream, fifo->pcm); 150 + 151 + /* 152 + * Make sure the buffer and period size are multiple of the fifo burst 153 + * size 154 + */ 155 + ret = snd_pcm_hw_constraint_step(substream->runtime, 0, 156 + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 157 + fifo->fifo_block); 158 + if (ret) 159 + return ret; 160 + 161 + ret = snd_pcm_hw_constraint_step(substream->runtime, 0, 162 + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 163 + fifo->fifo_block); 164 + if (ret) 165 + return ret; 166 + 167 + ret = clk_prepare_enable(fifo->pclk); 168 + if (ret) 169 + return ret; 170 + 171 + ret = request_irq(fifo->irq, aiu_fifo_isr, 0, dev_name(dai->dev), 172 + substream); 173 + if (ret) 174 + clk_disable_unprepare(fifo->pclk); 175 + 176 + return ret; 177 + } 178 + 179 + void aiu_fifo_shutdown(struct snd_pcm_substream *substream, 180 + struct snd_soc_dai *dai) 181 + { 182 + struct aiu_fifo *fifo = dai->playback_dma_data; 183 + 184 + free_irq(fifo->irq, substream); 185 + clk_disable_unprepare(fifo->pclk); 186 + } 187 + 188 + int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, 189 + struct snd_soc_dai *dai) 190 + { 191 + struct snd_pcm_substream *substream = 192 + rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 193 + struct snd_card *card = rtd->card->snd_card; 194 + struct aiu_fifo *fifo = dai->playback_dma_data; 195 + size_t size = fifo->pcm->buffer_bytes_max; 196 + 197 + snd_pcm_lib_preallocate_pages(substream, 198 + SNDRV_DMA_TYPE_DEV, 199 + card->dev, size, size); 200 + 201 + return 0; 202 + } 203 + 204 + int aiu_fifo_dai_probe(struct snd_soc_dai *dai) 205 + { 206 + struct aiu_fifo *fifo; 207 + 208 + fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); 209 + if (!fifo) 210 + return -ENOMEM; 211 + 212 + dai->playback_dma_data = fifo; 213 + 214 + return 0; 215 + } 216 + 217 + int aiu_fifo_dai_remove(struct snd_soc_dai *dai) 218 + { 219 + kfree(dai->playback_dma_data); 220 + 221 + return 0; 222 + } 223 +
+50
sound/soc/meson/aiu-fifo.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (c) 2020 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef _MESON_AIU_FIFO_H 8 + #define _MESON_AIU_FIFO_H 9 + 10 + struct snd_pcm_hardware; 11 + struct snd_soc_component_driver; 12 + struct snd_soc_dai_driver; 13 + struct clk; 14 + struct snd_pcm_ops; 15 + struct snd_pcm_substream; 16 + struct snd_soc_dai; 17 + struct snd_pcm_hw_params; 18 + struct platform_device; 19 + 20 + struct aiu_fifo { 21 + struct snd_pcm_hardware *pcm; 22 + unsigned int mem_offset; 23 + unsigned int fifo_block; 24 + struct clk *pclk; 25 + int irq; 26 + }; 27 + 28 + int aiu_fifo_dai_probe(struct snd_soc_dai *dai); 29 + int aiu_fifo_dai_remove(struct snd_soc_dai *dai); 30 + 31 + snd_pcm_uframes_t aiu_fifo_pointer(struct snd_soc_component *component, 32 + struct snd_pcm_substream *substream); 33 + 34 + int aiu_fifo_trigger(struct snd_pcm_substream *substream, int cmd, 35 + struct snd_soc_dai *dai); 36 + int aiu_fifo_prepare(struct snd_pcm_substream *substream, 37 + struct snd_soc_dai *dai); 38 + int aiu_fifo_hw_params(struct snd_pcm_substream *substream, 39 + struct snd_pcm_hw_params *params, 40 + struct snd_soc_dai *dai); 41 + int aiu_fifo_hw_free(struct snd_pcm_substream *substream, 42 + struct snd_soc_dai *dai); 43 + int aiu_fifo_startup(struct snd_pcm_substream *substream, 44 + struct snd_soc_dai *dai); 45 + void aiu_fifo_shutdown(struct snd_pcm_substream *substream, 46 + struct snd_soc_dai *dai); 47 + int aiu_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, 48 + struct snd_soc_dai *dai); 49 + 50 + #endif /* _MESON_AIU_FIFO_H */
+388
sound/soc/meson/aiu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <linux/module.h> 9 + #include <linux/of_platform.h> 10 + #include <linux/regmap.h> 11 + #include <linux/reset.h> 12 + #include <sound/soc.h> 13 + #include <sound/soc-dai.h> 14 + 15 + #include <dt-bindings/sound/meson-aiu.h> 16 + #include "aiu.h" 17 + #include "aiu-fifo.h" 18 + 19 + #define AIU_I2S_MISC_958_SRC_SHIFT 3 20 + 21 + static const char * const aiu_spdif_encode_sel_texts[] = { 22 + "SPDIF", "I2S", 23 + }; 24 + 25 + static SOC_ENUM_SINGLE_DECL(aiu_spdif_encode_sel_enum, AIU_I2S_MISC, 26 + AIU_I2S_MISC_958_SRC_SHIFT, 27 + aiu_spdif_encode_sel_texts); 28 + 29 + static const struct snd_kcontrol_new aiu_spdif_encode_mux = 30 + SOC_DAPM_ENUM("SPDIF Buffer Src", aiu_spdif_encode_sel_enum); 31 + 32 + static const struct snd_soc_dapm_widget aiu_cpu_dapm_widgets[] = { 33 + SND_SOC_DAPM_MUX("SPDIF SRC SEL", SND_SOC_NOPM, 0, 0, 34 + &aiu_spdif_encode_mux), 35 + }; 36 + 37 + static const struct snd_soc_dapm_route aiu_cpu_dapm_routes[] = { 38 + { "I2S Encoder Playback", NULL, "I2S FIFO Playback" }, 39 + { "SPDIF SRC SEL", "SPDIF", "SPDIF FIFO Playback" }, 40 + { "SPDIF SRC SEL", "I2S", "I2S FIFO Playback" }, 41 + { "SPDIF Encoder Playback", NULL, "SPDIF SRC SEL" }, 42 + }; 43 + 44 + int aiu_of_xlate_dai_name(struct snd_soc_component *component, 45 + struct of_phandle_args *args, 46 + const char **dai_name, 47 + unsigned int component_id) 48 + { 49 + struct snd_soc_dai *dai; 50 + int id; 51 + 52 + if (args->args_count != 2) 53 + return -EINVAL; 54 + 55 + if (args->args[0] != component_id) 56 + return -EINVAL; 57 + 58 + id = args->args[1]; 59 + 60 + if (id < 0 || id >= component->num_dai) 61 + return -EINVAL; 62 + 63 + for_each_component_dais(component, dai) { 64 + if (id == 0) 65 + break; 66 + id--; 67 + } 68 + 69 + *dai_name = dai->driver->name; 70 + 71 + return 0; 72 + } 73 + 74 + static int aiu_cpu_of_xlate_dai_name(struct snd_soc_component *component, 75 + struct of_phandle_args *args, 76 + const char **dai_name) 77 + { 78 + return aiu_of_xlate_dai_name(component, args, dai_name, AIU_CPU); 79 + } 80 + 81 + static int aiu_cpu_component_probe(struct snd_soc_component *component) 82 + { 83 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 84 + 85 + /* Required for the SPDIF Source control operation */ 86 + return clk_prepare_enable(aiu->i2s.clks[PCLK].clk); 87 + } 88 + 89 + static void aiu_cpu_component_remove(struct snd_soc_component *component) 90 + { 91 + struct aiu *aiu = snd_soc_component_get_drvdata(component); 92 + 93 + clk_disable_unprepare(aiu->i2s.clks[PCLK].clk); 94 + } 95 + 96 + static const struct snd_soc_component_driver aiu_cpu_component = { 97 + .name = "AIU CPU", 98 + .dapm_widgets = aiu_cpu_dapm_widgets, 99 + .num_dapm_widgets = ARRAY_SIZE(aiu_cpu_dapm_widgets), 100 + .dapm_routes = aiu_cpu_dapm_routes, 101 + .num_dapm_routes = ARRAY_SIZE(aiu_cpu_dapm_routes), 102 + .of_xlate_dai_name = aiu_cpu_of_xlate_dai_name, 103 + .pointer = aiu_fifo_pointer, 104 + .probe = aiu_cpu_component_probe, 105 + .remove = aiu_cpu_component_remove, 106 + }; 107 + 108 + static struct snd_soc_dai_driver aiu_cpu_dai_drv[] = { 109 + [CPU_I2S_FIFO] = { 110 + .name = "I2S FIFO", 111 + .playback = { 112 + .stream_name = "I2S FIFO Playback", 113 + .channels_min = 2, 114 + .channels_max = 8, 115 + .rates = SNDRV_PCM_RATE_CONTINUOUS, 116 + .rate_min = 5512, 117 + .rate_max = 192000, 118 + .formats = AIU_FORMATS, 119 + }, 120 + .ops = &aiu_fifo_i2s_dai_ops, 121 + .pcm_new = aiu_fifo_pcm_new, 122 + .probe = aiu_fifo_i2s_dai_probe, 123 + .remove = aiu_fifo_dai_remove, 124 + }, 125 + [CPU_SPDIF_FIFO] = { 126 + .name = "SPDIF FIFO", 127 + .playback = { 128 + .stream_name = "SPDIF FIFO Playback", 129 + .channels_min = 2, 130 + .channels_max = 2, 131 + .rates = SNDRV_PCM_RATE_CONTINUOUS, 132 + .rate_min = 5512, 133 + .rate_max = 192000, 134 + .formats = AIU_FORMATS, 135 + }, 136 + .ops = &aiu_fifo_spdif_dai_ops, 137 + .pcm_new = aiu_fifo_pcm_new, 138 + .probe = aiu_fifo_spdif_dai_probe, 139 + .remove = aiu_fifo_dai_remove, 140 + }, 141 + [CPU_I2S_ENCODER] = { 142 + .name = "I2S Encoder", 143 + .playback = { 144 + .stream_name = "I2S Encoder Playback", 145 + .channels_min = 2, 146 + .channels_max = 8, 147 + .rates = SNDRV_PCM_RATE_8000_192000, 148 + .formats = AIU_FORMATS, 149 + }, 150 + .ops = &aiu_encoder_i2s_dai_ops, 151 + }, 152 + [CPU_SPDIF_ENCODER] = { 153 + .name = "SPDIF Encoder", 154 + .playback = { 155 + .stream_name = "SPDIF Encoder Playback", 156 + .channels_min = 2, 157 + .channels_max = 2, 158 + .rates = (SNDRV_PCM_RATE_32000 | 159 + SNDRV_PCM_RATE_44100 | 160 + SNDRV_PCM_RATE_48000 | 161 + SNDRV_PCM_RATE_88200 | 162 + SNDRV_PCM_RATE_96000 | 163 + SNDRV_PCM_RATE_176400 | 164 + SNDRV_PCM_RATE_192000), 165 + .formats = AIU_FORMATS, 166 + }, 167 + .ops = &aiu_encoder_spdif_dai_ops, 168 + } 169 + }; 170 + 171 + static const struct regmap_config aiu_regmap_cfg = { 172 + .reg_bits = 32, 173 + .val_bits = 32, 174 + .reg_stride = 4, 175 + .max_register = 0x2ac, 176 + }; 177 + 178 + static int aiu_clk_bulk_get(struct device *dev, 179 + const char * const *ids, 180 + unsigned int num, 181 + struct aiu_interface *interface) 182 + { 183 + struct clk_bulk_data *clks; 184 + int i, ret; 185 + 186 + clks = devm_kcalloc(dev, num, sizeof(*clks), GFP_KERNEL); 187 + if (!clks) 188 + return -ENOMEM; 189 + 190 + for (i = 0; i < num; i++) 191 + clks[i].id = ids[i]; 192 + 193 + ret = devm_clk_bulk_get(dev, num, clks); 194 + if (ret < 0) 195 + return ret; 196 + 197 + interface->clks = clks; 198 + interface->clk_num = num; 199 + return 0; 200 + } 201 + 202 + static const char * const aiu_i2s_ids[] = { 203 + [PCLK] = "i2s_pclk", 204 + [AOCLK] = "i2s_aoclk", 205 + [MCLK] = "i2s_mclk", 206 + [MIXER] = "i2s_mixer", 207 + }; 208 + 209 + static const char * const aiu_spdif_ids[] = { 210 + [PCLK] = "spdif_pclk", 211 + [AOCLK] = "spdif_aoclk", 212 + [MCLK] = "spdif_mclk_sel" 213 + }; 214 + 215 + static int aiu_clk_get(struct device *dev) 216 + { 217 + struct aiu *aiu = dev_get_drvdata(dev); 218 + int ret; 219 + 220 + aiu->pclk = devm_clk_get(dev, "pclk"); 221 + if (IS_ERR(aiu->pclk)) { 222 + if (PTR_ERR(aiu->pclk) != -EPROBE_DEFER) 223 + dev_err(dev, "Can't get the aiu pclk\n"); 224 + return PTR_ERR(aiu->pclk); 225 + } 226 + 227 + aiu->spdif_mclk = devm_clk_get(dev, "spdif_mclk"); 228 + if (IS_ERR(aiu->spdif_mclk)) { 229 + if (PTR_ERR(aiu->spdif_mclk) != -EPROBE_DEFER) 230 + dev_err(dev, "Can't get the aiu spdif master clock\n"); 231 + return PTR_ERR(aiu->spdif_mclk); 232 + } 233 + 234 + ret = aiu_clk_bulk_get(dev, aiu_i2s_ids, ARRAY_SIZE(aiu_i2s_ids), 235 + &aiu->i2s); 236 + if (ret) { 237 + if (ret != -EPROBE_DEFER) 238 + dev_err(dev, "Can't get the i2s clocks\n"); 239 + return ret; 240 + } 241 + 242 + ret = aiu_clk_bulk_get(dev, aiu_spdif_ids, ARRAY_SIZE(aiu_spdif_ids), 243 + &aiu->spdif); 244 + if (ret) { 245 + if (ret != -EPROBE_DEFER) 246 + dev_err(dev, "Can't get the spdif clocks\n"); 247 + return ret; 248 + } 249 + 250 + ret = clk_prepare_enable(aiu->pclk); 251 + if (ret) { 252 + dev_err(dev, "peripheral clock enable failed\n"); 253 + return ret; 254 + } 255 + 256 + ret = devm_add_action_or_reset(dev, 257 + (void(*)(void *))clk_disable_unprepare, 258 + aiu->pclk); 259 + if (ret) 260 + dev_err(dev, "failed to add reset action on pclk"); 261 + 262 + return ret; 263 + } 264 + 265 + static int aiu_probe(struct platform_device *pdev) 266 + { 267 + struct device *dev = &pdev->dev; 268 + void __iomem *regs; 269 + struct regmap *map; 270 + struct aiu *aiu; 271 + int ret; 272 + 273 + aiu = devm_kzalloc(dev, sizeof(*aiu), GFP_KERNEL); 274 + if (!aiu) 275 + return -ENOMEM; 276 + 277 + aiu->platform = device_get_match_data(dev); 278 + if (!aiu->platform) 279 + return -ENODEV; 280 + 281 + platform_set_drvdata(pdev, aiu); 282 + 283 + ret = device_reset(dev); 284 + if (ret) { 285 + if (ret != -EPROBE_DEFER) 286 + dev_err(dev, "Failed to reset device\n"); 287 + return ret; 288 + } 289 + 290 + regs = devm_platform_ioremap_resource(pdev, 0); 291 + if (IS_ERR(regs)) 292 + return PTR_ERR(regs); 293 + 294 + map = devm_regmap_init_mmio(dev, regs, &aiu_regmap_cfg); 295 + if (IS_ERR(map)) { 296 + dev_err(dev, "failed to init regmap: %ld\n", 297 + PTR_ERR(map)); 298 + return PTR_ERR(map); 299 + } 300 + 301 + aiu->i2s.irq = platform_get_irq_byname(pdev, "i2s"); 302 + if (aiu->i2s.irq < 0) 303 + return aiu->i2s.irq; 304 + 305 + aiu->spdif.irq = platform_get_irq_byname(pdev, "spdif"); 306 + if (aiu->spdif.irq < 0) 307 + return aiu->spdif.irq; 308 + 309 + ret = aiu_clk_get(dev); 310 + if (ret) 311 + return ret; 312 + 313 + /* Register the cpu component of the aiu */ 314 + ret = snd_soc_register_component(dev, &aiu_cpu_component, 315 + aiu_cpu_dai_drv, 316 + ARRAY_SIZE(aiu_cpu_dai_drv)); 317 + if (ret) { 318 + dev_err(dev, "Failed to register cpu component\n"); 319 + return ret; 320 + } 321 + 322 + /* Register the hdmi codec control component */ 323 + ret = aiu_hdmi_ctrl_register_component(dev); 324 + if (ret) { 325 + dev_err(dev, "Failed to register hdmi control component\n"); 326 + goto err; 327 + } 328 + 329 + /* Register the internal dac control component on gxl */ 330 + if (aiu->platform->has_acodec) { 331 + ret = aiu_acodec_ctrl_register_component(dev); 332 + if (ret) { 333 + dev_err(dev, 334 + "Failed to register acodec control component\n"); 335 + goto err; 336 + } 337 + } 338 + 339 + return 0; 340 + err: 341 + snd_soc_unregister_component(dev); 342 + return ret; 343 + } 344 + 345 + static int aiu_remove(struct platform_device *pdev) 346 + { 347 + snd_soc_unregister_component(&pdev->dev); 348 + 349 + return 0; 350 + } 351 + 352 + static const struct aiu_platform_data aiu_gxbb_pdata = { 353 + .has_acodec = false, 354 + .has_clk_ctrl_more_i2s_div = true, 355 + }; 356 + 357 + static const struct aiu_platform_data aiu_gxl_pdata = { 358 + .has_acodec = true, 359 + .has_clk_ctrl_more_i2s_div = true, 360 + }; 361 + 362 + static const struct aiu_platform_data aiu_meson8_pdata = { 363 + .has_acodec = false, 364 + .has_clk_ctrl_more_i2s_div = false, 365 + }; 366 + 367 + static const struct of_device_id aiu_of_match[] = { 368 + { .compatible = "amlogic,aiu-gxbb", .data = &aiu_gxbb_pdata }, 369 + { .compatible = "amlogic,aiu-gxl", .data = &aiu_gxl_pdata }, 370 + { .compatible = "amlogic,aiu-meson8", .data = &aiu_meson8_pdata }, 371 + { .compatible = "amlogic,aiu-meson8b", .data = &aiu_meson8_pdata }, 372 + {} 373 + }; 374 + MODULE_DEVICE_TABLE(of, aiu_of_match); 375 + 376 + static struct platform_driver aiu_pdrv = { 377 + .probe = aiu_probe, 378 + .remove = aiu_remove, 379 + .driver = { 380 + .name = "meson-aiu", 381 + .of_match_table = aiu_of_match, 382 + }, 383 + }; 384 + module_platform_driver(aiu_pdrv); 385 + 386 + MODULE_DESCRIPTION("Meson AIU Driver"); 387 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 388 + MODULE_LICENSE("GPL v2");
+89
sound/soc/meson/aiu.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef _MESON_AIU_H 8 + #define _MESON_AIU_H 9 + 10 + struct clk; 11 + struct clk_bulk_data; 12 + struct device; 13 + struct of_phandle_args; 14 + struct snd_soc_dai; 15 + struct snd_soc_dai_ops; 16 + 17 + enum aiu_clk_ids { 18 + PCLK = 0, 19 + AOCLK, 20 + MCLK, 21 + MIXER 22 + }; 23 + 24 + struct aiu_interface { 25 + struct clk_bulk_data *clks; 26 + unsigned int clk_num; 27 + int irq; 28 + }; 29 + 30 + struct aiu_platform_data { 31 + bool has_acodec; 32 + bool has_clk_ctrl_more_i2s_div; 33 + }; 34 + 35 + struct aiu { 36 + struct clk *pclk; 37 + struct clk *spdif_mclk; 38 + struct aiu_interface i2s; 39 + struct aiu_interface spdif; 40 + const struct aiu_platform_data *platform; 41 + }; 42 + 43 + #define AIU_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 44 + SNDRV_PCM_FMTBIT_S20_LE | \ 45 + SNDRV_PCM_FMTBIT_S24_LE) 46 + 47 + int aiu_of_xlate_dai_name(struct snd_soc_component *component, 48 + struct of_phandle_args *args, 49 + const char **dai_name, 50 + unsigned int component_id); 51 + 52 + int aiu_hdmi_ctrl_register_component(struct device *dev); 53 + int aiu_acodec_ctrl_register_component(struct device *dev); 54 + 55 + int aiu_fifo_i2s_dai_probe(struct snd_soc_dai *dai); 56 + int aiu_fifo_spdif_dai_probe(struct snd_soc_dai *dai); 57 + 58 + extern const struct snd_soc_dai_ops aiu_fifo_i2s_dai_ops; 59 + extern const struct snd_soc_dai_ops aiu_fifo_spdif_dai_ops; 60 + extern const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops; 61 + extern const struct snd_soc_dai_ops aiu_encoder_spdif_dai_ops; 62 + 63 + #define AIU_IEC958_BPF 0x000 64 + #define AIU_958_MISC 0x010 65 + #define AIU_IEC958_DCU_FF_CTRL 0x01c 66 + #define AIU_958_CHSTAT_L0 0x020 67 + #define AIU_958_CHSTAT_L1 0x024 68 + #define AIU_958_CTRL 0x028 69 + #define AIU_I2S_SOURCE_DESC 0x034 70 + #define AIU_I2S_DAC_CFG 0x040 71 + #define AIU_I2S_SYNC 0x044 72 + #define AIU_I2S_MISC 0x048 73 + #define AIU_RST_SOFT 0x054 74 + #define AIU_CLK_CTRL 0x058 75 + #define AIU_CLK_CTRL_MORE 0x064 76 + #define AIU_CODEC_DAC_LRCLK_CTRL 0x0a0 77 + #define AIU_HDMI_CLK_DATA_CTRL 0x0a8 78 + #define AIU_ACODEC_CTRL 0x0b0 79 + #define AIU_958_CHSTAT_R0 0x0c0 80 + #define AIU_958_CHSTAT_R1 0x0c4 81 + #define AIU_MEM_I2S_START 0x180 82 + #define AIU_MEM_I2S_MASKS 0x18c 83 + #define AIU_MEM_I2S_CONTROL 0x190 84 + #define AIU_MEM_IEC958_START 0x194 85 + #define AIU_MEM_IEC958_CONTROL 0x1a4 86 + #define AIU_MEM_I2S_BUF_CNTL 0x1d8 87 + #define AIU_MEM_IEC958_BUF_CNTL 0x1fc 88 + 89 + #endif /* _MESON_AIU_H */
+33 -381
sound/soc/meson/axg-card.c
··· 9 9 #include <sound/soc-dai.h> 10 10 11 11 #include "axg-tdm.h" 12 - 13 - struct axg_card { 14 - struct snd_soc_card card; 15 - void **link_data; 16 - }; 12 + #include "meson-card.h" 17 13 18 14 struct axg_dai_link_tdm_mask { 19 15 u32 tx; ··· 37 41 .channels_max = 8, 38 42 }; 39 43 40 - #define PREFIX "amlogic," 41 - 42 - static int axg_card_reallocate_links(struct axg_card *priv, 43 - unsigned int num_links) 44 - { 45 - struct snd_soc_dai_link *links; 46 - void **ldata; 47 - 48 - links = krealloc(priv->card.dai_link, 49 - num_links * sizeof(*priv->card.dai_link), 50 - GFP_KERNEL | __GFP_ZERO); 51 - ldata = krealloc(priv->link_data, 52 - num_links * sizeof(*priv->link_data), 53 - GFP_KERNEL | __GFP_ZERO); 54 - 55 - if (!links || !ldata) { 56 - dev_err(priv->card.dev, "failed to allocate links\n"); 57 - return -ENOMEM; 58 - } 59 - 60 - priv->card.dai_link = links; 61 - priv->link_data = ldata; 62 - priv->card.num_links = num_links; 63 - return 0; 64 - } 65 - 66 - static int axg_card_parse_dai(struct snd_soc_card *card, 67 - struct device_node *node, 68 - struct device_node **dai_of_node, 69 - const char **dai_name) 70 - { 71 - struct of_phandle_args args; 72 - int ret; 73 - 74 - if (!dai_name || !dai_of_node || !node) 75 - return -EINVAL; 76 - 77 - ret = of_parse_phandle_with_args(node, "sound-dai", 78 - "#sound-dai-cells", 0, &args); 79 - if (ret) { 80 - if (ret != -EPROBE_DEFER) 81 - dev_err(card->dev, "can't parse dai %d\n", ret); 82 - return ret; 83 - } 84 - *dai_of_node = args.np; 85 - 86 - return snd_soc_get_dai_name(&args, dai_name); 87 - } 88 - 89 - static int axg_card_set_link_name(struct snd_soc_card *card, 90 - struct snd_soc_dai_link *link, 91 - struct device_node *node, 92 - const char *prefix) 93 - { 94 - char *name = devm_kasprintf(card->dev, GFP_KERNEL, "%s.%s", 95 - prefix, node->full_name); 96 - if (!name) 97 - return -ENOMEM; 98 - 99 - link->name = name; 100 - link->stream_name = name; 101 - 102 - return 0; 103 - } 104 - 105 - static void axg_card_clean_references(struct axg_card *priv) 106 - { 107 - struct snd_soc_card *card = &priv->card; 108 - struct snd_soc_dai_link *link; 109 - struct snd_soc_dai_link_component *codec; 110 - struct snd_soc_aux_dev *aux; 111 - int i, j; 112 - 113 - if (card->dai_link) { 114 - for_each_card_prelinks(card, i, link) { 115 - if (link->cpus) 116 - of_node_put(link->cpus->of_node); 117 - for_each_link_codecs(link, j, codec) 118 - of_node_put(codec->of_node); 119 - } 120 - } 121 - 122 - if (card->aux_dev) { 123 - for_each_card_pre_auxs(card, i, aux) 124 - of_node_put(aux->dlc.of_node); 125 - } 126 - 127 - kfree(card->dai_link); 128 - kfree(priv->link_data); 129 - } 130 - 131 - static int axg_card_add_aux_devices(struct snd_soc_card *card) 132 - { 133 - struct device_node *node = card->dev->of_node; 134 - struct snd_soc_aux_dev *aux; 135 - int num, i; 136 - 137 - num = of_count_phandle_with_args(node, "audio-aux-devs", NULL); 138 - if (num == -ENOENT) { 139 - /* 140 - * It is ok to have no auxiliary devices but for this card it 141 - * is a strange situtation. Let's warn the about it. 142 - */ 143 - dev_warn(card->dev, "card has no auxiliary devices\n"); 144 - return 0; 145 - } else if (num < 0) { 146 - dev_err(card->dev, "error getting auxiliary devices: %d\n", 147 - num); 148 - return num; 149 - } 150 - 151 - aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL); 152 - if (!aux) 153 - return -ENOMEM; 154 - card->aux_dev = aux; 155 - card->num_aux_devs = num; 156 - 157 - for_each_card_pre_auxs(card, i, aux) { 158 - aux->dlc.of_node = 159 - of_parse_phandle(node, "audio-aux-devs", i); 160 - if (!aux->dlc.of_node) 161 - return -EINVAL; 162 - } 163 - 164 - return 0; 165 - } 166 - 167 44 static int axg_card_tdm_be_hw_params(struct snd_pcm_substream *substream, 168 45 struct snd_pcm_hw_params *params) 169 46 { 170 47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 - struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card); 48 + struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); 172 49 struct axg_dai_link_tdm_data *be = 173 50 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; 174 - struct snd_soc_dai *codec_dai; 175 - unsigned int mclk; 176 - int ret, i; 177 51 178 - if (be->mclk_fs) { 179 - mclk = params_rate(params) * be->mclk_fs; 180 - 181 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 182 - ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 183 - SND_SOC_CLOCK_IN); 184 - if (ret && ret != -ENOTSUPP) 185 - return ret; 186 - } 187 - 188 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 189 - SND_SOC_CLOCK_OUT); 190 - if (ret && ret != -ENOTSUPP) 191 - return ret; 192 - } 193 - 194 - return 0; 52 + return meson_card_i2s_set_sysclk(substream, params, be->mclk_fs); 195 53 } 196 54 197 55 static const struct snd_soc_ops axg_card_tdm_be_ops = { ··· 54 204 55 205 static int axg_card_tdm_dai_init(struct snd_soc_pcm_runtime *rtd) 56 206 { 57 - struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card); 207 + struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); 58 208 struct axg_dai_link_tdm_data *be = 59 209 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; 60 210 struct snd_soc_dai *codec_dai; 61 211 int ret, i; 62 212 63 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 213 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 64 214 ret = snd_soc_dai_set_tdm_slot(codec_dai, 65 215 be->codec_masks[i].tx, 66 216 be->codec_masks[i].rx, ··· 72 222 } 73 223 } 74 224 75 - ret = axg_tdm_set_tdm_slots(rtd->cpu_dai, be->tx_mask, be->rx_mask, 225 + ret = axg_tdm_set_tdm_slots(asoc_rtd_to_cpu(rtd, 0), be->tx_mask, be->rx_mask, 76 226 be->slots, be->slot_width); 77 227 if (ret) { 78 - dev_err(rtd->cpu_dai->dev, "setting tdm link slots failed\n"); 228 + dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "setting tdm link slots failed\n"); 79 229 return ret; 80 230 } 81 231 ··· 84 234 85 235 static int axg_card_tdm_dai_lb_init(struct snd_soc_pcm_runtime *rtd) 86 236 { 87 - struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card); 237 + struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); 88 238 struct axg_dai_link_tdm_data *be = 89 239 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; 90 240 int ret; 91 241 92 242 /* The loopback rx_mask is the pad tx_mask */ 93 - ret = axg_tdm_set_tdm_slots(rtd->cpu_dai, NULL, be->tx_mask, 243 + ret = axg_tdm_set_tdm_slots(asoc_rtd_to_cpu(rtd, 0), NULL, be->tx_mask, 94 244 be->slots, be->slot_width); 95 245 if (ret) { 96 - dev_err(rtd->cpu_dai->dev, "setting tdm link slots failed\n"); 246 + dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "setting tdm link slots failed\n"); 97 247 return ret; 98 248 } 99 249 ··· 103 253 static int axg_card_add_tdm_loopback(struct snd_soc_card *card, 104 254 int *index) 105 255 { 106 - struct axg_card *priv = snd_soc_card_get_drvdata(card); 256 + struct meson_card *priv = snd_soc_card_get_drvdata(card); 107 257 struct snd_soc_dai_link *pad = &card->dai_link[*index]; 108 258 struct snd_soc_dai_link *lb; 109 259 struct snd_soc_dai_link_component *dlc; 110 260 int ret; 111 261 112 262 /* extend links */ 113 - ret = axg_card_reallocate_links(priv, card->num_links + 1); 263 + ret = meson_card_reallocate_links(card, card->num_links + 1); 114 264 if (ret) 115 265 return ret; 116 266 ··· 152 302 *index += 1; 153 303 154 304 return 0; 155 - } 156 - 157 - static unsigned int axg_card_parse_daifmt(struct device_node *node, 158 - struct device_node *cpu_node) 159 - { 160 - struct device_node *bitclkmaster = NULL; 161 - struct device_node *framemaster = NULL; 162 - unsigned int daifmt; 163 - 164 - daifmt = snd_soc_of_parse_daifmt(node, PREFIX, 165 - &bitclkmaster, &framemaster); 166 - daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; 167 - 168 - /* If no master is provided, default to cpu master */ 169 - if (!bitclkmaster || bitclkmaster == cpu_node) { 170 - daifmt |= (!framemaster || framemaster == cpu_node) ? 171 - SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBS_CFM; 172 - } else { 173 - daifmt |= (!framemaster || framemaster == cpu_node) ? 174 - SND_SOC_DAIFMT_CBM_CFS : SND_SOC_DAIFMT_CBM_CFM; 175 - } 176 - 177 - of_node_put(bitclkmaster); 178 - of_node_put(framemaster); 179 - 180 - return daifmt; 181 305 } 182 306 183 307 static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card, ··· 248 424 struct device_node *node, 249 425 int *index) 250 426 { 251 - struct axg_card *priv = snd_soc_card_get_drvdata(card); 427 + struct meson_card *priv = snd_soc_card_get_drvdata(card); 252 428 struct snd_soc_dai_link *link = &card->dai_link[*index]; 253 429 struct axg_dai_link_tdm_data *be; 254 430 int ret; ··· 262 438 /* Setup tdm link */ 263 439 link->ops = &axg_card_tdm_be_ops; 264 440 link->init = axg_card_tdm_dai_init; 265 - link->dai_fmt = axg_card_parse_daifmt(node, link->cpus->of_node); 441 + link->dai_fmt = meson_card_parse_daifmt(node, link->cpus->of_node); 266 442 267 443 of_property_read_u32(node, "mclk-fs", &be->mclk_fs); 268 444 ··· 286 462 return 0; 287 463 } 288 464 289 - static int axg_card_set_be_link(struct snd_soc_card *card, 290 - struct snd_soc_dai_link *link, 291 - struct device_node *node) 292 - { 293 - struct snd_soc_dai_link_component *codec; 294 - struct device_node *np; 295 - int ret, num_codecs; 296 - 297 - link->no_pcm = 1; 298 - link->dpcm_playback = 1; 299 - link->dpcm_capture = 1; 300 - 301 - num_codecs = of_get_child_count(node); 302 - if (!num_codecs) { 303 - dev_err(card->dev, "be link %s has no codec\n", 304 - node->full_name); 305 - return -EINVAL; 306 - } 307 - 308 - codec = devm_kcalloc(card->dev, num_codecs, sizeof(*codec), GFP_KERNEL); 309 - if (!codec) 310 - return -ENOMEM; 311 - 312 - link->codecs = codec; 313 - link->num_codecs = num_codecs; 314 - 315 - for_each_child_of_node(node, np) { 316 - ret = axg_card_parse_dai(card, np, &codec->of_node, 317 - &codec->dai_name); 318 - if (ret) { 319 - of_node_put(np); 320 - return ret; 321 - } 322 - 323 - codec++; 324 - } 325 - 326 - ret = axg_card_set_link_name(card, link, node, "be"); 327 - if (ret) 328 - dev_err(card->dev, "error setting %pOFn link name\n", np); 329 - 330 - return ret; 331 - } 332 - 333 - static int axg_card_set_fe_link(struct snd_soc_card *card, 334 - struct snd_soc_dai_link *link, 335 - struct device_node *node, 336 - bool is_playback) 337 - { 338 - struct snd_soc_dai_link_component *codec; 339 - 340 - codec = devm_kzalloc(card->dev, sizeof(*codec), GFP_KERNEL); 341 - if (!codec) 342 - return -ENOMEM; 343 - 344 - link->codecs = codec; 345 - link->num_codecs = 1; 346 - 347 - link->dynamic = 1; 348 - link->dpcm_merged_format = 1; 349 - link->dpcm_merged_chan = 1; 350 - link->dpcm_merged_rate = 1; 351 - link->codecs->dai_name = "snd-soc-dummy-dai"; 352 - link->codecs->name = "snd-soc-dummy"; 353 - 354 - if (is_playback) 355 - link->dpcm_playback = 1; 356 - else 357 - link->dpcm_capture = 1; 358 - 359 - return axg_card_set_link_name(card, link, node, "fe"); 360 - } 361 - 362 465 static int axg_card_cpu_is_capture_fe(struct device_node *np) 363 466 { 364 - return of_device_is_compatible(np, PREFIX "axg-toddr"); 467 + return of_device_is_compatible(np, DT_PREFIX "axg-toddr"); 365 468 } 366 469 367 470 static int axg_card_cpu_is_playback_fe(struct device_node *np) 368 471 { 369 - return of_device_is_compatible(np, PREFIX "axg-frddr"); 472 + return of_device_is_compatible(np, DT_PREFIX "axg-frddr"); 370 473 } 371 474 372 475 static int axg_card_cpu_is_tdm_iface(struct device_node *np) 373 476 { 374 - return of_device_is_compatible(np, PREFIX "axg-tdm-iface"); 477 + return of_device_is_compatible(np, DT_PREFIX "axg-tdm-iface"); 375 478 } 376 479 377 480 static int axg_card_cpu_is_codec(struct device_node *np) 378 481 { 379 - return of_device_is_compatible(np, PREFIX "g12a-tohdmitx"); 482 + return of_device_is_compatible(np, DT_PREFIX "g12a-tohdmitx") || 483 + of_device_is_compatible(np, DT_PREFIX "g12a-toacodec"); 380 484 } 381 485 382 486 static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np, ··· 321 569 dai_link->cpus = cpu; 322 570 dai_link->num_cpus = 1; 323 571 324 - ret = axg_card_parse_dai(card, np, &dai_link->cpus->of_node, 325 - &dai_link->cpus->dai_name); 572 + ret = meson_card_parse_dai(card, np, &dai_link->cpus->of_node, 573 + &dai_link->cpus->dai_name); 326 574 if (ret) 327 575 return ret; 328 576 329 577 if (axg_card_cpu_is_playback_fe(dai_link->cpus->of_node)) 330 - ret = axg_card_set_fe_link(card, dai_link, np, true); 578 + ret = meson_card_set_fe_link(card, dai_link, np, true); 331 579 else if (axg_card_cpu_is_capture_fe(dai_link->cpus->of_node)) 332 - ret = axg_card_set_fe_link(card, dai_link, np, false); 580 + ret = meson_card_set_fe_link(card, dai_link, np, false); 333 581 else 334 - ret = axg_card_set_be_link(card, dai_link, np); 582 + ret = meson_card_set_be_link(card, dai_link, np); 335 583 336 584 if (ret) 337 585 return ret; ··· 344 592 return ret; 345 593 } 346 594 347 - static int axg_card_add_links(struct snd_soc_card *card) 348 - { 349 - struct axg_card *priv = snd_soc_card_get_drvdata(card); 350 - struct device_node *node = card->dev->of_node; 351 - struct device_node *np; 352 - int num, i, ret; 353 - 354 - num = of_get_child_count(node); 355 - if (!num) { 356 - dev_err(card->dev, "card has no links\n"); 357 - return -EINVAL; 358 - } 359 - 360 - ret = axg_card_reallocate_links(priv, num); 361 - if (ret) 362 - return ret; 363 - 364 - i = 0; 365 - for_each_child_of_node(node, np) { 366 - ret = axg_card_add_link(card, np, &i); 367 - if (ret) { 368 - of_node_put(np); 369 - return ret; 370 - } 371 - 372 - i++; 373 - } 374 - 375 - return 0; 376 - } 377 - 378 - static int axg_card_parse_of_optional(struct snd_soc_card *card, 379 - const char *propname, 380 - int (*func)(struct snd_soc_card *c, 381 - const char *p)) 382 - { 383 - /* If property is not provided, don't fail ... */ 384 - if (!of_property_read_bool(card->dev->of_node, propname)) 385 - return 0; 386 - 387 - /* ... but do fail if it is provided and the parsing fails */ 388 - return func(card, propname); 389 - } 595 + static const struct meson_card_match_data axg_card_match_data = { 596 + .add_link = axg_card_add_link, 597 + }; 390 598 391 599 static const struct of_device_id axg_card_of_match[] = { 392 - { .compatible = "amlogic,axg-sound-card", }, 393 - {} 600 + { 601 + .compatible = "amlogic,axg-sound-card", 602 + .data = &axg_card_match_data, 603 + }, {} 394 604 }; 395 605 MODULE_DEVICE_TABLE(of, axg_card_of_match); 396 606 397 - static int axg_card_probe(struct platform_device *pdev) 398 - { 399 - struct device *dev = &pdev->dev; 400 - struct axg_card *priv; 401 - int ret; 402 - 403 - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 404 - if (!priv) 405 - return -ENOMEM; 406 - 407 - platform_set_drvdata(pdev, priv); 408 - snd_soc_card_set_drvdata(&priv->card, priv); 409 - 410 - priv->card.owner = THIS_MODULE; 411 - priv->card.dev = dev; 412 - 413 - ret = snd_soc_of_parse_card_name(&priv->card, "model"); 414 - if (ret < 0) 415 - return ret; 416 - 417 - ret = axg_card_parse_of_optional(&priv->card, "audio-routing", 418 - snd_soc_of_parse_audio_routing); 419 - if (ret) { 420 - dev_err(dev, "error while parsing routing\n"); 421 - return ret; 422 - } 423 - 424 - ret = axg_card_parse_of_optional(&priv->card, "audio-widgets", 425 - snd_soc_of_parse_audio_simple_widgets); 426 - if (ret) { 427 - dev_err(dev, "error while parsing widgets\n"); 428 - return ret; 429 - } 430 - 431 - ret = axg_card_add_links(&priv->card); 432 - if (ret) 433 - goto out_err; 434 - 435 - ret = axg_card_add_aux_devices(&priv->card); 436 - if (ret) 437 - goto out_err; 438 - 439 - ret = devm_snd_soc_register_card(dev, &priv->card); 440 - if (ret) 441 - goto out_err; 442 - 443 - return 0; 444 - 445 - out_err: 446 - axg_card_clean_references(priv); 447 - return ret; 448 - } 449 - 450 - static int axg_card_remove(struct platform_device *pdev) 451 - { 452 - struct axg_card *priv = platform_get_drvdata(pdev); 453 - 454 - axg_card_clean_references(priv); 455 - 456 - return 0; 457 - } 458 - 459 607 static struct platform_driver axg_card_pdrv = { 460 - .probe = axg_card_probe, 461 - .remove = axg_card_remove, 608 + .probe = meson_card_probe, 609 + .remove = meson_card_remove, 462 610 .driver = { 463 611 .name = "axg-sound-card", 464 612 .of_match_table = axg_card_of_match,
+1 -1
sound/soc/meson/axg-fifo.c
··· 47 47 { 48 48 struct snd_soc_pcm_runtime *rtd = ss->private_data; 49 49 50 - return rtd->cpu_dai; 50 + return asoc_rtd_to_cpu(rtd, 0); 51 51 } 52 52 53 53 static struct axg_fifo *axg_fifo_data(struct snd_pcm_substream *ss)
+252
sound/soc/meson/g12a-toacodec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/bitfield.h> 7 + #include <linux/clk.h> 8 + #include <linux/module.h> 9 + #include <sound/pcm_params.h> 10 + #include <linux/regmap.h> 11 + #include <linux/regulator/consumer.h> 12 + #include <linux/reset.h> 13 + #include <sound/soc.h> 14 + #include <sound/soc-dai.h> 15 + 16 + #include <dt-bindings/sound/meson-g12a-toacodec.h> 17 + #include "axg-tdm.h" 18 + #include "meson-codec-glue.h" 19 + 20 + #define G12A_TOACODEC_DRV_NAME "g12a-toacodec" 21 + 22 + #define TOACODEC_CTRL0 0x0 23 + #define CTRL0_ENABLE_SHIFT 31 24 + #define CTRL0_DAT_SEL_SHIFT 14 25 + #define CTRL0_DAT_SEL (0x3 << CTRL0_DAT_SEL_SHIFT) 26 + #define CTRL0_LANE_SEL 12 27 + #define CTRL0_LRCLK_SEL GENMASK(9, 8) 28 + #define CTRL0_BLK_CAP_INV BIT(7) 29 + #define CTRL0_BCLK_O_INV BIT(6) 30 + #define CTRL0_BCLK_SEL GENMASK(5, 4) 31 + #define CTRL0_MCLK_SEL GENMASK(2, 0) 32 + 33 + #define TOACODEC_OUT_CHMAX 2 34 + 35 + static const char * const g12a_toacodec_mux_texts[] = { 36 + "I2S A", "I2S B", "I2S C", 37 + }; 38 + 39 + static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, 40 + struct snd_ctl_elem_value *ucontrol) 41 + { 42 + struct snd_soc_component *component = 43 + snd_soc_dapm_kcontrol_component(kcontrol); 44 + struct snd_soc_dapm_context *dapm = 45 + snd_soc_dapm_kcontrol_dapm(kcontrol); 46 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 47 + unsigned int mux, changed; 48 + 49 + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); 50 + changed = snd_soc_component_test_bits(component, e->reg, 51 + CTRL0_DAT_SEL, 52 + FIELD_PREP(CTRL0_DAT_SEL, mux)); 53 + 54 + if (!changed) 55 + return 0; 56 + 57 + /* Force disconnect of the mux while updating */ 58 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 59 + 60 + snd_soc_component_update_bits(component, e->reg, 61 + CTRL0_DAT_SEL | 62 + CTRL0_LRCLK_SEL | 63 + CTRL0_BCLK_SEL, 64 + FIELD_PREP(CTRL0_DAT_SEL, mux) | 65 + FIELD_PREP(CTRL0_LRCLK_SEL, mux) | 66 + FIELD_PREP(CTRL0_BCLK_SEL, mux)); 67 + 68 + /* 69 + * FIXME: 70 + * On this soc, the glue gets the MCLK directly from the clock 71 + * controller instead of going the through the TDM interface. 72 + * 73 + * Here we assume interface A uses clock A, etc ... While it is 74 + * true for now, it could be different. Instead the glue should 75 + * find out the clock used by the interface and select the same 76 + * source. For that, we will need regmap backed clock mux which 77 + * is a work in progress 78 + */ 79 + snd_soc_component_update_bits(component, e->reg, 80 + CTRL0_MCLK_SEL, 81 + FIELD_PREP(CTRL0_MCLK_SEL, mux)); 82 + 83 + snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); 84 + 85 + return 0; 86 + } 87 + 88 + static SOC_ENUM_SINGLE_DECL(g12a_toacodec_mux_enum, TOACODEC_CTRL0, 89 + CTRL0_DAT_SEL_SHIFT, 90 + g12a_toacodec_mux_texts); 91 + 92 + static const struct snd_kcontrol_new g12a_toacodec_mux = 93 + SOC_DAPM_ENUM_EXT("Source", g12a_toacodec_mux_enum, 94 + snd_soc_dapm_get_enum_double, 95 + g12a_toacodec_mux_put_enum); 96 + 97 + static const struct snd_kcontrol_new g12a_toacodec_out_enable = 98 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", TOACODEC_CTRL0, 99 + CTRL0_ENABLE_SHIFT, 1, 0); 100 + 101 + static const struct snd_soc_dapm_widget g12a_toacodec_widgets[] = { 102 + SND_SOC_DAPM_MUX("SRC", SND_SOC_NOPM, 0, 0, 103 + &g12a_toacodec_mux), 104 + SND_SOC_DAPM_SWITCH("OUT EN", SND_SOC_NOPM, 0, 0, 105 + &g12a_toacodec_out_enable), 106 + }; 107 + 108 + static int g12a_toacodec_input_hw_params(struct snd_pcm_substream *substream, 109 + struct snd_pcm_hw_params *params, 110 + struct snd_soc_dai *dai) 111 + { 112 + struct meson_codec_glue_input *data; 113 + int ret; 114 + 115 + ret = meson_codec_glue_input_hw_params(substream, params, dai); 116 + if (ret) 117 + return ret; 118 + 119 + /* The glue will provide 1 lane out of the 4 to the output */ 120 + data = meson_codec_glue_input_get_data(dai); 121 + data->params.channels_min = min_t(unsigned int, TOACODEC_OUT_CHMAX, 122 + data->params.channels_min); 123 + data->params.channels_max = min_t(unsigned int, TOACODEC_OUT_CHMAX, 124 + data->params.channels_max); 125 + 126 + return 0; 127 + } 128 + 129 + static const struct snd_soc_dai_ops g12a_toacodec_input_ops = { 130 + .hw_params = g12a_toacodec_input_hw_params, 131 + .set_fmt = meson_codec_glue_input_set_fmt, 132 + }; 133 + 134 + static const struct snd_soc_dai_ops g12a_toacodec_output_ops = { 135 + .startup = meson_codec_glue_output_startup, 136 + }; 137 + 138 + #define TOACODEC_STREAM(xname, xsuffix, xchmax) \ 139 + { \ 140 + .stream_name = xname " " xsuffix, \ 141 + .channels_min = 1, \ 142 + .channels_max = (xchmax), \ 143 + .rate_min = 5512, \ 144 + .rate_max = 192000, \ 145 + .formats = AXG_TDM_FORMATS, \ 146 + } 147 + 148 + #define TOACODEC_INPUT(xname, xid) { \ 149 + .name = xname, \ 150 + .id = (xid), \ 151 + .playback = TOACODEC_STREAM(xname, "Playback", 8), \ 152 + .ops = &g12a_toacodec_input_ops, \ 153 + .probe = meson_codec_glue_input_dai_probe, \ 154 + .remove = meson_codec_glue_input_dai_remove, \ 155 + } 156 + 157 + #define TOACODEC_OUTPUT(xname, xid) { \ 158 + .name = xname, \ 159 + .id = (xid), \ 160 + .capture = TOACODEC_STREAM(xname, "Capture", TOACODEC_OUT_CHMAX), \ 161 + .ops = &g12a_toacodec_output_ops, \ 162 + } 163 + 164 + static struct snd_soc_dai_driver g12a_toacodec_dai_drv[] = { 165 + TOACODEC_INPUT("IN A", TOACODEC_IN_A), 166 + TOACODEC_INPUT("IN B", TOACODEC_IN_B), 167 + TOACODEC_INPUT("IN C", TOACODEC_IN_C), 168 + TOACODEC_OUTPUT("OUT", TOACODEC_OUT), 169 + }; 170 + 171 + static int g12a_toacodec_component_probe(struct snd_soc_component *c) 172 + { 173 + /* Initialize the static clock parameters */ 174 + return snd_soc_component_write(c, TOACODEC_CTRL0, 175 + CTRL0_BLK_CAP_INV); 176 + } 177 + 178 + static const struct snd_soc_dapm_route g12a_toacodec_routes[] = { 179 + { "SRC", "I2S A", "IN A Playback" }, 180 + { "SRC", "I2S B", "IN B Playback" }, 181 + { "SRC", "I2S C", "IN C Playback" }, 182 + { "OUT EN", "Switch", "SRC" }, 183 + { "OUT Capture", NULL, "OUT EN" }, 184 + }; 185 + 186 + static const struct snd_kcontrol_new g12a_toacodec_controls[] = { 187 + SOC_SINGLE("Lane Select", TOACODEC_CTRL0, CTRL0_LANE_SEL, 3, 0), 188 + }; 189 + 190 + static const struct snd_soc_component_driver g12a_toacodec_component_drv = { 191 + .probe = g12a_toacodec_component_probe, 192 + .controls = g12a_toacodec_controls, 193 + .num_controls = ARRAY_SIZE(g12a_toacodec_controls), 194 + .dapm_widgets = g12a_toacodec_widgets, 195 + .num_dapm_widgets = ARRAY_SIZE(g12a_toacodec_widgets), 196 + .dapm_routes = g12a_toacodec_routes, 197 + .num_dapm_routes = ARRAY_SIZE(g12a_toacodec_routes), 198 + .endianness = 1, 199 + .non_legacy_dai_naming = 1, 200 + }; 201 + 202 + static const struct regmap_config g12a_toacodec_regmap_cfg = { 203 + .reg_bits = 32, 204 + .val_bits = 32, 205 + .reg_stride = 4, 206 + }; 207 + 208 + static const struct of_device_id g12a_toacodec_of_match[] = { 209 + { .compatible = "amlogic,g12a-toacodec", }, 210 + {} 211 + }; 212 + MODULE_DEVICE_TABLE(of, g12a_toacodec_of_match); 213 + 214 + static int g12a_toacodec_probe(struct platform_device *pdev) 215 + { 216 + struct device *dev = &pdev->dev; 217 + void __iomem *regs; 218 + struct regmap *map; 219 + int ret; 220 + 221 + ret = device_reset(dev); 222 + if (ret) 223 + return ret; 224 + 225 + regs = devm_platform_ioremap_resource(pdev, 0); 226 + if (IS_ERR(regs)) 227 + return PTR_ERR(regs); 228 + 229 + map = devm_regmap_init_mmio(dev, regs, &g12a_toacodec_regmap_cfg); 230 + if (IS_ERR(map)) { 231 + dev_err(dev, "failed to init regmap: %ld\n", 232 + PTR_ERR(map)); 233 + return PTR_ERR(map); 234 + } 235 + 236 + return devm_snd_soc_register_component(dev, 237 + &g12a_toacodec_component_drv, g12a_toacodec_dai_drv, 238 + ARRAY_SIZE(g12a_toacodec_dai_drv)); 239 + } 240 + 241 + static struct platform_driver g12a_toacodec_pdrv = { 242 + .driver = { 243 + .name = G12A_TOACODEC_DRV_NAME, 244 + .of_match_table = g12a_toacodec_of_match, 245 + }, 246 + .probe = g12a_toacodec_probe, 247 + }; 248 + module_platform_driver(g12a_toacodec_pdrv); 249 + 250 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 251 + MODULE_DESCRIPTION("Amlogic G12a To Internal DAC Codec Driver"); 252 + MODULE_LICENSE("GPL v2");
+43 -176
sound/soc/meson/g12a-tohdmitx.c
··· 13 13 #include <sound/soc-dai.h> 14 14 15 15 #include <dt-bindings/sound/meson-g12a-tohdmitx.h> 16 + #include "meson-codec-glue.h" 16 17 17 18 #define G12A_TOHDMITX_DRV_NAME "g12a-tohdmitx" 18 19 19 20 #define TOHDMITX_CTRL0 0x0 20 21 #define CTRL0_ENABLE_SHIFT 31 21 - #define CTRL0_I2S_DAT_SEL GENMASK(13, 12) 22 + #define CTRL0_I2S_DAT_SEL_SHIFT 12 23 + #define CTRL0_I2S_DAT_SEL (0x3 << CTRL0_I2S_DAT_SEL_SHIFT) 22 24 #define CTRL0_I2S_LRCLK_SEL GENMASK(9, 8) 23 25 #define CTRL0_I2S_BLK_CAP_INV BIT(7) 24 26 #define CTRL0_I2S_BCLK_O_INV BIT(6) 25 27 #define CTRL0_I2S_BCLK_SEL GENMASK(5, 4) 26 28 #define CTRL0_SPDIF_CLK_CAP_INV BIT(3) 27 29 #define CTRL0_SPDIF_CLK_O_INV BIT(2) 28 - #define CTRL0_SPDIF_SEL BIT(1) 30 + #define CTRL0_SPDIF_SEL_SHIFT 1 31 + #define CTRL0_SPDIF_SEL (0x1 << CTRL0_SPDIF_SEL_SHIFT) 29 32 #define CTRL0_SPDIF_CLK_SEL BIT(0) 30 - 31 - struct g12a_tohdmitx_input { 32 - struct snd_soc_pcm_stream params; 33 - unsigned int fmt; 34 - }; 35 - 36 - static struct snd_soc_dapm_widget * 37 - g12a_tohdmitx_get_input(struct snd_soc_dapm_widget *w) 38 - { 39 - struct snd_soc_dapm_path *p = NULL; 40 - struct snd_soc_dapm_widget *in; 41 - 42 - snd_soc_dapm_widget_for_each_source_path(w, p) { 43 - if (!p->connect) 44 - continue; 45 - 46 - /* Check that we still are in the same component */ 47 - if (snd_soc_dapm_to_component(w->dapm) != 48 - snd_soc_dapm_to_component(p->source->dapm)) 49 - continue; 50 - 51 - if (p->source->id == snd_soc_dapm_dai_in) 52 - return p->source; 53 - 54 - in = g12a_tohdmitx_get_input(p->source); 55 - if (in) 56 - return in; 57 - } 58 - 59 - return NULL; 60 - } 61 - 62 - static struct g12a_tohdmitx_input * 63 - g12a_tohdmitx_get_input_data(struct snd_soc_dapm_widget *w) 64 - { 65 - struct snd_soc_dapm_widget *in = 66 - g12a_tohdmitx_get_input(w); 67 - struct snd_soc_dai *dai; 68 - 69 - if (WARN_ON(!in)) 70 - return NULL; 71 - 72 - dai = in->priv; 73 - 74 - return dai->playback_dma_data; 75 - } 76 33 77 34 static const char * const g12a_tohdmitx_i2s_mux_texts[] = { 78 35 "I2S A", "I2S B", "I2S C", 79 36 }; 80 37 81 - static SOC_ENUM_SINGLE_EXT_DECL(g12a_tohdmitx_i2s_mux_enum, 82 - g12a_tohdmitx_i2s_mux_texts); 83 - 84 - static int g12a_tohdmitx_get_input_val(struct snd_soc_component *component, 85 - unsigned int mask) 86 - { 87 - unsigned int val; 88 - 89 - snd_soc_component_read(component, TOHDMITX_CTRL0, &val); 90 - return (val & mask) >> __ffs(mask); 91 - } 92 - 93 - static int g12a_tohdmitx_i2s_mux_get_enum(struct snd_kcontrol *kcontrol, 94 - struct snd_ctl_elem_value *ucontrol) 95 - { 96 - struct snd_soc_component *component = 97 - snd_soc_dapm_kcontrol_component(kcontrol); 98 - 99 - ucontrol->value.enumerated.item[0] = 100 - g12a_tohdmitx_get_input_val(component, CTRL0_I2S_DAT_SEL); 101 - 102 - return 0; 103 - } 104 - 105 38 static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol, 106 - struct snd_ctl_elem_value *ucontrol) 39 + struct snd_ctl_elem_value *ucontrol) 107 40 { 108 41 struct snd_soc_component *component = 109 42 snd_soc_dapm_kcontrol_component(kcontrol); 110 43 struct snd_soc_dapm_context *dapm = 111 44 snd_soc_dapm_kcontrol_dapm(kcontrol); 112 45 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 113 - unsigned int mux = ucontrol->value.enumerated.item[0]; 114 - unsigned int val = g12a_tohdmitx_get_input_val(component, 115 - CTRL0_I2S_DAT_SEL); 46 + unsigned int mux, changed; 47 + 48 + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); 49 + changed = snd_soc_component_test_bits(component, e->reg, 50 + CTRL0_I2S_DAT_SEL, 51 + FIELD_PREP(CTRL0_I2S_DAT_SEL, 52 + mux)); 53 + 54 + if (!changed) 55 + return 0; 116 56 117 57 /* Force disconnect of the mux while updating */ 118 - if (val != mux) 119 - snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 58 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 120 59 121 - snd_soc_component_update_bits(component, TOHDMITX_CTRL0, 60 + snd_soc_component_update_bits(component, e->reg, 122 61 CTRL0_I2S_DAT_SEL | 123 62 CTRL0_I2S_LRCLK_SEL | 124 63 CTRL0_I2S_BCLK_SEL, ··· 70 131 return 0; 71 132 } 72 133 134 + static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_i2s_mux_enum, TOHDMITX_CTRL0, 135 + CTRL0_I2S_DAT_SEL_SHIFT, 136 + g12a_tohdmitx_i2s_mux_texts); 137 + 73 138 static const struct snd_kcontrol_new g12a_tohdmitx_i2s_mux = 74 139 SOC_DAPM_ENUM_EXT("I2S Source", g12a_tohdmitx_i2s_mux_enum, 75 - g12a_tohdmitx_i2s_mux_get_enum, 140 + snd_soc_dapm_get_enum_double, 76 141 g12a_tohdmitx_i2s_mux_put_enum); 77 142 78 143 static const char * const g12a_tohdmitx_spdif_mux_texts[] = { 79 144 "SPDIF A", "SPDIF B", 80 145 }; 81 - 82 - static SOC_ENUM_SINGLE_EXT_DECL(g12a_tohdmitx_spdif_mux_enum, 83 - g12a_tohdmitx_spdif_mux_texts); 84 - 85 - static int g12a_tohdmitx_spdif_mux_get_enum(struct snd_kcontrol *kcontrol, 86 - struct snd_ctl_elem_value *ucontrol) 87 - { 88 - struct snd_soc_component *component = 89 - snd_soc_dapm_kcontrol_component(kcontrol); 90 - 91 - ucontrol->value.enumerated.item[0] = 92 - g12a_tohdmitx_get_input_val(component, CTRL0_SPDIF_SEL); 93 - 94 - return 0; 95 - } 96 146 97 147 static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, 98 148 struct snd_ctl_elem_value *ucontrol) ··· 91 163 struct snd_soc_dapm_context *dapm = 92 164 snd_soc_dapm_kcontrol_dapm(kcontrol); 93 165 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 94 - unsigned int mux = ucontrol->value.enumerated.item[0]; 95 - unsigned int val = g12a_tohdmitx_get_input_val(component, 96 - CTRL0_SPDIF_SEL); 166 + unsigned int mux, changed; 167 + 168 + mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); 169 + changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0, 170 + CTRL0_SPDIF_SEL, 171 + FIELD_PREP(CTRL0_SPDIF_SEL, mux)); 172 + 173 + if (!changed) 174 + return 0; 97 175 98 176 /* Force disconnect of the mux while updating */ 99 - if (val != mux) 100 - snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 177 + snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL); 101 178 102 179 snd_soc_component_update_bits(component, TOHDMITX_CTRL0, 103 180 CTRL0_SPDIF_SEL | ··· 115 182 return 0; 116 183 } 117 184 185 + static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0, 186 + CTRL0_SPDIF_SEL_SHIFT, 187 + g12a_tohdmitx_spdif_mux_texts); 188 + 118 189 static const struct snd_kcontrol_new g12a_tohdmitx_spdif_mux = 119 190 SOC_DAPM_ENUM_EXT("SPDIF Source", g12a_tohdmitx_spdif_mux_enum, 120 - g12a_tohdmitx_spdif_mux_get_enum, 191 + snd_soc_dapm_get_enum_double, 121 192 g12a_tohdmitx_spdif_mux_put_enum); 122 193 123 194 static const struct snd_kcontrol_new g12a_tohdmitx_out_enable = ··· 139 202 &g12a_tohdmitx_out_enable), 140 203 }; 141 204 142 - static int g12a_tohdmitx_input_probe(struct snd_soc_dai *dai) 143 - { 144 - struct g12a_tohdmitx_input *data; 145 - 146 - data = kzalloc(sizeof(*data), GFP_KERNEL); 147 - if (!data) 148 - return -ENOMEM; 149 - 150 - dai->playback_dma_data = data; 151 - return 0; 152 - } 153 - 154 - static int g12a_tohdmitx_input_remove(struct snd_soc_dai *dai) 155 - { 156 - kfree(dai->playback_dma_data); 157 - return 0; 158 - } 159 - 160 - static int g12a_tohdmitx_input_hw_params(struct snd_pcm_substream *substream, 161 - struct snd_pcm_hw_params *params, 162 - struct snd_soc_dai *dai) 163 - { 164 - struct g12a_tohdmitx_input *data = dai->playback_dma_data; 165 - 166 - data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params)); 167 - data->params.rate_min = params_rate(params); 168 - data->params.rate_max = params_rate(params); 169 - data->params.formats = 1 << params_format(params); 170 - data->params.channels_min = params_channels(params); 171 - data->params.channels_max = params_channels(params); 172 - data->params.sig_bits = dai->driver->playback.sig_bits; 173 - 174 - return 0; 175 - } 176 - 177 - 178 - static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai, 179 - unsigned int fmt) 180 - { 181 - struct g12a_tohdmitx_input *data = dai->playback_dma_data; 182 - 183 - /* Save the source stream format for the downstream link */ 184 - data->fmt = fmt; 185 - return 0; 186 - } 187 - 188 - static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream, 189 - struct snd_soc_dai *dai) 190 - { 191 - struct snd_soc_pcm_runtime *rtd = substream->private_data; 192 - struct g12a_tohdmitx_input *in_data = 193 - g12a_tohdmitx_get_input_data(dai->capture_widget); 194 - 195 - if (!in_data) 196 - return -ENODEV; 197 - 198 - if (WARN_ON(!rtd->dai_link->params)) { 199 - dev_warn(dai->dev, "codec2codec link expected\n"); 200 - return -EINVAL; 201 - } 202 - 203 - /* Replace link params with the input params */ 204 - rtd->dai_link->params = &in_data->params; 205 - 206 - if (!in_data->fmt) 207 - return 0; 208 - 209 - return snd_soc_runtime_set_dai_fmt(rtd, in_data->fmt); 210 - } 211 - 212 205 static const struct snd_soc_dai_ops g12a_tohdmitx_input_ops = { 213 - .hw_params = g12a_tohdmitx_input_hw_params, 214 - .set_fmt = g12a_tohdmitx_input_set_fmt, 206 + .hw_params = meson_codec_glue_input_hw_params, 207 + .set_fmt = meson_codec_glue_input_set_fmt, 215 208 }; 216 209 217 210 static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = { 218 - .startup = g12a_tohdmitx_output_startup, 211 + .startup = meson_codec_glue_output_startup, 219 212 }; 220 213 221 214 #define TOHDMITX_SPDIF_FORMATS \ ··· 172 305 .id = (xid), \ 173 306 .playback = TOHDMITX_STREAM(xname, "Playback", xfmt, xchmax), \ 174 307 .ops = &g12a_tohdmitx_input_ops, \ 175 - .probe = g12a_tohdmitx_input_probe, \ 176 - .remove = g12a_tohdmitx_input_remove, \ 308 + .probe = meson_codec_glue_input_dai_probe, \ 309 + .remove = meson_codec_glue_input_dai_remove, \ 177 310 } 178 311 179 312 #define TOHDMITX_OUT(xname, xid, xfmt, xchmax) { \
+141
sound/soc/meson/gx-card.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/module.h> 7 + #include <linux/of_platform.h> 8 + #include <sound/soc.h> 9 + #include <sound/soc-dai.h> 10 + 11 + #include "meson-card.h" 12 + 13 + struct gx_dai_link_i2s_data { 14 + unsigned int mclk_fs; 15 + }; 16 + 17 + /* 18 + * Base params for the codec to codec links 19 + * Those will be over-written by the CPU side of the link 20 + */ 21 + static const struct snd_soc_pcm_stream codec_params = { 22 + .formats = SNDRV_PCM_FMTBIT_S24_LE, 23 + .rate_min = 5525, 24 + .rate_max = 192000, 25 + .channels_min = 1, 26 + .channels_max = 8, 27 + }; 28 + 29 + static int gx_card_i2s_be_hw_params(struct snd_pcm_substream *substream, 30 + struct snd_pcm_hw_params *params) 31 + { 32 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 33 + struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card); 34 + struct gx_dai_link_i2s_data *be = 35 + (struct gx_dai_link_i2s_data *)priv->link_data[rtd->num]; 36 + 37 + return meson_card_i2s_set_sysclk(substream, params, be->mclk_fs); 38 + } 39 + 40 + static const struct snd_soc_ops gx_card_i2s_be_ops = { 41 + .hw_params = gx_card_i2s_be_hw_params, 42 + }; 43 + 44 + static int gx_card_parse_i2s(struct snd_soc_card *card, 45 + struct device_node *node, 46 + int *index) 47 + { 48 + struct meson_card *priv = snd_soc_card_get_drvdata(card); 49 + struct snd_soc_dai_link *link = &card->dai_link[*index]; 50 + struct gx_dai_link_i2s_data *be; 51 + 52 + /* Allocate i2s link parameters */ 53 + be = devm_kzalloc(card->dev, sizeof(*be), GFP_KERNEL); 54 + if (!be) 55 + return -ENOMEM; 56 + priv->link_data[*index] = be; 57 + 58 + /* Setup i2s link */ 59 + link->ops = &gx_card_i2s_be_ops; 60 + link->dai_fmt = meson_card_parse_daifmt(node, link->cpus->of_node); 61 + 62 + of_property_read_u32(node, "mclk-fs", &be->mclk_fs); 63 + 64 + return 0; 65 + } 66 + 67 + static int gx_card_cpu_identify(struct snd_soc_dai_link_component *c, 68 + char *match) 69 + { 70 + if (of_device_is_compatible(c->of_node, DT_PREFIX "aiu")) { 71 + if (strstr(c->dai_name, match)) 72 + return 1; 73 + } 74 + 75 + /* dai not matched */ 76 + return 0; 77 + } 78 + 79 + static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np, 80 + int *index) 81 + { 82 + struct snd_soc_dai_link *dai_link = &card->dai_link[*index]; 83 + struct snd_soc_dai_link_component *cpu; 84 + int ret; 85 + 86 + cpu = devm_kzalloc(card->dev, sizeof(*cpu), GFP_KERNEL); 87 + if (!cpu) 88 + return -ENOMEM; 89 + 90 + dai_link->cpus = cpu; 91 + dai_link->num_cpus = 1; 92 + 93 + ret = meson_card_parse_dai(card, np, &dai_link->cpus->of_node, 94 + &dai_link->cpus->dai_name); 95 + if (ret) 96 + return ret; 97 + 98 + if (gx_card_cpu_identify(dai_link->cpus, "FIFO")) 99 + ret = meson_card_set_fe_link(card, dai_link, np, true); 100 + else 101 + ret = meson_card_set_be_link(card, dai_link, np); 102 + 103 + if (ret) 104 + return ret; 105 + 106 + /* Check if the cpu is the i2s encoder and parse i2s data */ 107 + if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder")) 108 + ret = gx_card_parse_i2s(card, np, index); 109 + 110 + /* Or apply codec to codec params if necessary */ 111 + else if (gx_card_cpu_identify(dai_link->cpus, "CODEC CTRL")) 112 + dai_link->params = &codec_params; 113 + 114 + return ret; 115 + } 116 + 117 + static const struct meson_card_match_data gx_card_match_data = { 118 + .add_link = gx_card_add_link, 119 + }; 120 + 121 + static const struct of_device_id gx_card_of_match[] = { 122 + { 123 + .compatible = "amlogic,gx-sound-card", 124 + .data = &gx_card_match_data, 125 + }, {} 126 + }; 127 + MODULE_DEVICE_TABLE(of, gx_card_of_match); 128 + 129 + static struct platform_driver gx_card_pdrv = { 130 + .probe = meson_card_probe, 131 + .remove = meson_card_remove, 132 + .driver = { 133 + .name = "gx-sound-card", 134 + .of_match_table = gx_card_of_match, 135 + }, 136 + }; 137 + module_platform_driver(gx_card_pdrv); 138 + 139 + MODULE_DESCRIPTION("Amlogic GX ALSA machine driver"); 140 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 141 + MODULE_LICENSE("GPL v2");
+385
sound/soc/meson/meson-card-utils.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/module.h> 7 + #include <linux/of_platform.h> 8 + #include <sound/soc.h> 9 + 10 + #include "meson-card.h" 11 + 12 + int meson_card_i2s_set_sysclk(struct snd_pcm_substream *substream, 13 + struct snd_pcm_hw_params *params, 14 + unsigned int mclk_fs) 15 + { 16 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 17 + struct snd_soc_dai *codec_dai; 18 + unsigned int mclk; 19 + int ret, i; 20 + 21 + if (!mclk_fs) 22 + return 0; 23 + 24 + mclk = params_rate(params) * mclk_fs; 25 + 26 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 27 + ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 28 + SND_SOC_CLOCK_IN); 29 + if (ret && ret != -ENOTSUPP) 30 + return ret; 31 + } 32 + 33 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 34 + SND_SOC_CLOCK_OUT); 35 + if (ret && ret != -ENOTSUPP) 36 + return ret; 37 + 38 + return 0; 39 + } 40 + EXPORT_SYMBOL_GPL(meson_card_i2s_set_sysclk); 41 + 42 + int meson_card_reallocate_links(struct snd_soc_card *card, 43 + unsigned int num_links) 44 + { 45 + struct meson_card *priv = snd_soc_card_get_drvdata(card); 46 + struct snd_soc_dai_link *links; 47 + void **ldata; 48 + 49 + links = krealloc(priv->card.dai_link, 50 + num_links * sizeof(*priv->card.dai_link), 51 + GFP_KERNEL | __GFP_ZERO); 52 + ldata = krealloc(priv->link_data, 53 + num_links * sizeof(*priv->link_data), 54 + GFP_KERNEL | __GFP_ZERO); 55 + 56 + if (!links || !ldata) { 57 + dev_err(priv->card.dev, "failed to allocate links\n"); 58 + return -ENOMEM; 59 + } 60 + 61 + priv->card.dai_link = links; 62 + priv->link_data = ldata; 63 + priv->card.num_links = num_links; 64 + return 0; 65 + } 66 + EXPORT_SYMBOL_GPL(meson_card_reallocate_links); 67 + 68 + int meson_card_parse_dai(struct snd_soc_card *card, 69 + struct device_node *node, 70 + struct device_node **dai_of_node, 71 + const char **dai_name) 72 + { 73 + struct of_phandle_args args; 74 + int ret; 75 + 76 + if (!dai_name || !dai_of_node || !node) 77 + return -EINVAL; 78 + 79 + ret = of_parse_phandle_with_args(node, "sound-dai", 80 + "#sound-dai-cells", 0, &args); 81 + if (ret) { 82 + if (ret != -EPROBE_DEFER) 83 + dev_err(card->dev, "can't parse dai %d\n", ret); 84 + return ret; 85 + } 86 + *dai_of_node = args.np; 87 + 88 + return snd_soc_get_dai_name(&args, dai_name); 89 + } 90 + EXPORT_SYMBOL_GPL(meson_card_parse_dai); 91 + 92 + static int meson_card_set_link_name(struct snd_soc_card *card, 93 + struct snd_soc_dai_link *link, 94 + struct device_node *node, 95 + const char *prefix) 96 + { 97 + char *name = devm_kasprintf(card->dev, GFP_KERNEL, "%s.%s", 98 + prefix, node->full_name); 99 + if (!name) 100 + return -ENOMEM; 101 + 102 + link->name = name; 103 + link->stream_name = name; 104 + 105 + return 0; 106 + } 107 + 108 + unsigned int meson_card_parse_daifmt(struct device_node *node, 109 + struct device_node *cpu_node) 110 + { 111 + struct device_node *bitclkmaster = NULL; 112 + struct device_node *framemaster = NULL; 113 + unsigned int daifmt; 114 + 115 + daifmt = snd_soc_of_parse_daifmt(node, DT_PREFIX, 116 + &bitclkmaster, &framemaster); 117 + daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; 118 + 119 + /* If no master is provided, default to cpu master */ 120 + if (!bitclkmaster || bitclkmaster == cpu_node) { 121 + daifmt |= (!framemaster || framemaster == cpu_node) ? 122 + SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBS_CFM; 123 + } else { 124 + daifmt |= (!framemaster || framemaster == cpu_node) ? 125 + SND_SOC_DAIFMT_CBM_CFS : SND_SOC_DAIFMT_CBM_CFM; 126 + } 127 + 128 + of_node_put(bitclkmaster); 129 + of_node_put(framemaster); 130 + 131 + return daifmt; 132 + } 133 + EXPORT_SYMBOL_GPL(meson_card_parse_daifmt); 134 + 135 + int meson_card_set_be_link(struct snd_soc_card *card, 136 + struct snd_soc_dai_link *link, 137 + struct device_node *node) 138 + { 139 + struct snd_soc_dai_link_component *codec; 140 + struct device_node *np; 141 + int ret, num_codecs; 142 + 143 + link->no_pcm = 1; 144 + link->dpcm_playback = 1; 145 + link->dpcm_capture = 1; 146 + 147 + num_codecs = of_get_child_count(node); 148 + if (!num_codecs) { 149 + dev_err(card->dev, "be link %s has no codec\n", 150 + node->full_name); 151 + return -EINVAL; 152 + } 153 + 154 + codec = devm_kcalloc(card->dev, num_codecs, sizeof(*codec), GFP_KERNEL); 155 + if (!codec) 156 + return -ENOMEM; 157 + 158 + link->codecs = codec; 159 + link->num_codecs = num_codecs; 160 + 161 + for_each_child_of_node(node, np) { 162 + ret = meson_card_parse_dai(card, np, &codec->of_node, 163 + &codec->dai_name); 164 + if (ret) { 165 + of_node_put(np); 166 + return ret; 167 + } 168 + 169 + codec++; 170 + } 171 + 172 + ret = meson_card_set_link_name(card, link, node, "be"); 173 + if (ret) 174 + dev_err(card->dev, "error setting %pOFn link name\n", np); 175 + 176 + return ret; 177 + } 178 + EXPORT_SYMBOL_GPL(meson_card_set_be_link); 179 + 180 + int meson_card_set_fe_link(struct snd_soc_card *card, 181 + struct snd_soc_dai_link *link, 182 + struct device_node *node, 183 + bool is_playback) 184 + { 185 + struct snd_soc_dai_link_component *codec; 186 + 187 + codec = devm_kzalloc(card->dev, sizeof(*codec), GFP_KERNEL); 188 + if (!codec) 189 + return -ENOMEM; 190 + 191 + link->codecs = codec; 192 + link->num_codecs = 1; 193 + 194 + link->dynamic = 1; 195 + link->dpcm_merged_format = 1; 196 + link->dpcm_merged_chan = 1; 197 + link->dpcm_merged_rate = 1; 198 + link->codecs->dai_name = "snd-soc-dummy-dai"; 199 + link->codecs->name = "snd-soc-dummy"; 200 + 201 + if (is_playback) 202 + link->dpcm_playback = 1; 203 + else 204 + link->dpcm_capture = 1; 205 + 206 + return meson_card_set_link_name(card, link, node, "fe"); 207 + } 208 + EXPORT_SYMBOL_GPL(meson_card_set_fe_link); 209 + 210 + static int meson_card_add_links(struct snd_soc_card *card) 211 + { 212 + struct meson_card *priv = snd_soc_card_get_drvdata(card); 213 + struct device_node *node = card->dev->of_node; 214 + struct device_node *np; 215 + int num, i, ret; 216 + 217 + num = of_get_child_count(node); 218 + if (!num) { 219 + dev_err(card->dev, "card has no links\n"); 220 + return -EINVAL; 221 + } 222 + 223 + ret = meson_card_reallocate_links(card, num); 224 + if (ret) 225 + return ret; 226 + 227 + i = 0; 228 + for_each_child_of_node(node, np) { 229 + ret = priv->match_data->add_link(card, np, &i); 230 + if (ret) { 231 + of_node_put(np); 232 + return ret; 233 + } 234 + 235 + i++; 236 + } 237 + 238 + return 0; 239 + } 240 + 241 + static int meson_card_parse_of_optional(struct snd_soc_card *card, 242 + const char *propname, 243 + int (*func)(struct snd_soc_card *c, 244 + const char *p)) 245 + { 246 + /* If property is not provided, don't fail ... */ 247 + if (!of_property_read_bool(card->dev->of_node, propname)) 248 + return 0; 249 + 250 + /* ... but do fail if it is provided and the parsing fails */ 251 + return func(card, propname); 252 + } 253 + 254 + static int meson_card_add_aux_devices(struct snd_soc_card *card) 255 + { 256 + struct device_node *node = card->dev->of_node; 257 + struct snd_soc_aux_dev *aux; 258 + int num, i; 259 + 260 + num = of_count_phandle_with_args(node, "audio-aux-devs", NULL); 261 + if (num == -ENOENT) { 262 + return 0; 263 + } else if (num < 0) { 264 + dev_err(card->dev, "error getting auxiliary devices: %d\n", 265 + num); 266 + return num; 267 + } 268 + 269 + aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL); 270 + if (!aux) 271 + return -ENOMEM; 272 + card->aux_dev = aux; 273 + card->num_aux_devs = num; 274 + 275 + for_each_card_pre_auxs(card, i, aux) { 276 + aux->dlc.of_node = 277 + of_parse_phandle(node, "audio-aux-devs", i); 278 + if (!aux->dlc.of_node) 279 + return -EINVAL; 280 + } 281 + 282 + return 0; 283 + } 284 + 285 + static void meson_card_clean_references(struct meson_card *priv) 286 + { 287 + struct snd_soc_card *card = &priv->card; 288 + struct snd_soc_dai_link *link; 289 + struct snd_soc_dai_link_component *codec; 290 + struct snd_soc_aux_dev *aux; 291 + int i, j; 292 + 293 + if (card->dai_link) { 294 + for_each_card_prelinks(card, i, link) { 295 + if (link->cpus) 296 + of_node_put(link->cpus->of_node); 297 + for_each_link_codecs(link, j, codec) 298 + of_node_put(codec->of_node); 299 + } 300 + } 301 + 302 + if (card->aux_dev) { 303 + for_each_card_pre_auxs(card, i, aux) 304 + of_node_put(aux->dlc.of_node); 305 + } 306 + 307 + kfree(card->dai_link); 308 + kfree(priv->link_data); 309 + } 310 + 311 + int meson_card_probe(struct platform_device *pdev) 312 + { 313 + const struct meson_card_match_data *data; 314 + struct device *dev = &pdev->dev; 315 + struct meson_card *priv; 316 + int ret; 317 + 318 + data = of_device_get_match_data(dev); 319 + if (!data) { 320 + dev_err(dev, "failed to match device\n"); 321 + return -ENODEV; 322 + } 323 + 324 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 325 + if (!priv) 326 + return -ENOMEM; 327 + 328 + platform_set_drvdata(pdev, priv); 329 + snd_soc_card_set_drvdata(&priv->card, priv); 330 + 331 + priv->card.owner = THIS_MODULE; 332 + priv->card.dev = dev; 333 + priv->match_data = data; 334 + 335 + ret = snd_soc_of_parse_card_name(&priv->card, "model"); 336 + if (ret < 0) 337 + return ret; 338 + 339 + ret = meson_card_parse_of_optional(&priv->card, "audio-routing", 340 + snd_soc_of_parse_audio_routing); 341 + if (ret) { 342 + dev_err(dev, "error while parsing routing\n"); 343 + return ret; 344 + } 345 + 346 + ret = meson_card_parse_of_optional(&priv->card, "audio-widgets", 347 + snd_soc_of_parse_audio_simple_widgets); 348 + if (ret) { 349 + dev_err(dev, "error while parsing widgets\n"); 350 + return ret; 351 + } 352 + 353 + ret = meson_card_add_links(&priv->card); 354 + if (ret) 355 + goto out_err; 356 + 357 + ret = meson_card_add_aux_devices(&priv->card); 358 + if (ret) 359 + goto out_err; 360 + 361 + ret = devm_snd_soc_register_card(dev, &priv->card); 362 + if (ret) 363 + goto out_err; 364 + 365 + return 0; 366 + 367 + out_err: 368 + meson_card_clean_references(priv); 369 + return ret; 370 + } 371 + EXPORT_SYMBOL_GPL(meson_card_probe); 372 + 373 + int meson_card_remove(struct platform_device *pdev) 374 + { 375 + struct meson_card *priv = platform_get_drvdata(pdev); 376 + 377 + meson_card_clean_references(priv); 378 + 379 + return 0; 380 + } 381 + EXPORT_SYMBOL_GPL(meson_card_remove); 382 + 383 + MODULE_DESCRIPTION("Amlogic Sound Card Utils"); 384 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 385 + MODULE_LICENSE("GPL v2");
+55
sound/soc/meson/meson-card.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef _MESON_SND_CARD_H 8 + #define _MESON_SND_CARD_H 9 + 10 + struct device_node; 11 + struct platform_device; 12 + 13 + struct snd_soc_card; 14 + struct snd_pcm_substream; 15 + struct snd_pcm_hw_params; 16 + 17 + #define DT_PREFIX "amlogic," 18 + 19 + struct meson_card_match_data { 20 + int (*add_link)(struct snd_soc_card *card, 21 + struct device_node *node, 22 + int *index); 23 + }; 24 + 25 + struct meson_card { 26 + const struct meson_card_match_data *match_data; 27 + struct snd_soc_card card; 28 + void **link_data; 29 + }; 30 + 31 + unsigned int meson_card_parse_daifmt(struct device_node *node, 32 + struct device_node *cpu_node); 33 + 34 + int meson_card_i2s_set_sysclk(struct snd_pcm_substream *substream, 35 + struct snd_pcm_hw_params *params, 36 + unsigned int mclk_fs); 37 + 38 + int meson_card_reallocate_links(struct snd_soc_card *card, 39 + unsigned int num_links); 40 + int meson_card_parse_dai(struct snd_soc_card *card, 41 + struct device_node *node, 42 + struct device_node **dai_of_node, 43 + const char **dai_name); 44 + int meson_card_set_be_link(struct snd_soc_card *card, 45 + struct snd_soc_dai_link *link, 46 + struct device_node *node); 47 + int meson_card_set_fe_link(struct snd_soc_card *card, 48 + struct snd_soc_dai_link *link, 49 + struct device_node *node, 50 + bool is_playback); 51 + 52 + int meson_card_probe(struct platform_device *pdev); 53 + int meson_card_remove(struct platform_device *pdev); 54 + 55 + #endif /* _MESON_SND_CARD_H */
+149
sound/soc/meson/meson-codec-glue.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2019 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/module.h> 7 + #include <sound/pcm_params.h> 8 + #include <sound/soc.h> 9 + #include <sound/soc-dai.h> 10 + 11 + #include "meson-codec-glue.h" 12 + 13 + static struct snd_soc_dapm_widget * 14 + meson_codec_glue_get_input(struct snd_soc_dapm_widget *w) 15 + { 16 + struct snd_soc_dapm_path *p = NULL; 17 + struct snd_soc_dapm_widget *in; 18 + 19 + snd_soc_dapm_widget_for_each_source_path(w, p) { 20 + if (!p->connect) 21 + continue; 22 + 23 + /* Check that we still are in the same component */ 24 + if (snd_soc_dapm_to_component(w->dapm) != 25 + snd_soc_dapm_to_component(p->source->dapm)) 26 + continue; 27 + 28 + if (p->source->id == snd_soc_dapm_dai_in) 29 + return p->source; 30 + 31 + in = meson_codec_glue_get_input(p->source); 32 + if (in) 33 + return in; 34 + } 35 + 36 + return NULL; 37 + } 38 + 39 + static void meson_codec_glue_input_set_data(struct snd_soc_dai *dai, 40 + struct meson_codec_glue_input *data) 41 + { 42 + dai->playback_dma_data = data; 43 + } 44 + 45 + struct meson_codec_glue_input * 46 + meson_codec_glue_input_get_data(struct snd_soc_dai *dai) 47 + { 48 + return dai->playback_dma_data; 49 + } 50 + EXPORT_SYMBOL_GPL(meson_codec_glue_input_get_data); 51 + 52 + static struct meson_codec_glue_input * 53 + meson_codec_glue_output_get_input_data(struct snd_soc_dapm_widget *w) 54 + { 55 + struct snd_soc_dapm_widget *in = 56 + meson_codec_glue_get_input(w); 57 + struct snd_soc_dai *dai; 58 + 59 + if (WARN_ON(!in)) 60 + return NULL; 61 + 62 + dai = in->priv; 63 + 64 + return meson_codec_glue_input_get_data(dai); 65 + } 66 + 67 + int meson_codec_glue_input_hw_params(struct snd_pcm_substream *substream, 68 + struct snd_pcm_hw_params *params, 69 + struct snd_soc_dai *dai) 70 + { 71 + struct meson_codec_glue_input *data = 72 + meson_codec_glue_input_get_data(dai); 73 + 74 + data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params)); 75 + data->params.rate_min = params_rate(params); 76 + data->params.rate_max = params_rate(params); 77 + data->params.formats = 1ULL << (__force int) params_format(params); 78 + data->params.channels_min = params_channels(params); 79 + data->params.channels_max = params_channels(params); 80 + data->params.sig_bits = dai->driver->playback.sig_bits; 81 + 82 + return 0; 83 + } 84 + EXPORT_SYMBOL_GPL(meson_codec_glue_input_hw_params); 85 + 86 + int meson_codec_glue_input_set_fmt(struct snd_soc_dai *dai, 87 + unsigned int fmt) 88 + { 89 + struct meson_codec_glue_input *data = 90 + meson_codec_glue_input_get_data(dai); 91 + 92 + /* Save the source stream format for the downstream link */ 93 + data->fmt = fmt; 94 + return 0; 95 + } 96 + EXPORT_SYMBOL_GPL(meson_codec_glue_input_set_fmt); 97 + 98 + int meson_codec_glue_output_startup(struct snd_pcm_substream *substream, 99 + struct snd_soc_dai *dai) 100 + { 101 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 102 + struct meson_codec_glue_input *in_data = 103 + meson_codec_glue_output_get_input_data(dai->capture_widget); 104 + 105 + if (!in_data) 106 + return -ENODEV; 107 + 108 + if (WARN_ON(!rtd->dai_link->params)) { 109 + dev_warn(dai->dev, "codec2codec link expected\n"); 110 + return -EINVAL; 111 + } 112 + 113 + /* Replace link params with the input params */ 114 + rtd->dai_link->params = &in_data->params; 115 + 116 + if (!in_data->fmt) 117 + return 0; 118 + 119 + return snd_soc_runtime_set_dai_fmt(rtd, in_data->fmt); 120 + } 121 + EXPORT_SYMBOL_GPL(meson_codec_glue_output_startup); 122 + 123 + int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai) 124 + { 125 + struct meson_codec_glue_input *data; 126 + 127 + data = kzalloc(sizeof(*data), GFP_KERNEL); 128 + if (!data) 129 + return -ENOMEM; 130 + 131 + meson_codec_glue_input_set_data(dai, data); 132 + return 0; 133 + } 134 + EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_probe); 135 + 136 + int meson_codec_glue_input_dai_remove(struct snd_soc_dai *dai) 137 + { 138 + struct meson_codec_glue_input *data = 139 + meson_codec_glue_input_get_data(dai); 140 + 141 + kfree(data); 142 + return 0; 143 + } 144 + EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_remove); 145 + 146 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 147 + MODULE_DESCRIPTION("Amlogic Codec Glue Helpers"); 148 + MODULE_LICENSE("GPL v2"); 149 +
+32
sound/soc/meson/meson-codec-glue.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * Copyright (c) 2018 Baylibre SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef _MESON_CODEC_GLUE_H 8 + #define _MESON_CODEC_GLUE_H 9 + 10 + #include <sound/soc.h> 11 + 12 + struct meson_codec_glue_input { 13 + struct snd_soc_pcm_stream params; 14 + unsigned int fmt; 15 + }; 16 + 17 + /* Input helpers */ 18 + struct meson_codec_glue_input * 19 + meson_codec_glue_input_get_data(struct snd_soc_dai *dai); 20 + int meson_codec_glue_input_hw_params(struct snd_pcm_substream *substream, 21 + struct snd_pcm_hw_params *params, 22 + struct snd_soc_dai *dai); 23 + int meson_codec_glue_input_set_fmt(struct snd_soc_dai *dai, 24 + unsigned int fmt); 25 + int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai); 26 + int meson_codec_glue_input_dai_remove(struct snd_soc_dai *dai); 27 + 28 + /* Output helpers */ 29 + int meson_codec_glue_output_startup(struct snd_pcm_substream *substream, 30 + struct snd_soc_dai *dai); 31 + 32 + #endif /* _MESON_CODEC_GLUE_H */
+333
sound/soc/meson/t9015.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 BayLibre, SAS. 4 + // Author: Jerome Brunet <jbrunet@baylibre.com> 5 + 6 + #include <linux/clk.h> 7 + #include <linux/delay.h> 8 + #include <linux/module.h> 9 + #include <linux/regmap.h> 10 + #include <linux/regulator/consumer.h> 11 + #include <linux/reset.h> 12 + #include <sound/soc.h> 13 + #include <sound/tlv.h> 14 + 15 + #define BLOCK_EN 0x00 16 + #define LORN_EN 0 17 + #define LORP_EN 1 18 + #define LOLN_EN 2 19 + #define LOLP_EN 3 20 + #define DACR_EN 4 21 + #define DACL_EN 5 22 + #define DACR_INV 20 23 + #define DACL_INV 21 24 + #define DACR_SRC 22 25 + #define DACL_SRC 23 26 + #define REFP_BUF_EN BIT(12) 27 + #define BIAS_CURRENT_EN BIT(13) 28 + #define VMID_GEN_FAST BIT(14) 29 + #define VMID_GEN_EN BIT(15) 30 + #define I2S_MODE BIT(30) 31 + #define VOL_CTRL0 0x04 32 + #define GAIN_H 31 33 + #define GAIN_L 23 34 + #define VOL_CTRL1 0x08 35 + #define DAC_MONO 8 36 + #define RAMP_RATE 10 37 + #define VC_RAMP_MODE 12 38 + #define MUTE_MODE 13 39 + #define UNMUTE_MODE 14 40 + #define DAC_SOFT_MUTE 15 41 + #define DACR_VC 16 42 + #define DACL_VC 24 43 + #define LINEOUT_CFG 0x0c 44 + #define LORN_POL 0 45 + #define LORP_POL 4 46 + #define LOLN_POL 8 47 + #define LOLP_POL 12 48 + #define POWER_CFG 0x10 49 + 50 + struct t9015 { 51 + struct clk *pclk; 52 + struct regulator *avdd; 53 + }; 54 + 55 + static int t9015_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 56 + { 57 + struct snd_soc_component *component = dai->component; 58 + unsigned int val; 59 + 60 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 61 + case SND_SOC_DAIFMT_CBM_CFM: 62 + val = I2S_MODE; 63 + break; 64 + 65 + case SND_SOC_DAIFMT_CBS_CFS: 66 + val = 0; 67 + break; 68 + 69 + default: 70 + return -EINVAL; 71 + } 72 + 73 + snd_soc_component_update_bits(component, BLOCK_EN, I2S_MODE, val); 74 + 75 + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) && 76 + ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_LEFT_J)) 77 + return -EINVAL; 78 + 79 + return 0; 80 + } 81 + 82 + static const struct snd_soc_dai_ops t9015_dai_ops = { 83 + .set_fmt = t9015_dai_set_fmt, 84 + }; 85 + 86 + static struct snd_soc_dai_driver t9015_dai = { 87 + .name = "t9015-hifi", 88 + .playback = { 89 + .stream_name = "Playback", 90 + .channels_min = 1, 91 + .channels_max = 2, 92 + .rates = SNDRV_PCM_RATE_8000_96000, 93 + .formats = (SNDRV_PCM_FMTBIT_S8 | 94 + SNDRV_PCM_FMTBIT_S16_LE | 95 + SNDRV_PCM_FMTBIT_S20_LE | 96 + SNDRV_PCM_FMTBIT_S24_LE), 97 + }, 98 + .ops = &t9015_dai_ops, 99 + }; 100 + 101 + static const DECLARE_TLV_DB_MINMAX_MUTE(dac_vol_tlv, -9525, 0); 102 + 103 + static const char * const ramp_rate_txt[] = { "Fast", "Slow" }; 104 + static SOC_ENUM_SINGLE_DECL(ramp_rate_enum, VOL_CTRL1, RAMP_RATE, 105 + ramp_rate_txt); 106 + 107 + static const char * const dacr_in_txt[] = { "Right", "Left" }; 108 + static SOC_ENUM_SINGLE_DECL(dacr_in_enum, BLOCK_EN, DACR_SRC, dacr_in_txt); 109 + 110 + static const char * const dacl_in_txt[] = { "Left", "Right" }; 111 + static SOC_ENUM_SINGLE_DECL(dacl_in_enum, BLOCK_EN, DACL_SRC, dacl_in_txt); 112 + 113 + static const char * const mono_txt[] = { "Stereo", "Mono"}; 114 + static SOC_ENUM_SINGLE_DECL(mono_enum, VOL_CTRL1, DAC_MONO, mono_txt); 115 + 116 + static const struct snd_kcontrol_new t9015_snd_controls[] = { 117 + /* Volume Controls */ 118 + SOC_ENUM("Playback Channel Mode", mono_enum), 119 + SOC_SINGLE("Playback Switch", VOL_CTRL1, DAC_SOFT_MUTE, 1, 1), 120 + SOC_DOUBLE_TLV("Playback Volume", VOL_CTRL1, DACL_VC, DACR_VC, 121 + 0xff, 0, dac_vol_tlv), 122 + 123 + /* Ramp Controls */ 124 + SOC_ENUM("Ramp Rate", ramp_rate_enum), 125 + SOC_SINGLE("Volume Ramp Switch", VOL_CTRL1, VC_RAMP_MODE, 1, 0), 126 + SOC_SINGLE("Mute Ramp Switch", VOL_CTRL1, MUTE_MODE, 1, 0), 127 + SOC_SINGLE("Unmute Ramp Switch", VOL_CTRL1, UNMUTE_MODE, 1, 0), 128 + }; 129 + 130 + static const struct snd_kcontrol_new t9015_right_dac_mux = 131 + SOC_DAPM_ENUM("Right DAC Source", dacr_in_enum); 132 + static const struct snd_kcontrol_new t9015_left_dac_mux = 133 + SOC_DAPM_ENUM("Left DAC Source", dacl_in_enum); 134 + 135 + static const struct snd_soc_dapm_widget t9015_dapm_widgets[] = { 136 + SND_SOC_DAPM_AIF_IN("Right IN", NULL, 0, SND_SOC_NOPM, 0, 0), 137 + SND_SOC_DAPM_AIF_IN("Left IN", NULL, 0, SND_SOC_NOPM, 0, 0), 138 + SND_SOC_DAPM_MUX("Right DAC Sel", SND_SOC_NOPM, 0, 0, 139 + &t9015_right_dac_mux), 140 + SND_SOC_DAPM_MUX("Left DAC Sel", SND_SOC_NOPM, 0, 0, 141 + &t9015_left_dac_mux), 142 + SND_SOC_DAPM_DAC("Right DAC", NULL, BLOCK_EN, DACR_EN, 0), 143 + SND_SOC_DAPM_DAC("Left DAC", NULL, BLOCK_EN, DACL_EN, 0), 144 + SND_SOC_DAPM_OUT_DRV("Right- Driver", BLOCK_EN, LORN_EN, 0, 145 + NULL, 0), 146 + SND_SOC_DAPM_OUT_DRV("Right+ Driver", BLOCK_EN, LORP_EN, 0, 147 + NULL, 0), 148 + SND_SOC_DAPM_OUT_DRV("Left- Driver", BLOCK_EN, LOLN_EN, 0, 149 + NULL, 0), 150 + SND_SOC_DAPM_OUT_DRV("Left+ Driver", BLOCK_EN, LOLP_EN, 0, 151 + NULL, 0), 152 + SND_SOC_DAPM_OUTPUT("LORN"), 153 + SND_SOC_DAPM_OUTPUT("LORP"), 154 + SND_SOC_DAPM_OUTPUT("LOLN"), 155 + SND_SOC_DAPM_OUTPUT("LOLP"), 156 + }; 157 + 158 + static const struct snd_soc_dapm_route t9015_dapm_routes[] = { 159 + { "Right IN", NULL, "Playback" }, 160 + { "Left IN", NULL, "Playback" }, 161 + { "Right DAC Sel", "Right", "Right IN" }, 162 + { "Right DAC Sel", "Left", "Left IN" }, 163 + { "Left DAC Sel", "Right", "Right IN" }, 164 + { "Left DAC Sel", "Left", "Left IN" }, 165 + { "Right DAC", NULL, "Right DAC Sel" }, 166 + { "Left DAC", NULL, "Left DAC Sel" }, 167 + { "Right- Driver", NULL, "Right DAC" }, 168 + { "Right+ Driver", NULL, "Right DAC" }, 169 + { "Left- Driver", NULL, "Left DAC" }, 170 + { "Left+ Driver", NULL, "Left DAC" }, 171 + { "LORN", NULL, "Right- Driver", }, 172 + { "LORP", NULL, "Right+ Driver", }, 173 + { "LOLN", NULL, "Left- Driver", }, 174 + { "LOLP", NULL, "Left+ Driver", }, 175 + }; 176 + 177 + static int t9015_set_bias_level(struct snd_soc_component *component, 178 + enum snd_soc_bias_level level) 179 + { 180 + struct t9015 *priv = snd_soc_component_get_drvdata(component); 181 + enum snd_soc_bias_level now = 182 + snd_soc_component_get_bias_level(component); 183 + int ret; 184 + 185 + switch (level) { 186 + case SND_SOC_BIAS_ON: 187 + snd_soc_component_update_bits(component, BLOCK_EN, 188 + BIAS_CURRENT_EN, 189 + BIAS_CURRENT_EN); 190 + break; 191 + case SND_SOC_BIAS_PREPARE: 192 + snd_soc_component_update_bits(component, BLOCK_EN, 193 + BIAS_CURRENT_EN, 194 + 0); 195 + break; 196 + case SND_SOC_BIAS_STANDBY: 197 + ret = regulator_enable(priv->avdd); 198 + if (ret) { 199 + dev_err(component->dev, "AVDD enable failed\n"); 200 + return ret; 201 + } 202 + 203 + if (now == SND_SOC_BIAS_OFF) { 204 + snd_soc_component_update_bits(component, BLOCK_EN, 205 + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN, 206 + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN); 207 + 208 + mdelay(200); 209 + snd_soc_component_update_bits(component, BLOCK_EN, 210 + VMID_GEN_FAST, 211 + 0); 212 + } 213 + 214 + break; 215 + case SND_SOC_BIAS_OFF: 216 + snd_soc_component_update_bits(component, BLOCK_EN, 217 + VMID_GEN_EN | VMID_GEN_FAST | REFP_BUF_EN, 218 + 0); 219 + 220 + regulator_disable(priv->avdd); 221 + break; 222 + } 223 + 224 + return 0; 225 + } 226 + 227 + static const struct snd_soc_component_driver t9015_codec_driver = { 228 + .set_bias_level = t9015_set_bias_level, 229 + .controls = t9015_snd_controls, 230 + .num_controls = ARRAY_SIZE(t9015_snd_controls), 231 + .dapm_widgets = t9015_dapm_widgets, 232 + .num_dapm_widgets = ARRAY_SIZE(t9015_dapm_widgets), 233 + .dapm_routes = t9015_dapm_routes, 234 + .num_dapm_routes = ARRAY_SIZE(t9015_dapm_routes), 235 + .suspend_bias_off = 1, 236 + .endianness = 1, 237 + .non_legacy_dai_naming = 1, 238 + }; 239 + 240 + static const struct regmap_config t9015_regmap_config = { 241 + .reg_bits = 32, 242 + .reg_stride = 4, 243 + .val_bits = 32, 244 + .max_register = POWER_CFG, 245 + }; 246 + 247 + static int t9015_probe(struct platform_device *pdev) 248 + { 249 + struct device *dev = &pdev->dev; 250 + struct t9015 *priv; 251 + void __iomem *regs; 252 + struct regmap *regmap; 253 + int ret; 254 + 255 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 256 + if (!priv) 257 + return -ENOMEM; 258 + platform_set_drvdata(pdev, priv); 259 + 260 + priv->pclk = devm_clk_get(dev, "pclk"); 261 + if (IS_ERR(priv->pclk)) { 262 + if (PTR_ERR(priv->pclk) != -EPROBE_DEFER) 263 + dev_err(dev, "failed to get core clock\n"); 264 + return PTR_ERR(priv->pclk); 265 + } 266 + 267 + priv->avdd = devm_regulator_get(dev, "AVDD"); 268 + if (IS_ERR(priv->avdd)) { 269 + if (PTR_ERR(priv->avdd) != -EPROBE_DEFER) 270 + dev_err(dev, "failed to AVDD\n"); 271 + return PTR_ERR(priv->avdd); 272 + } 273 + 274 + ret = clk_prepare_enable(priv->pclk); 275 + if (ret) { 276 + dev_err(dev, "core clock enable failed\n"); 277 + return ret; 278 + } 279 + 280 + ret = devm_add_action_or_reset(dev, 281 + (void(*)(void *))clk_disable_unprepare, 282 + priv->pclk); 283 + if (ret) 284 + return ret; 285 + 286 + ret = device_reset(dev); 287 + if (ret) { 288 + dev_err(dev, "reset failed\n"); 289 + return ret; 290 + } 291 + 292 + regs = devm_platform_ioremap_resource(pdev, 0); 293 + if (IS_ERR(regs)) { 294 + dev_err(dev, "register map failed\n"); 295 + return PTR_ERR(regs); 296 + } 297 + 298 + regmap = devm_regmap_init_mmio(dev, regs, &t9015_regmap_config); 299 + if (IS_ERR(regmap)) { 300 + dev_err(dev, "regmap init failed\n"); 301 + return PTR_ERR(regmap); 302 + } 303 + 304 + /* 305 + * Initialize output polarity: 306 + * ATM the output polarity is fixed but in the future it might useful 307 + * to add DT property to set this depending on the platform needs 308 + */ 309 + regmap_write(regmap, LINEOUT_CFG, 0x1111); 310 + 311 + return devm_snd_soc_register_component(dev, &t9015_codec_driver, 312 + &t9015_dai, 1); 313 + } 314 + 315 + static const struct of_device_id t9015_ids[] = { 316 + { .compatible = "amlogic,t9015", }, 317 + { } 318 + }; 319 + MODULE_DEVICE_TABLE(of, t9015_ids); 320 + 321 + static struct platform_driver t9015_driver = { 322 + .driver = { 323 + .name = "t9015-codec", 324 + .of_match_table = of_match_ptr(t9015_ids), 325 + }, 326 + .probe = t9015_probe, 327 + }; 328 + 329 + module_platform_driver(t9015_driver); 330 + 331 + MODULE_DESCRIPTION("ASoC Amlogic T9015 codec driver"); 332 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 333 + MODULE_LICENSE("GPL");
+2 -2
sound/soc/mxs/mxs-sgtl5000.c
··· 20 20 struct snd_pcm_hw_params *params) 21 21 { 22 22 struct snd_soc_pcm_runtime *rtd = substream->private_data; 23 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 24 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 23 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 24 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 25 25 unsigned int rate = params_rate(params); 26 26 u32 mclk; 27 27 int ret;
+22
sound/soc/pxa/Kconfig
··· 81 81 depends on SND_PXA2XX_SOC && MACH_TOSA 82 82 depends on MFD_TC6393XB 83 83 depends on AC97_BUS=n 84 + select REGMAP 85 + select AC97_BUS_NEW 86 + select AC97_BUS_COMPAT 84 87 select SND_PXA2XX_SOC_AC97 85 88 select SND_SOC_WM9712 86 89 help ··· 94 91 tristate "SoC AC97 Audio support for e740" 95 92 depends on SND_PXA2XX_SOC && MACH_E740 96 93 depends on AC97_BUS=n 94 + select REGMAP 95 + select AC97_BUS_NEW 96 + select AC97_BUS_COMPAT 97 97 select SND_SOC_WM9705 98 98 select SND_PXA2XX_SOC_AC97 99 99 help ··· 107 101 tristate "SoC AC97 Audio support for e750" 108 102 depends on SND_PXA2XX_SOC && MACH_E750 109 103 depends on AC97_BUS=n 104 + select REGMAP 110 105 select SND_SOC_WM9705 111 106 select SND_PXA2XX_SOC_AC97 112 107 help ··· 118 111 tristate "SoC AC97 Audio support for e800" 119 112 depends on SND_PXA2XX_SOC && MACH_E800 120 113 depends on AC97_BUS=n 114 + select REGMAP 121 115 select SND_SOC_WM9712 116 + select AC97_BUS_NEW 117 + select AC97_BUS_COMPAT 122 118 select SND_PXA2XX_SOC_AC97 123 119 help 124 120 Say Y if you want to add support for SoC audio on the ··· 132 122 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \ 133 123 MACH_CM_X300) 134 124 depends on AC97_BUS=n 125 + select REGMAP 126 + select AC97_BUS_NEW 127 + select AC97_BUS_COMPAT 135 128 select SND_PXA2XX_SOC_AC97 136 129 select SND_SOC_WM9712 137 130 help ··· 146 133 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \ 147 134 MACH_PALMT5 || MACH_PALMTE2) 148 135 depends on AC97_BUS=n 136 + select REGMAP 137 + select AC97_BUS_NEW 138 + select AC97_BUS_COMPAT 149 139 select SND_PXA2XX_SOC_AC97 150 140 select SND_SOC_WM9712 151 141 help ··· 179 163 tristate "SoC Audio support for Marvell Zylonite" 180 164 depends on SND_PXA2XX_SOC && MACH_ZYLONITE 181 165 depends on AC97_BUS=n 166 + select AC97_BUS_NEW 167 + select AC97_BUS_COMPAT 182 168 select SND_PXA2XX_SOC_AC97 169 + select REGMAP 183 170 select SND_PXA_SOC_SSP 184 171 select SND_SOC_WM9713 185 172 help ··· 212 193 tristate "SoC Audio support for MIO A701" 213 194 depends on SND_PXA2XX_SOC && MACH_MIOA701 214 195 depends on AC97_BUS=n 196 + select REGMAP 197 + select AC97_BUS_NEW 198 + select AC97_BUS_COMPAT 215 199 select SND_PXA2XX_SOC_AC97 216 200 select SND_SOC_WM9713 217 201 help
+2 -2
sound/soc/pxa/brownstone.c
··· 44 44 struct snd_pcm_hw_params *params) 45 45 { 46 46 struct snd_soc_pcm_runtime *rtd = substream->private_data; 47 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 47 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 48 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 49 49 int freq_out, sspa_mclk, sysclk; 50 50 51 51 if (params_rate(params) > 11025) {
+2 -2
sound/soc/pxa/corgi.c
··· 116 116 struct snd_pcm_hw_params *params) 117 117 { 118 118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 119 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 120 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 119 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 120 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 121 121 unsigned int clk = 0; 122 122 int ret = 0; 123 123
+2 -2
sound/soc/pxa/hx4700.c
··· 54 54 struct snd_pcm_hw_params *params) 55 55 { 56 56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 57 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 58 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 57 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 58 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 59 59 int ret = 0; 60 60 61 61 /* set the I2S system clock as output */
+2 -2
sound/soc/pxa/imote2.c
··· 12 12 struct snd_pcm_hw_params *params) 13 13 { 14 14 struct snd_soc_pcm_runtime *rtd = substream->private_data; 15 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 16 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 15 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 16 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 17 17 unsigned int clk = 0; 18 18 int ret; 19 19
+7 -7
sound/soc/pxa/magician.c
··· 83 83 struct snd_pcm_hw_params *params) 84 84 { 85 85 struct snd_soc_pcm_runtime *rtd = substream->private_data; 86 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 87 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 86 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 87 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 88 88 unsigned int width; 89 89 int ret = 0; 90 90 ··· 121 121 struct snd_pcm_hw_params *params) 122 122 { 123 123 struct snd_soc_pcm_runtime *rtd = substream->private_data; 124 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 125 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 124 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 125 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 126 126 int ret = 0; 127 127 128 128 /* set codec DAI configuration */ ··· 358 358 adapter = i2c_get_adapter(0); 359 359 if (!adapter) 360 360 return -ENODEV; 361 - client = i2c_new_device(adapter, i2c_board_info); 361 + client = i2c_new_client_device(adapter, i2c_board_info); 362 362 i2c_put_adapter(adapter); 363 - if (!client) 364 - return -ENODEV; 363 + if (IS_ERR(client)) 364 + return PTR_ERR(client); 365 365 366 366 ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER"); 367 367 if (ret)
+2 -2
sound/soc/pxa/mioa701_wm9713.c
··· 73 73 struct snd_soc_component *component; 74 74 75 75 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 76 - component = rtd->codec_dai->component; 76 + component = asoc_rtd_to_codec(rtd, 0)->component; 77 77 return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event)); 78 78 } 79 79 ··· 117 117 118 118 static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) 119 119 { 120 - struct snd_soc_component *component = rtd->codec_dai->component; 120 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 121 121 122 122 /* Prepare GPIO8 for rear speaker amplifier */ 123 123 snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100);
+1 -1
sound/soc/pxa/mmp-pcm.c
··· 112 112 { 113 113 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 114 struct platform_device *pdev = to_platform_device(component->dev); 115 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 115 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 116 116 struct mmp_dma_data dma_data; 117 117 struct resource *r; 118 118
+1 -1
sound/soc/pxa/mmp-sspa.c
··· 251 251 struct snd_soc_dai *dai) 252 252 { 253 253 struct snd_soc_pcm_runtime *rtd = substream->private_data; 254 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 254 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 255 255 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai); 256 256 struct ssp_device *sspa = sspa_priv->sspa; 257 257 struct snd_dmaengine_dai_dma_data *dma_params;
+2 -2
sound/soc/pxa/poodle.c
··· 90 90 struct snd_pcm_hw_params *params) 91 91 { 92 92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 93 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 94 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 93 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 94 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 95 95 unsigned int clk = 0; 96 96 int ret = 0; 97 97
+1 -1
sound/soc/pxa/pxa2xx-i2s.c
··· 96 96 struct snd_soc_dai *dai) 97 97 { 98 98 struct snd_soc_pcm_runtime *rtd = substream->private_data; 99 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 99 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 100 100 101 101 if (IS_ERR(clk_i2s)) 102 102 return PTR_ERR(clk_i2s);
+2 -2
sound/soc/pxa/spitz.c
··· 117 117 struct snd_pcm_hw_params *params) 118 118 { 119 119 struct snd_soc_pcm_runtime *rtd = substream->private_data; 120 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 121 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 120 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 121 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 122 122 unsigned int clk = 0; 123 123 int ret = 0; 124 124
+1 -1
sound/soc/pxa/ttc-dkb.c
··· 61 61 62 62 static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) 63 63 { 64 - struct snd_soc_component *component = rtd->codec_dai->component; 64 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 65 65 66 66 /* Headset jack detection */ 67 67 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE |
+2 -2
sound/soc/pxa/z2.c
··· 34 34 struct snd_pcm_hw_params *params) 35 35 { 36 36 struct snd_soc_pcm_runtime *rtd = substream->private_data; 37 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 38 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 37 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 38 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 39 39 unsigned int clk = 0; 40 40 int ret = 0; 41 41
+3 -3
sound/soc/pxa/zylonite.c
··· 66 66 static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) 67 67 { 68 68 if (clk_pout) 69 - snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, 69 + snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 0, 0, 70 70 clk_get_rate(pout), 0); 71 71 72 72 return 0; ··· 76 76 struct snd_pcm_hw_params *params) 77 77 { 78 78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 80 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 79 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 80 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 81 81 unsigned int wm9713_div = 0; 82 82 int ret = 0; 83 83 int rate = params_rate(params);
+1 -1
sound/soc/qcom/Kconfig
··· 99 99 100 100 config SND_SOC_SDM845 101 101 tristate "SoC Machine driver for SDM845 boards" 102 - depends on QCOM_APR && CROS_EC && I2C 102 + depends on QCOM_APR && CROS_EC && I2C && SOUNDWIRE 103 103 select SND_SOC_QDSP6 104 104 select SND_SOC_QCOM_COMMON 105 105 select SND_SOC_RT5663
+4 -5
sound/soc/qcom/apq8016_sbc.c
··· 33 33 34 34 static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) 35 35 { 36 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 36 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 37 + struct snd_soc_dai *codec_dai; 37 38 struct snd_soc_component *component; 38 - struct snd_soc_dai_link *dai_link = rtd->dai_link; 39 39 struct snd_soc_card *card = rtd->card; 40 40 struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); 41 41 int i, rval; ··· 90 90 pdata->jack_setup = true; 91 91 } 92 92 93 - for (i = 0 ; i < dai_link->num_codecs; i++) { 94 - struct snd_soc_dai *dai = rtd->codec_dais[i]; 93 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 95 94 96 - component = dai->component; 95 + component = codec_dai->component; 97 96 /* Set default mclk for internal codec */ 98 97 rval = snd_soc_component_set_sysclk(component, 0, 0, DEFAULT_MCLK_RATE, 99 98 SND_SOC_CLOCK_IN);
+3 -3
sound/soc/qcom/apq8096.c
··· 31 31 struct snd_pcm_hw_params *params) 32 32 { 33 33 struct snd_soc_pcm_runtime *rtd = substream->private_data; 34 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 35 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 34 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 35 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 36 36 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; 37 37 u32 rx_ch_cnt = 0, tx_ch_cnt = 0; 38 38 int ret = 0; ··· 66 66 67 67 static int apq8096_init(struct snd_soc_pcm_runtime *rtd) 68 68 { 69 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 69 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 70 70 71 71 /* 72 72 * Codec SLIMBUS configuration
+2 -2
sound/soc/qcom/lpass-platform.c
··· 55 55 { 56 56 struct snd_pcm_runtime *runtime = substream->runtime; 57 57 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 58 - struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai; 58 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_runtime, 0); 59 59 struct lpass_data *drvdata = snd_soc_component_get_drvdata(component); 60 60 struct lpass_variant *v = drvdata->variant; 61 61 int ret, dma_ch, dir = substream->stream; ··· 529 529 struct snd_pcm_substream *substream; 530 530 int i; 531 531 532 - for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) { 532 + for_each_pcm_streams(i) { 533 533 substream = pcm->streams[i].substream; 534 534 if (substream) { 535 535 snd_dma_free_pages(&substream->dma_buffer);
+161 -12
sound/soc/qcom/qdsp6/q6asm-dai.c
··· 41 41 #define Q6ASM_DAI_TX 1 42 42 #define Q6ASM_DAI_RX 2 43 43 44 + #define ALAC_CH_LAYOUT_MONO ((101 << 16) | 1) 45 + #define ALAC_CH_LAYOUT_STEREO ((101 << 16) | 2) 46 + 44 47 enum stream_state { 45 48 Q6ASM_STREAM_IDLE = 0, 46 49 Q6ASM_STREAM_STOPPED, ··· 72 69 }; 73 70 74 71 struct q6asm_dai_data { 72 + struct snd_soc_dai_driver *dais; 73 + int num_dais; 75 74 long long int sid; 76 75 }; 77 76 ··· 255 250 256 251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 257 252 ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM, 258 - prtd->bits_per_sample); 253 + 0, prtd->bits_per_sample); 259 254 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 260 255 ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM, 261 256 prtd->bits_per_sample); ··· 333 328 { 334 329 struct snd_pcm_runtime *runtime = substream->runtime; 335 330 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; 336 - struct snd_soc_dai *cpu_dai = soc_prtd->cpu_dai; 331 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_prtd, 0); 337 332 struct q6asm_dai_rtd *prtd; 338 333 struct q6asm_dai_data *pdata; 339 334 struct device *dev = component->dev; ··· 545 540 struct snd_soc_pcm_runtime *rtd = stream->private_data; 546 541 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 547 542 struct snd_compr_runtime *runtime = stream->runtime; 548 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 543 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 549 544 struct q6asm_dai_data *pdata; 550 545 struct device *dev = c->dev; 551 546 struct q6asm_dai_rtd *prtd; ··· 632 627 int dir = stream->direction; 633 628 struct q6asm_dai_data *pdata; 634 629 struct q6asm_flac_cfg flac_cfg; 630 + struct q6asm_wma_cfg wma_cfg; 631 + struct q6asm_alac_cfg alac_cfg; 632 + struct q6asm_ape_cfg ape_cfg; 633 + unsigned int wma_v9 = 0; 635 634 struct device *dev = c->dev; 636 635 int ret; 637 636 union snd_codec_options *codec_options; 638 637 struct snd_dec_flac *flac; 638 + struct snd_dec_wma *wma; 639 + struct snd_dec_alac *alac; 640 + struct snd_dec_ape *ape; 639 641 640 642 codec_options = &(prtd->codec_param.codec.options); 641 643 ··· 664 652 prtd->bits_per_sample = 16; 665 653 if (dir == SND_COMPRESS_PLAYBACK) { 666 654 ret = q6asm_open_write(prtd->audio_client, params->codec.id, 667 - prtd->bits_per_sample); 655 + params->codec.profile, prtd->bits_per_sample); 668 656 669 657 if (ret < 0) { 670 658 dev_err(dev, "q6asm_open_write failed\n"); ··· 704 692 return -EIO; 705 693 } 706 694 break; 695 + 696 + case SND_AUDIOCODEC_WMA: 697 + wma = &codec_options->wma_d; 698 + 699 + memset(&wma_cfg, 0x0, sizeof(struct q6asm_wma_cfg)); 700 + 701 + wma_cfg.sample_rate = params->codec.sample_rate; 702 + wma_cfg.num_channels = params->codec.ch_in; 703 + wma_cfg.bytes_per_sec = params->codec.bit_rate / 8; 704 + wma_cfg.block_align = params->codec.align; 705 + wma_cfg.bits_per_sample = prtd->bits_per_sample; 706 + wma_cfg.enc_options = wma->encoder_option; 707 + wma_cfg.adv_enc_options = wma->adv_encoder_option; 708 + wma_cfg.adv_enc_options2 = wma->adv_encoder_option2; 709 + 710 + if (wma_cfg.num_channels == 1) 711 + wma_cfg.channel_mask = 4; /* Mono Center */ 712 + else if (wma_cfg.num_channels == 2) 713 + wma_cfg.channel_mask = 3; /* Stereo FL/FR */ 714 + else 715 + return -EINVAL; 716 + 717 + /* check the codec profile */ 718 + switch (params->codec.profile) { 719 + case SND_AUDIOPROFILE_WMA9: 720 + wma_cfg.fmtag = 0x161; 721 + wma_v9 = 1; 722 + break; 723 + 724 + case SND_AUDIOPROFILE_WMA10: 725 + wma_cfg.fmtag = 0x166; 726 + break; 727 + 728 + case SND_AUDIOPROFILE_WMA9_PRO: 729 + wma_cfg.fmtag = 0x162; 730 + break; 731 + 732 + case SND_AUDIOPROFILE_WMA9_LOSSLESS: 733 + wma_cfg.fmtag = 0x163; 734 + break; 735 + 736 + case SND_AUDIOPROFILE_WMA10_LOSSLESS: 737 + wma_cfg.fmtag = 0x167; 738 + break; 739 + 740 + default: 741 + dev_err(dev, "Unknown WMA profile:%x\n", 742 + params->codec.profile); 743 + return -EIO; 744 + } 745 + 746 + if (wma_v9) 747 + ret = q6asm_stream_media_format_block_wma_v9( 748 + prtd->audio_client, &wma_cfg); 749 + else 750 + ret = q6asm_stream_media_format_block_wma_v10( 751 + prtd->audio_client, &wma_cfg); 752 + if (ret < 0) { 753 + dev_err(dev, "WMA9 CMD failed:%d\n", ret); 754 + return -EIO; 755 + } 756 + break; 757 + 758 + case SND_AUDIOCODEC_ALAC: 759 + memset(&alac_cfg, 0x0, sizeof(alac_cfg)); 760 + alac = &codec_options->alac_d; 761 + 762 + alac_cfg.sample_rate = params->codec.sample_rate; 763 + alac_cfg.avg_bit_rate = params->codec.bit_rate; 764 + alac_cfg.bit_depth = prtd->bits_per_sample; 765 + alac_cfg.num_channels = params->codec.ch_in; 766 + 767 + alac_cfg.frame_length = alac->frame_length; 768 + alac_cfg.pb = alac->pb; 769 + alac_cfg.mb = alac->mb; 770 + alac_cfg.kb = alac->kb; 771 + alac_cfg.max_run = alac->max_run; 772 + alac_cfg.compatible_version = alac->compatible_version; 773 + alac_cfg.max_frame_bytes = alac->max_frame_bytes; 774 + 775 + switch (params->codec.ch_in) { 776 + case 1: 777 + alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_MONO; 778 + break; 779 + case 2: 780 + alac_cfg.channel_layout_tag = ALAC_CH_LAYOUT_STEREO; 781 + break; 782 + } 783 + ret = q6asm_stream_media_format_block_alac(prtd->audio_client, 784 + &alac_cfg); 785 + if (ret < 0) { 786 + dev_err(dev, "ALAC CMD Format block failed:%d\n", ret); 787 + return -EIO; 788 + } 789 + break; 790 + 791 + case SND_AUDIOCODEC_APE: 792 + memset(&ape_cfg, 0x0, sizeof(ape_cfg)); 793 + ape = &codec_options->ape_d; 794 + 795 + ape_cfg.sample_rate = params->codec.sample_rate; 796 + ape_cfg.num_channels = params->codec.ch_in; 797 + ape_cfg.bits_per_sample = prtd->bits_per_sample; 798 + 799 + ape_cfg.compatible_version = ape->compatible_version; 800 + ape_cfg.compression_level = ape->compression_level; 801 + ape_cfg.format_flags = ape->format_flags; 802 + ape_cfg.blocks_per_frame = ape->blocks_per_frame; 803 + ape_cfg.final_frame_blocks = ape->final_frame_blocks; 804 + ape_cfg.total_frames = ape->total_frames; 805 + ape_cfg.seek_table_present = ape->seek_table_present; 806 + 807 + ret = q6asm_stream_media_format_block_ape(prtd->audio_client, 808 + &ape_cfg); 809 + if (ret < 0) { 810 + dev_err(dev, "APE CMD Format block failed:%d\n", ret); 811 + return -EIO; 812 + } 813 + break; 814 + 707 815 default: 708 816 break; 709 817 } ··· 923 791 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; 924 792 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; 925 793 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; 926 - caps->num_codecs = 2; 794 + caps->num_codecs = 5; 927 795 caps->codecs[0] = SND_AUDIOCODEC_MP3; 928 796 caps->codecs[1] = SND_AUDIOCODEC_FLAC; 797 + caps->codecs[2] = SND_AUDIOCODEC_WMA; 798 + caps->codecs[3] = SND_AUDIOCODEC_ALAC; 799 + caps->codecs[4] = SND_AUDIOCODEC_APE; 929 800 930 801 return 0; 931 802 } ··· 1024 889 .compr_ops = &q6asm_dai_compr_ops, 1025 890 }; 1026 891 1027 - static struct snd_soc_dai_driver q6asm_fe_dais[] = { 892 + static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { 1028 893 Q6ASM_FEDAI_DRIVER(1), 1029 894 Q6ASM_FEDAI_DRIVER(2), 1030 895 Q6ASM_FEDAI_DRIVER(3), ··· 1038 903 static int of_q6asm_parse_dai_data(struct device *dev, 1039 904 struct q6asm_dai_data *pdata) 1040 905 { 1041 - static struct snd_soc_dai_driver *dai_drv; 906 + struct snd_soc_dai_driver *dai_drv; 1042 907 struct snd_soc_pcm_stream empty_stream; 1043 908 struct device_node *node; 1044 - int ret, id, dir; 909 + int ret, id, dir, idx = 0; 910 + 911 + 912 + pdata->num_dais = of_get_child_count(dev->of_node); 913 + if (!pdata->num_dais) { 914 + dev_err(dev, "No dais found in DT\n"); 915 + return -EINVAL; 916 + } 917 + 918 + pdata->dais = devm_kcalloc(dev, pdata->num_dais, sizeof(*dai_drv), 919 + GFP_KERNEL); 920 + if (!pdata->dais) 921 + return -ENOMEM; 1045 922 1046 923 memset(&empty_stream, 0, sizeof(empty_stream)); 1047 924 ··· 1064 917 continue; 1065 918 } 1066 919 1067 - dai_drv = &q6asm_fe_dais[id]; 920 + dai_drv = &pdata->dais[idx++]; 921 + *dai_drv = q6asm_fe_dais_template[id]; 1068 922 1069 923 ret = of_property_read_u32(node, "direction", &dir); 1070 924 if (ret) ··· 1103 955 1104 956 dev_set_drvdata(dev, pdata); 1105 957 1106 - of_q6asm_parse_dai_data(dev, pdata); 958 + rc = of_q6asm_parse_dai_data(dev, pdata); 959 + if (rc) 960 + return rc; 1107 961 1108 962 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 1109 - q6asm_fe_dais, 1110 - ARRAY_SIZE(q6asm_fe_dais)); 963 + pdata->dais, pdata->num_dais); 1111 964 } 1112 965 1113 966 static const struct of_device_id q6asm_dai_device_id[] = {
+242 -1
sound/soc/qcom/qdsp6/q6asm.c
··· 39 39 #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 40 40 #define ASM_MEDIA_FMT_MP3 0x00010BE9 41 41 #define ASM_MEDIA_FMT_FLAC 0x00010C16 42 + #define ASM_MEDIA_FMT_WMA_V9 0x00010DA8 43 + #define ASM_MEDIA_FMT_WMA_V10 0x00010DA7 42 44 #define ASM_DATA_CMD_WRITE_V2 0x00010DAB 43 45 #define ASM_DATA_CMD_READ_V2 0x00010DAC 44 46 #define ASM_SESSION_CMD_SUSPEND 0x00010DEC ··· 48 46 #define ASM_STREAM_CMD_OPEN_READ_V3 0x00010DB4 49 47 #define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A 50 48 #define ASM_STREAM_CMD_OPEN_READWRITE_V2 0x00010D8D 49 + #define ASM_MEDIA_FMT_ALAC 0x00012f31 50 + #define ASM_MEDIA_FMT_APE 0x00012f32 51 51 52 52 53 53 #define ASM_LEGACY_STREAM_SESSION 0 ··· 106 102 u32 max_frame_size; 107 103 u16 sample_size; 108 104 u16 reserved; 105 + } __packed; 106 + 107 + struct asm_wmastdv9_fmt_blk_v2 { 108 + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; 109 + u16 fmtag; 110 + u16 num_channels; 111 + u32 sample_rate; 112 + u32 bytes_per_sec; 113 + u16 blk_align; 114 + u16 bits_per_sample; 115 + u32 channel_mask; 116 + u16 enc_options; 117 + u16 reserved; 118 + } __packed; 119 + 120 + struct asm_wmaprov10_fmt_blk_v2 { 121 + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; 122 + u16 fmtag; 123 + u16 num_channels; 124 + u32 sample_rate; 125 + u32 bytes_per_sec; 126 + u16 blk_align; 127 + u16 bits_per_sample; 128 + u32 channel_mask; 129 + u16 enc_options; 130 + u16 advanced_enc_options1; 131 + u32 advanced_enc_options2; 132 + } __packed; 133 + 134 + struct asm_alac_fmt_blk_v2 { 135 + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; 136 + u32 frame_length; 137 + u8 compatible_version; 138 + u8 bit_depth; 139 + u8 pb; 140 + u8 mb; 141 + u8 kb; 142 + u8 num_channels; 143 + u16 max_run; 144 + u32 max_frame_bytes; 145 + u32 avg_bit_rate; 146 + u32 sample_rate; 147 + u32 channel_layout_tag; 148 + } __packed; 149 + 150 + struct asm_ape_fmt_blk_v2 { 151 + struct asm_data_cmd_media_fmt_update_v2 fmt_blk; 152 + u16 compatible_version; 153 + u16 compression_level; 154 + u32 format_flags; 155 + u32 blocks_per_frame; 156 + u32 final_frame_blocks; 157 + u32 total_frames; 158 + u16 bits_per_sample; 159 + u16 num_channels; 160 + u32 sample_rate; 161 + u32 seek_table_present; 109 162 } __packed; 110 163 111 164 struct asm_stream_cmd_set_encdec_param { ··· 919 858 * Return: Will be an negative value on error or zero on success 920 859 */ 921 860 int q6asm_open_write(struct audio_client *ac, uint32_t format, 922 - uint16_t bits_per_sample) 861 + u32 codec_profile, uint16_t bits_per_sample) 923 862 { 924 863 struct asm_stream_cmd_open_write_v3 *open; 925 864 struct apr_pkt *pkt; ··· 954 893 break; 955 894 case SND_AUDIOCODEC_FLAC: 956 895 open->dec_fmt_id = ASM_MEDIA_FMT_FLAC; 896 + break; 897 + case SND_AUDIOCODEC_WMA: 898 + switch (codec_profile) { 899 + case SND_AUDIOPROFILE_WMA9: 900 + open->dec_fmt_id = ASM_MEDIA_FMT_WMA_V9; 901 + break; 902 + case SND_AUDIOPROFILE_WMA10: 903 + case SND_AUDIOPROFILE_WMA9_PRO: 904 + case SND_AUDIOPROFILE_WMA9_LOSSLESS: 905 + case SND_AUDIOPROFILE_WMA10_LOSSLESS: 906 + open->dec_fmt_id = ASM_MEDIA_FMT_WMA_V10; 907 + break; 908 + default: 909 + dev_err(ac->dev, "Invalid codec profile 0x%x\n", 910 + codec_profile); 911 + rc = -EINVAL; 912 + goto err; 913 + } 914 + break; 915 + case SND_AUDIOCODEC_ALAC: 916 + open->dec_fmt_id = ASM_MEDIA_FMT_ALAC; 917 + break; 918 + case SND_AUDIOCODEC_APE: 919 + open->dec_fmt_id = ASM_MEDIA_FMT_APE; 957 920 break; 958 921 default: 959 922 dev_err(ac->dev, "Invalid format 0x%x\n", format); ··· 1160 1075 return rc; 1161 1076 } 1162 1077 EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_flac); 1078 + 1079 + int q6asm_stream_media_format_block_wma_v9(struct audio_client *ac, 1080 + struct q6asm_wma_cfg *cfg) 1081 + { 1082 + struct asm_wmastdv9_fmt_blk_v2 *fmt; 1083 + struct apr_pkt *pkt; 1084 + void *p; 1085 + int rc, pkt_size; 1086 + 1087 + pkt_size = APR_HDR_SIZE + sizeof(*fmt); 1088 + p = kzalloc(pkt_size, GFP_KERNEL); 1089 + if (!p) 1090 + return -ENOMEM; 1091 + 1092 + pkt = p; 1093 + fmt = p + APR_HDR_SIZE; 1094 + 1095 + q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id); 1096 + 1097 + pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; 1098 + fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk); 1099 + fmt->fmtag = cfg->fmtag; 1100 + fmt->num_channels = cfg->num_channels; 1101 + fmt->sample_rate = cfg->sample_rate; 1102 + fmt->bytes_per_sec = cfg->bytes_per_sec; 1103 + fmt->blk_align = cfg->block_align; 1104 + fmt->bits_per_sample = cfg->bits_per_sample; 1105 + fmt->channel_mask = cfg->channel_mask; 1106 + fmt->enc_options = cfg->enc_options; 1107 + fmt->reserved = 0; 1108 + 1109 + rc = q6asm_ac_send_cmd_sync(ac, pkt); 1110 + kfree(pkt); 1111 + 1112 + return rc; 1113 + } 1114 + EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_wma_v9); 1115 + 1116 + int q6asm_stream_media_format_block_wma_v10(struct audio_client *ac, 1117 + struct q6asm_wma_cfg *cfg) 1118 + { 1119 + struct asm_wmaprov10_fmt_blk_v2 *fmt; 1120 + struct apr_pkt *pkt; 1121 + void *p; 1122 + int rc, pkt_size; 1123 + 1124 + pkt_size = APR_HDR_SIZE + sizeof(*fmt); 1125 + p = kzalloc(pkt_size, GFP_KERNEL); 1126 + if (!p) 1127 + return -ENOMEM; 1128 + 1129 + pkt = p; 1130 + fmt = p + APR_HDR_SIZE; 1131 + 1132 + q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id); 1133 + 1134 + pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; 1135 + fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk); 1136 + fmt->fmtag = cfg->fmtag; 1137 + fmt->num_channels = cfg->num_channels; 1138 + fmt->sample_rate = cfg->sample_rate; 1139 + fmt->bytes_per_sec = cfg->bytes_per_sec; 1140 + fmt->blk_align = cfg->block_align; 1141 + fmt->bits_per_sample = cfg->bits_per_sample; 1142 + fmt->channel_mask = cfg->channel_mask; 1143 + fmt->enc_options = cfg->enc_options; 1144 + fmt->advanced_enc_options1 = cfg->adv_enc_options; 1145 + fmt->advanced_enc_options2 = cfg->adv_enc_options2; 1146 + 1147 + rc = q6asm_ac_send_cmd_sync(ac, pkt); 1148 + kfree(pkt); 1149 + 1150 + return rc; 1151 + } 1152 + EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_wma_v10); 1153 + 1154 + int q6asm_stream_media_format_block_alac(struct audio_client *ac, 1155 + struct q6asm_alac_cfg *cfg) 1156 + { 1157 + struct asm_alac_fmt_blk_v2 *fmt; 1158 + struct apr_pkt *pkt; 1159 + void *p; 1160 + int rc, pkt_size; 1161 + 1162 + pkt_size = APR_HDR_SIZE + sizeof(*fmt); 1163 + p = kzalloc(pkt_size, GFP_KERNEL); 1164 + if (!p) 1165 + return -ENOMEM; 1166 + 1167 + pkt = p; 1168 + fmt = p + APR_HDR_SIZE; 1169 + 1170 + q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id); 1171 + 1172 + pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; 1173 + fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk); 1174 + 1175 + fmt->frame_length = cfg->frame_length; 1176 + fmt->compatible_version = cfg->compatible_version; 1177 + fmt->bit_depth = cfg->bit_depth; 1178 + fmt->num_channels = cfg->num_channels; 1179 + fmt->max_run = cfg->max_run; 1180 + fmt->max_frame_bytes = cfg->max_frame_bytes; 1181 + fmt->avg_bit_rate = cfg->avg_bit_rate; 1182 + fmt->sample_rate = cfg->sample_rate; 1183 + fmt->channel_layout_tag = cfg->channel_layout_tag; 1184 + fmt->pb = cfg->pb; 1185 + fmt->mb = cfg->mb; 1186 + fmt->kb = cfg->kb; 1187 + 1188 + rc = q6asm_ac_send_cmd_sync(ac, pkt); 1189 + kfree(pkt); 1190 + 1191 + return rc; 1192 + } 1193 + EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_alac); 1194 + 1195 + int q6asm_stream_media_format_block_ape(struct audio_client *ac, 1196 + struct q6asm_ape_cfg *cfg) 1197 + { 1198 + struct asm_ape_fmt_blk_v2 *fmt; 1199 + struct apr_pkt *pkt; 1200 + void *p; 1201 + int rc, pkt_size; 1202 + 1203 + pkt_size = APR_HDR_SIZE + sizeof(*fmt); 1204 + p = kzalloc(pkt_size, GFP_KERNEL); 1205 + if (!p) 1206 + return -ENOMEM; 1207 + 1208 + pkt = p; 1209 + fmt = p + APR_HDR_SIZE; 1210 + 1211 + q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id); 1212 + 1213 + pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2; 1214 + fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk); 1215 + 1216 + fmt->compatible_version = cfg->compatible_version; 1217 + fmt->compression_level = cfg->compression_level; 1218 + fmt->format_flags = cfg->format_flags; 1219 + fmt->blocks_per_frame = cfg->blocks_per_frame; 1220 + fmt->final_frame_blocks = cfg->final_frame_blocks; 1221 + fmt->total_frames = cfg->total_frames; 1222 + fmt->bits_per_sample = cfg->bits_per_sample; 1223 + fmt->num_channels = cfg->num_channels; 1224 + fmt->sample_rate = cfg->sample_rate; 1225 + fmt->seek_table_present = cfg->seek_table_present; 1226 + 1227 + rc = q6asm_ac_send_cmd_sync(ac, pkt); 1228 + kfree(pkt); 1229 + 1230 + return rc; 1231 + } 1232 + EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_ape); 1233 + 1163 1234 /** 1164 1235 * q6asm_enc_cfg_blk_pcm_format_support() - setup pcm configuration for capture 1165 1236 *
+50 -1
sound/soc/qcom/qdsp6/q6asm.h
··· 45 45 u16 md5_sum; 46 46 }; 47 47 48 + struct q6asm_wma_cfg { 49 + u32 fmtag; 50 + u32 num_channels; 51 + u32 sample_rate; 52 + u32 bytes_per_sec; 53 + u32 block_align; 54 + u32 bits_per_sample; 55 + u32 channel_mask; 56 + u32 enc_options; 57 + u32 adv_enc_options; 58 + u32 adv_enc_options2; 59 + }; 60 + 61 + struct q6asm_alac_cfg { 62 + u32 frame_length; 63 + u8 compatible_version; 64 + u8 bit_depth; 65 + u8 pb; 66 + u8 mb; 67 + u8 kb; 68 + u8 num_channels; 69 + u16 max_run; 70 + u32 max_frame_bytes; 71 + u32 avg_bit_rate; 72 + u32 sample_rate; 73 + u32 channel_layout_tag; 74 + }; 75 + 76 + struct q6asm_ape_cfg { 77 + u16 compatible_version; 78 + u16 compression_level; 79 + u32 format_flags; 80 + u32 blocks_per_frame; 81 + u32 final_frame_blocks; 82 + u32 total_frames; 83 + u16 bits_per_sample; 84 + u16 num_channels; 85 + u32 sample_rate; 86 + u32 seek_table_present; 87 + }; 88 + 48 89 typedef void (*q6asm_cb) (uint32_t opcode, uint32_t token, 49 90 void *payload, void *priv); 50 91 struct audio_client; ··· 96 55 int q6asm_write_async(struct audio_client *ac, uint32_t len, uint32_t msw_ts, 97 56 uint32_t lsw_ts, uint32_t flags); 98 57 int q6asm_open_write(struct audio_client *ac, uint32_t format, 99 - uint16_t bits_per_sample); 58 + u32 codec_profile, uint16_t bits_per_sample); 100 59 101 60 int q6asm_open_read(struct audio_client *ac, uint32_t format, 102 61 uint16_t bits_per_sample); ··· 110 69 uint16_t bits_per_sample); 111 70 int q6asm_stream_media_format_block_flac(struct audio_client *ac, 112 71 struct q6asm_flac_cfg *cfg); 72 + int q6asm_stream_media_format_block_wma_v9(struct audio_client *ac, 73 + struct q6asm_wma_cfg *cfg); 74 + int q6asm_stream_media_format_block_wma_v10(struct audio_client *ac, 75 + struct q6asm_wma_cfg *cfg); 76 + int q6asm_stream_media_format_block_alac(struct audio_client *ac, 77 + struct q6asm_alac_cfg *cfg); 78 + int q6asm_stream_media_format_block_ape(struct audio_client *ac, 79 + struct q6asm_ape_cfg *cfg); 113 80 int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts, 114 81 uint32_t lsw_ts); 115 82 int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
+1 -20
sound/soc/qcom/qdsp6/q6routing.c
··· 918 918 {"MM_UL6", NULL, "MultiMedia6 Mixer"}, 919 919 {"MM_UL7", NULL, "MultiMedia7 Mixer"}, 920 920 {"MM_UL8", NULL, "MultiMedia8 Mixer"}, 921 - 922 - {"MM_DL1", NULL, "MultiMedia1 Playback" }, 923 - {"MM_DL2", NULL, "MultiMedia2 Playback" }, 924 - {"MM_DL3", NULL, "MultiMedia3 Playback" }, 925 - {"MM_DL4", NULL, "MultiMedia4 Playback" }, 926 - {"MM_DL5", NULL, "MultiMedia5 Playback" }, 927 - {"MM_DL6", NULL, "MultiMedia6 Playback" }, 928 - {"MM_DL7", NULL, "MultiMedia7 Playback" }, 929 - {"MM_DL8", NULL, "MultiMedia8 Playback" }, 930 - 931 - {"MultiMedia1 Capture", NULL, "MM_UL1"}, 932 - {"MultiMedia2 Capture", NULL, "MM_UL2"}, 933 - {"MultiMedia3 Capture", NULL, "MM_UL3"}, 934 - {"MultiMedia4 Capture", NULL, "MM_UL4"}, 935 - {"MultiMedia5 Capture", NULL, "MM_UL5"}, 936 - {"MultiMedia6 Capture", NULL, "MM_UL6"}, 937 - {"MultiMedia7 Capture", NULL, "MM_UL7"}, 938 - {"MultiMedia8 Capture", NULL, "MM_UL8"}, 939 - 940 921 }; 941 922 942 923 static int routing_hw_params(struct snd_soc_component *component, ··· 926 945 { 927 946 struct snd_soc_pcm_runtime *rtd = substream->private_data; 928 947 struct msm_routing_data *data = dev_get_drvdata(component->dev); 929 - unsigned int be_id = rtd->cpu_dai->id; 948 + unsigned int be_id = asoc_rtd_to_cpu(rtd, 0)->id; 930 949 struct session_data *session; 931 950 int path_type; 932 951
+85 -20
sound/soc/qcom/sdm845.c
··· 11 11 #include <sound/pcm_params.h> 12 12 #include <sound/jack.h> 13 13 #include <sound/soc.h> 14 + #include <linux/soundwire/sdw.h> 14 15 #include <uapi/linux/input-event-codes.h> 15 16 #include "common.h" 16 17 #include "qdsp6/q6afe.h" ··· 32 31 struct sdm845_snd_data { 33 32 struct snd_soc_jack jack; 34 33 bool jack_setup; 34 + bool stream_prepared[SLIM_MAX_RX_PORTS]; 35 35 struct snd_soc_card *card; 36 36 uint32_t pri_mi2s_clk_count; 37 37 uint32_t sec_mi2s_clk_count; 38 38 uint32_t quat_tdm_clk_count; 39 + struct sdw_stream_runtime *sruntime[SLIM_MAX_RX_PORTS]; 39 40 }; 40 41 41 42 static unsigned int tdm_slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28}; ··· 46 43 struct snd_pcm_hw_params *params) 47 44 { 48 45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 - struct snd_soc_dai_link *dai_link = rtd->dai_link; 50 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 46 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 47 + struct snd_soc_dai *codec_dai; 48 + struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 51 49 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; 50 + struct sdw_stream_runtime *sruntime; 52 51 u32 rx_ch_cnt = 0, tx_ch_cnt = 0; 53 52 int ret = 0, i; 54 53 55 - for (i = 0 ; i < dai_link->num_codecs; i++) { 56 - ret = snd_soc_dai_get_channel_map(rtd->codec_dais[i], 54 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 55 + sruntime = snd_soc_dai_get_sdw_stream(codec_dai, 56 + substream->stream); 57 + if (sruntime != ERR_PTR(-ENOTSUPP)) 58 + pdata->sruntime[cpu_dai->id] = sruntime; 59 + 60 + ret = snd_soc_dai_get_channel_map(codec_dai, 57 61 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); 58 62 59 63 if (ret != 0 && ret != -ENOTSUPP) { ··· 86 76 struct snd_pcm_hw_params *params) 87 77 { 88 78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 89 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 79 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 80 + struct snd_soc_dai *codec_dai; 90 81 int ret = 0, j; 91 82 int channels, slot_width; 92 83 ··· 136 125 } 137 126 } 138 127 139 - for (j = 0; j < rtd->num_codecs; j++) { 140 - struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 128 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 141 129 142 130 if (!strcmp(codec_dai->component->name_prefix, "Left")) { 143 131 ret = snd_soc_dai_set_tdm_slot( ··· 171 161 struct snd_pcm_hw_params *params) 172 162 { 173 163 struct snd_soc_pcm_runtime *rtd = substream->private_data; 174 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 175 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 164 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 165 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 176 166 int ret = 0; 177 167 178 168 switch (cpu_dai->id) { ··· 220 210 { 221 211 struct snd_soc_component *component; 222 212 struct snd_soc_card *card = rtd->card; 223 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 224 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 213 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 214 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 225 215 struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card); 226 216 struct snd_jack *jack; 227 - struct snd_soc_dai_link *dai_link = rtd->dai_link; 228 217 /* 229 218 * Codec SLIMBUS configuration 230 219 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 ··· 275 266 } 276 267 break; 277 268 case SLIMBUS_0_RX...SLIMBUS_6_TX: 278 - for (i = 0 ; i < dai_link->num_codecs; i++) { 279 - rval = snd_soc_dai_set_channel_map(rtd->codec_dais[i], 269 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 270 + rval = snd_soc_dai_set_channel_map(codec_dai, 280 271 ARRAY_SIZE(tx_ch), 281 272 tx_ch, 282 273 ARRAY_SIZE(rx_ch), ··· 284 275 if (rval != 0 && rval != -ENOTSUPP) 285 276 return rval; 286 277 287 - snd_soc_dai_set_sysclk(rtd->codec_dais[i], 0, 278 + snd_soc_dai_set_sysclk(codec_dai, 0, 288 279 WCD934X_DEFAULT_MCLK_RATE, 289 280 SNDRV_PCM_STREAM_PLAYBACK); 290 281 } ··· 304 295 struct snd_soc_pcm_runtime *rtd = substream->private_data; 305 296 struct snd_soc_card *card = rtd->card; 306 297 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 307 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 308 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 298 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 299 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 309 300 int j; 310 301 int ret; 311 302 ··· 354 345 355 346 codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B; 356 347 357 - for (j = 0; j < rtd->num_codecs; j++) { 358 - codec_dai = rtd->codec_dais[j]; 348 + for_each_rtd_codec_dais(rtd, j, codec_dai) { 359 349 360 350 if (!strcmp(codec_dai->component->name_prefix, 361 351 "Left")) { ··· 394 386 struct snd_soc_pcm_runtime *rtd = substream->private_data; 395 387 struct snd_soc_card *card = rtd->card; 396 388 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 397 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 389 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 398 390 399 391 switch (cpu_dai->id) { 400 392 case PRIMARY_MI2S_RX: ··· 435 427 } 436 428 } 437 429 430 + static int sdm845_snd_prepare(struct snd_pcm_substream *substream) 431 + { 432 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 433 + struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 434 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 435 + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 436 + int ret; 437 + 438 + if (!sruntime) 439 + return 0; 440 + 441 + if (data->stream_prepared[cpu_dai->id]) { 442 + sdw_disable_stream(sruntime); 443 + sdw_deprepare_stream(sruntime); 444 + data->stream_prepared[cpu_dai->id] = false; 445 + } 446 + 447 + ret = sdw_prepare_stream(sruntime); 448 + if (ret) 449 + return ret; 450 + 451 + /** 452 + * NOTE: there is a strict hw requirement about the ordering of port 453 + * enables and actual WSA881x PA enable. PA enable should only happen 454 + * after soundwire ports are enabled if not DC on the line is 455 + * accumulated resulting in Click/Pop Noise 456 + * PA enable/mute are handled as part of codec DAPM and digital mute. 457 + */ 458 + 459 + ret = sdw_enable_stream(sruntime); 460 + if (ret) { 461 + sdw_deprepare_stream(sruntime); 462 + return ret; 463 + } 464 + data->stream_prepared[cpu_dai->id] = true; 465 + 466 + return ret; 467 + } 468 + 469 + static int sdm845_snd_hw_free(struct snd_pcm_substream *substream) 470 + { 471 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 472 + struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 473 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 474 + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 475 + 476 + if (sruntime && data->stream_prepared[cpu_dai->id]) { 477 + sdw_disable_stream(sruntime); 478 + sdw_deprepare_stream(sruntime); 479 + data->stream_prepared[cpu_dai->id] = false; 480 + } 481 + 482 + return 0; 483 + } 484 + 438 485 static const struct snd_soc_ops sdm845_be_ops = { 439 486 .hw_params = sdm845_snd_hw_params, 487 + .hw_free = sdm845_snd_hw_free, 488 + .prepare = sdm845_snd_prepare, 440 489 .startup = sdm845_snd_startup, 441 490 .shutdown = sdm845_snd_shutdown, 442 491 };
+1 -1
sound/soc/qcom/storm.c
··· 39 39 */ 40 40 sysclk_freq = rate * bitwidth * 2 * STORM_SYSCLK_MULT; 41 41 42 - ret = snd_soc_dai_set_sysclk(soc_runtime->cpu_dai, 0, sysclk_freq, 0); 42 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(soc_runtime, 0), 0, sysclk_freq, 0); 43 43 if (ret) { 44 44 dev_err(card->dev, "error setting sysclk to %u: %d\n", 45 45 sysclk_freq, ret);
+2 -2
sound/soc/rockchip/rk3288_hdmi_analog.c
··· 67 67 { 68 68 int ret = 0; 69 69 struct snd_soc_pcm_runtime *rtd = substream->private_data; 70 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 71 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 70 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 71 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 72 72 int mclk; 73 73 74 74 switch (params_rate(params)) {
+8 -8
sound/soc/rockchip/rk3399_gru_sound.c
··· 57 57 58 58 mclk = params_rate(params) * SOUND_FS; 59 59 60 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); 60 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0); 61 61 if (ret) { 62 62 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", 63 63 __func__, mclk, ret); ··· 71 71 struct snd_pcm_hw_params *params) 72 72 { 73 73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 75 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 74 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 75 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 76 76 unsigned int mclk; 77 77 int ret; 78 78 ··· 103 103 struct snd_pcm_hw_params *params) 104 104 { 105 105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 106 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 107 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 106 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 107 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 108 108 int mclk, ret; 109 109 110 110 /* in bypass mode, the mclk has to be one of the frequencies below */ ··· 153 153 154 154 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) 155 155 { 156 - struct snd_soc_component *component = rtd->codec_dais[0]->component; 157 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 156 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 157 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 158 158 int ret; 159 159 160 160 /* We need default MCLK and PLL settings for the accessory detection */ ··· 206 206 207 207 mclk = params_rate(params) * SOUND_FS; 208 208 209 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); 209 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0, mclk, 0); 210 210 if (ret) { 211 211 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", 212 212 __func__, mclk, ret);
+3 -3
sound/soc/rockchip/rockchip_max98090.c
··· 146 146 { 147 147 int ret = 0; 148 148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 149 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 150 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 149 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 150 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 151 151 int mclk; 152 152 153 153 switch (params_rate(params)) { ··· 227 227 static int rk_hdmi_init(struct snd_soc_pcm_runtime *runtime) 228 228 { 229 229 struct snd_soc_card *card = runtime->card; 230 - struct snd_soc_component *component = runtime->codec_dai->component; 230 + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; 231 231 int ret; 232 232 233 233 /* enable jack detection */
+3 -3
sound/soc/rockchip/rockchip_rt5645.c
··· 56 56 { 57 57 int ret = 0; 58 58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 60 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 60 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 61 61 int mclk; 62 62 63 63 switch (params_rate(params)) { ··· 113 113 return ret; 114 114 } 115 115 116 - return rt5645_set_jack_detect(runtime->codec_dai->component, 116 + return rt5645_set_jack_detect(asoc_rtd_to_codec(runtime, 0)->component, 117 117 &headset_jack, 118 118 &headset_jack, 119 119 &headset_jack);
+2 -2
sound/soc/samsung/Kconfig
··· 151 151 152 152 config SND_SOC_BELLS 153 153 tristate "Audio support for Wolfson Bells" 154 - depends on MFD_ARIZONA && I2C && SPI_MASTER 154 + depends on MFD_ARIZONA && MFD_WM5102 && MFD_WM5110 && I2C && SPI_MASTER 155 155 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 156 156 select SND_SAMSUNG_I2S 157 157 select SND_SOC_WM5102 ··· 204 204 205 205 config SND_SOC_SAMSUNG_TM2_WM5110 206 206 tristate "SoC I2S Audio support for WM5110 on TM2 board" 207 - depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER 207 + depends on SND_SOC_SAMSUNG && MFD_ARIZONA && MFD_WM5110 && I2C && SPI_MASTER 208 208 depends on GPIOLIB || COMPILE_TEST 209 209 select SND_SOC_MAX98504 210 210 select SND_SOC_WM5110
+6 -4
sound/soc/samsung/arndale.c
··· 21 21 struct snd_pcm_hw_params *params) 22 22 { 23 23 struct snd_soc_pcm_runtime *rtd = substream->private_data; 24 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 25 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 24 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 25 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 26 26 int rfs, ret; 27 27 unsigned long rclk; 28 28 ··· 56 56 struct snd_pcm_hw_params *params) 57 57 { 58 58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 60 60 unsigned int rfs, rclk; 61 61 62 62 /* Ensure AIF1CLK is >= 3 MHz for optimal performance */ ··· 174 174 175 175 ret = devm_snd_soc_register_card(card->dev, card); 176 176 if (ret) { 177 - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); 177 + if (ret != -EPROBE_DEFER) 178 + dev_err(&pdev->dev, 179 + "snd_soc_register_card() failed: %d\n", ret); 178 180 goto err_put_of_nodes; 179 181 } 180 182 return 0;
+8 -8
sound/soc/samsung/bells.c
··· 60 60 int ret; 61 61 62 62 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_DSP_CODEC]); 63 - codec_dai = rtd->codec_dai; 63 + codec_dai = asoc_rtd_to_codec(rtd, 0); 64 64 component = codec_dai->component; 65 65 66 66 if (dapm->dev != codec_dai->dev) ··· 106 106 int ret; 107 107 108 108 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_DSP_CODEC]); 109 - codec_dai = rtd->codec_dai; 109 + codec_dai = asoc_rtd_to_codec(rtd, 0); 110 110 component = codec_dai->component; 111 111 112 112 if (dapm->dev != codec_dai->dev) ··· 152 152 int ret; 153 153 154 154 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_AP_DSP]); 155 - wm0010 = rtd->codec_dai->component; 155 + wm0010 = asoc_rtd_to_codec(rtd, 0)->component; 156 156 157 157 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_DSP_CODEC]); 158 - component = rtd->codec_dai->component; 159 - aif1_dai = rtd->codec_dai; 158 + component = asoc_rtd_to_codec(rtd, 0)->component; 159 + aif1_dai = asoc_rtd_to_codec(rtd, 0); 160 160 161 161 ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK, 162 162 ARIZONA_CLK_SRC_FLL1, ··· 195 195 } 196 196 197 197 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_CODEC_CP]); 198 - aif2_dai = rtd->cpu_dai; 198 + aif2_dai = asoc_rtd_to_cpu(rtd, 0); 199 199 200 200 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); 201 201 if (ret != 0) { ··· 207 207 return 0; 208 208 209 209 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_CODEC_SUB]); 210 - aif3_dai = rtd->cpu_dai; 211 - wm9081_dai = rtd->codec_dai; 210 + aif3_dai = asoc_rtd_to_cpu(rtd, 0); 211 + wm9081_dai = asoc_rtd_to_codec(rtd, 0); 212 212 213 213 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); 214 214 if (ret != 0) {
+1 -1
sound/soc/samsung/h1940_uda1380.c
··· 68 68 struct snd_pcm_hw_params *params) 69 69 { 70 70 struct snd_soc_pcm_runtime *rtd = substream->private_data; 71 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 71 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 72 72 int div; 73 73 int ret; 74 74 unsigned int rate = params_rate(params);
+1 -1
sound/soc/samsung/i2s.c
··· 932 932 struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai); 933 933 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 934 934 struct snd_soc_pcm_runtime *rtd = substream->private_data; 935 - struct i2s_dai *i2s = to_info(rtd->cpu_dai); 935 + struct i2s_dai *i2s = to_info(asoc_rtd_to_cpu(rtd, 0)); 936 936 unsigned long flags; 937 937 938 938 switch (cmd) {
+2 -2
sound/soc/samsung/jive_wm8750.c
··· 33 33 struct snd_pcm_hw_params *params) 34 34 { 35 35 struct snd_soc_pcm_runtime *rtd = substream->private_data; 36 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 37 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 36 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 37 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 38 38 struct s3c_i2sv2_rate_calc div; 39 39 unsigned int clk = 0; 40 40 int ret = 0;
+8 -8
sound/soc/samsung/littlemill.c
··· 23 23 int ret; 24 24 25 25 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 26 - aif1_dai = rtd->codec_dai; 26 + aif1_dai = asoc_rtd_to_codec(rtd, 0); 27 27 28 28 if (dapm->dev != aif1_dai->dev) 29 29 return 0; ··· 70 70 int ret; 71 71 72 72 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 73 - aif1_dai = rtd->codec_dai; 73 + aif1_dai = asoc_rtd_to_codec(rtd, 0); 74 74 75 75 if (dapm->dev != aif1_dai->dev) 76 76 return 0; ··· 105 105 struct snd_pcm_hw_params *params) 106 106 { 107 107 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 108 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 109 109 int ret; 110 110 111 111 sample_rate = params_rate(params); ··· 181 181 int ret; 182 182 183 183 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); 184 - aif2_dai = rtd->cpu_dai; 184 + aif2_dai = asoc_rtd_to_cpu(rtd, 0); 185 185 186 186 switch (event) { 187 187 case SND_SOC_DAPM_PRE_PMU: ··· 264 264 int ret; 265 265 266 266 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 267 - component = rtd->codec_dai->component; 268 - aif1_dai = rtd->codec_dai; 267 + component = asoc_rtd_to_codec(rtd, 0)->component; 268 + aif1_dai = asoc_rtd_to_codec(rtd, 0); 269 269 270 270 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); 271 - aif2_dai = rtd->cpu_dai; 271 + aif2_dai = asoc_rtd_to_cpu(rtd, 0); 272 272 273 273 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 274 274 32768, SND_SOC_CLOCK_IN); ··· 325 325 card->dev = &pdev->dev; 326 326 327 327 ret = devm_snd_soc_register_card(&pdev->dev, card); 328 - if (ret) 328 + if (ret && ret != -EPROBE_DEFER) 329 329 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 330 330 ret); 331 331
+3 -3
sound/soc/samsung/lowland.c
··· 32 32 33 33 static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd) 34 34 { 35 - struct snd_soc_component *component = rtd->codec_dai->component; 35 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 36 36 int ret; 37 37 38 38 ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK, ··· 65 65 66 66 static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd) 67 67 { 68 - struct snd_soc_component *component = rtd->codec_dai->component; 68 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 69 69 70 70 snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT"); 71 71 ··· 183 183 card->dev = &pdev->dev; 184 184 185 185 ret = devm_snd_soc_register_card(&pdev->dev, card); 186 - if (ret) 186 + if (ret && ret != -EPROBE_DEFER) 187 187 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 188 188 ret); 189 189
+5 -5
sound/soc/samsung/neo1973_wm8753.c
··· 26 26 struct snd_pcm_hw_params *params) 27 27 { 28 28 struct snd_soc_pcm_runtime *rtd = substream->private_data; 29 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 30 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 29 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 30 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 31 31 unsigned int pll_out = 0, bclk = 0; 32 32 int ret = 0; 33 33 unsigned long iis_clkrate; ··· 100 100 static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) 101 101 { 102 102 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 103 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 104 104 105 105 /* disable the PLL */ 106 106 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); ··· 118 118 struct snd_pcm_hw_params *params) 119 119 { 120 120 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 121 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 122 122 unsigned int pcmdiv = 0; 123 123 int ret = 0; 124 124 unsigned long iis_clkrate; ··· 155 155 static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) 156 156 { 157 157 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 158 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 159 159 160 160 /* disable the PLL */ 161 161 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
+4 -2
sound/soc/samsung/odroid.c
··· 98 98 return ret; 99 99 100 100 if (rtd->num_codecs > 1) { 101 - struct snd_soc_dai *codec_dai = rtd->codec_dais[1]; 101 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 1); 102 102 103 103 ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq, 104 104 SND_SOC_CLOCK_IN); ··· 311 311 312 312 ret = devm_snd_soc_register_card(dev, card); 313 313 if (ret < 0) { 314 - dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); 314 + if (ret != -EPROBE_DEFER) 315 + dev_err(dev, "snd_soc_register_card() failed: %d\n", 316 + ret); 315 317 goto err_put_clk_i2s; 316 318 } 317 319
+2 -2
sound/soc/samsung/pcm.c
··· 212 212 struct snd_soc_dai *dai) 213 213 { 214 214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 215 - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); 215 + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 216 216 unsigned long flags; 217 217 218 218 dev_dbg(pcm->dev, "Entered %s\n", __func__); ··· 256 256 struct snd_soc_dai *socdai) 257 257 { 258 258 struct snd_soc_pcm_runtime *rtd = substream->private_data; 259 - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); 259 + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 260 260 void __iomem *regs = pcm->regs; 261 261 struct clk *clk; 262 262 int sclk_div, sync_div;
+1 -1
sound/soc/samsung/rx1950_uda1380.c
··· 149 149 struct snd_pcm_hw_params *params) 150 150 { 151 151 struct snd_soc_pcm_runtime *rtd = substream->private_data; 152 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 152 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 153 153 int div; 154 154 int ret; 155 155 unsigned int rate = params_rate(params);
+1 -1
sound/soc/samsung/s3c-i2s-v2.c
··· 380 380 struct snd_soc_dai *dai) 381 381 { 382 382 struct snd_soc_pcm_runtime *rtd = substream->private_data; 383 - struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai); 383 + struct s3c_i2sv2_info *i2s = to_info(asoc_rtd_to_cpu(rtd, 0)); 384 384 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 385 385 unsigned long irqs; 386 386 int ret = 0;
+2 -2
sound/soc/samsung/s3c24xx_simtec.c
··· 160 160 struct snd_pcm_hw_params *params) 161 161 { 162 162 struct snd_soc_pcm_runtime *rtd = substream->private_data; 163 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 164 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 163 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 164 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 165 165 int ret; 166 166 167 167 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
+3 -3
sound/soc/samsung/s3c24xx_uda134x.c
··· 51 51 { 52 52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 53 struct s3c24xx_uda134x *priv = snd_soc_card_get_drvdata(rtd->card); 54 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 54 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 55 55 int ret = 0; 56 56 57 57 mutex_lock(&priv->clk_lock); ··· 119 119 struct snd_pcm_hw_params *params) 120 120 { 121 121 struct snd_soc_pcm_runtime *rtd = substream->private_data; 122 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 123 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 122 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 123 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 124 124 unsigned int clk = 0; 125 125 int ret = 0; 126 126 int clk_source, fs_mode;
+2 -2
sound/soc/samsung/smartq_wm8987.c
··· 25 25 struct snd_pcm_hw_params *params) 26 26 { 27 27 struct snd_soc_pcm_runtime *rtd = substream->private_data; 28 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 29 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 28 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 29 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 30 30 unsigned int clk = 0; 31 31 int ret; 32 32
+1 -1
sound/soc/samsung/smdk_spdif.c
··· 101 101 struct snd_pcm_hw_params *params) 102 102 { 103 103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 104 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 104 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 105 105 unsigned long pll_out, rclk_rate; 106 106 int ret, ratio; 107 107
+1 -1
sound/soc/samsung/smdk_wm8580.c
··· 23 23 struct snd_pcm_hw_params *params) 24 24 { 25 25 struct snd_soc_pcm_runtime *rtd = substream->private_data; 26 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 26 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 27 27 unsigned int pll_out; 28 28 int rfs, ret; 29 29
+2 -2
sound/soc/samsung/smdk_wm8994.c
··· 45 45 struct snd_pcm_hw_params *params) 46 46 { 47 47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 48 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 49 49 unsigned int pll_out; 50 50 int ret; 51 51 ··· 178 178 179 179 ret = devm_snd_soc_register_card(&pdev->dev, card); 180 180 181 - if (ret) 181 + if (ret && ret != -EPROBE_DEFER) 182 182 dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); 183 183 184 184 return ret;
+3 -3
sound/soc/samsung/smdk_wm8994pcm.c
··· 44 44 struct snd_pcm_hw_params *params) 45 45 { 46 46 struct snd_soc_pcm_runtime *rtd = substream->private_data; 47 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 47 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 48 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 49 49 unsigned long mclk_freq; 50 50 int rfs, ret; 51 51 ··· 118 118 119 119 smdk_pcm.dev = &pdev->dev; 120 120 ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm); 121 - if (ret) 121 + if (ret && ret != -EPROBE_DEFER) 122 122 dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); 123 123 124 124 return ret;
+5 -3
sound/soc/samsung/snow.c
··· 110 110 111 111 /* In the multi-codec case codec_dais 0 is MAX98095 and 1 is HDMI. */ 112 112 if (rtd->num_codecs > 1) 113 - codec_dai = rtd->codec_dais[0]; 113 + codec_dai = asoc_rtd_to_codec(rtd, 0); 114 114 else 115 - codec_dai = rtd->codec_dai; 115 + codec_dai = asoc_rtd_to_codec(rtd, 0); 116 116 117 117 /* Set the MCLK rate for the codec */ 118 118 return snd_soc_dai_set_sysclk(codec_dai, 0, ··· 216 216 217 217 ret = devm_snd_soc_register_card(dev, card); 218 218 if (ret) { 219 - dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 219 + if (ret != -EPROBE_DEFER) 220 + dev_err(&pdev->dev, 221 + "snd_soc_register_card failed (%d)\n", ret); 220 222 return ret; 221 223 } 222 224
+4 -4
sound/soc/samsung/spdif.c
··· 142 142 struct snd_soc_dai *dai) 143 143 { 144 144 struct snd_soc_pcm_runtime *rtd = substream->private_data; 145 - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); 145 + struct samsung_spdif_info *spdif = to_info(asoc_rtd_to_cpu(rtd, 0)); 146 146 unsigned long flags; 147 147 148 148 dev_dbg(spdif->dev, "Entered %s\n", __func__); ··· 178 178 struct snd_soc_dai *socdai) 179 179 { 180 180 struct snd_soc_pcm_runtime *rtd = substream->private_data; 181 - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); 181 + struct samsung_spdif_info *spdif = to_info(asoc_rtd_to_cpu(rtd, 0)); 182 182 void __iomem *regs = spdif->regs; 183 183 struct snd_dmaengine_dai_dma_data *dma_data; 184 184 u32 con, clkcon, cstas; ··· 194 194 return -EINVAL; 195 195 } 196 196 197 - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); 197 + snd_soc_dai_set_dma_data(asoc_rtd_to_cpu(rtd, 0), substream, dma_data); 198 198 199 199 spin_lock_irqsave(&spdif->lock, flags); 200 200 ··· 280 280 struct snd_soc_dai *dai) 281 281 { 282 282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 283 - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); 283 + struct samsung_spdif_info *spdif = to_info(asoc_rtd_to_cpu(rtd, 0)); 284 284 void __iomem *regs = spdif->regs; 285 285 u32 con, clkcon; 286 286
+5 -5
sound/soc/samsung/speyside.c
··· 25 25 int ret; 26 26 27 27 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); 28 - codec_dai = rtd->codec_dai; 28 + codec_dai = asoc_rtd_to_codec(rtd, 0); 29 29 30 30 if (dapm->dev != codec_dai->dev) 31 31 return 0; ··· 61 61 int ret; 62 62 63 63 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); 64 - codec_dai = rtd->codec_dai; 64 + codec_dai = asoc_rtd_to_codec(rtd, 0); 65 65 66 66 if (dapm->dev != codec_dai->dev) 67 67 return 0; ··· 131 131 132 132 static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd) 133 133 { 134 - struct snd_soc_dai *dai = rtd->codec_dai; 134 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 135 135 int ret; 136 136 137 137 ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0); ··· 143 143 144 144 static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) 145 145 { 146 - struct snd_soc_dai *dai = rtd->codec_dai; 146 + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); 147 147 struct snd_soc_component *component = dai->component; 148 148 int ret; 149 149 ··· 330 330 card->dev = &pdev->dev; 331 331 332 332 ret = devm_snd_soc_register_card(&pdev->dev, card); 333 - if (ret) 333 + if (ret && ret != -EPROBE_DEFER) 334 334 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 335 335 ret); 336 336
+10 -9
sound/soc/samsung/tm2_wm5110.c
··· 93 93 struct snd_pcm_hw_params *params) 94 94 { 95 95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 96 - struct snd_soc_component *component = rtd->codec_dai->component; 96 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 97 97 struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(rtd->card); 98 98 99 99 switch (params_rate(params)) { ··· 134 134 struct snd_pcm_hw_params *params) 135 135 { 136 136 struct snd_soc_pcm_runtime *rtd = substream->private_data; 137 - struct snd_soc_component *component = rtd->codec_dai->component; 137 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 138 138 unsigned int asyncclk_rate; 139 139 int ret; 140 140 ··· 188 188 static int tm2_aif2_hw_free(struct snd_pcm_substream *substream) 189 189 { 190 190 struct snd_soc_pcm_runtime *rtd = substream->private_data; 191 - struct snd_soc_component *component = rtd->codec_dai->component; 191 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 192 192 int ret; 193 193 194 194 /* disable FLL2 */ ··· 209 209 struct snd_pcm_hw_params *params) 210 210 { 211 211 struct snd_soc_pcm_runtime *rtd = substream->private_data; 212 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 212 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 213 213 unsigned int bfs; 214 214 int bitwidth, ret; 215 215 ··· 284 284 285 285 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 286 286 287 - if (dapm->dev != rtd->codec_dai->dev) 287 + if (dapm->dev != asoc_rtd_to_codec(rtd, 0)->dev) 288 288 return 0; 289 289 290 290 switch (level) { ··· 315 315 int ret; 316 316 317 317 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[TM2_DAI_AIF1]); 318 - aif1_dai = rtd->codec_dai; 319 - priv->component = rtd->codec_dai->component; 318 + aif1_dai = asoc_rtd_to_codec(rtd, 0); 319 + priv->component = asoc_rtd_to_codec(rtd, 0)->component; 320 320 321 321 ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0); 322 322 if (ret < 0) { ··· 325 325 } 326 326 327 327 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[TM2_DAI_AIF2]); 328 - aif2_dai = rtd->codec_dai; 328 + aif2_dai = asoc_rtd_to_codec(rtd, 0); 329 329 330 330 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); 331 331 if (ret < 0) { ··· 611 611 612 612 ret = devm_snd_soc_register_card(dev, card); 613 613 if (ret < 0) { 614 - dev_err(dev, "Failed to register card: %d\n", ret); 614 + if (ret != -EPROBE_DEFER) 615 + dev_err(dev, "Failed to register card: %d\n", ret); 615 616 goto dai_node_put; 616 617 } 617 618
+5 -5
sound/soc/samsung/tobermory.c
··· 23 23 int ret; 24 24 25 25 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 26 - codec_dai = rtd->codec_dai; 26 + codec_dai = asoc_rtd_to_codec(rtd, 0); 27 27 28 28 if (dapm->dev != codec_dai->dev) 29 29 return 0; ··· 66 66 int ret; 67 67 68 68 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 69 - codec_dai = rtd->codec_dai; 69 + codec_dai = asoc_rtd_to_codec(rtd, 0); 70 70 71 71 if (dapm->dev != codec_dai->dev) 72 72 return 0; ··· 181 181 int ret; 182 182 183 183 rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 184 - component = rtd->codec_dai->component; 185 - codec_dai = rtd->codec_dai; 184 + component = asoc_rtd_to_codec(rtd, 0)->component; 185 + codec_dai = asoc_rtd_to_codec(rtd, 0); 186 186 187 187 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK, 188 188 32768, SND_SOC_CLOCK_IN); ··· 229 229 card->dev = &pdev->dev; 230 230 231 231 ret = devm_snd_soc_register_card(&pdev->dev, card); 232 - if (ret) 232 + if (ret && ret != -EPROBE_DEFER) 233 233 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 234 234 ret); 235 235
+8 -8
sound/soc/sh/dma-sh7760.c
··· 119 119 struct snd_pcm_substream *substream) 120 120 { 121 121 struct snd_soc_pcm_runtime *rtd = substream->private_data; 122 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 122 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 123 123 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 124 124 int ret, dmairq; 125 125 ··· 132 132 ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); 133 133 if (unlikely(ret)) { 134 134 pr_debug("audio unit %d irqs already taken!\n", 135 - rtd->cpu_dai->id); 135 + asoc_rtd_to_cpu(rtd, 0)->id); 136 136 return -EBUSY; 137 137 } 138 138 (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); ··· 141 141 ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); 142 142 if (unlikely(ret)) { 143 143 pr_debug("audio unit %d irqs already taken!\n", 144 - rtd->cpu_dai->id); 144 + asoc_rtd_to_cpu(rtd, 0)->id); 145 145 return -EBUSY; 146 146 } 147 147 (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); ··· 153 153 struct snd_pcm_substream *substream) 154 154 { 155 155 struct snd_soc_pcm_runtime *rtd = substream->private_data; 156 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 156 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 157 157 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 158 158 int dmairq; 159 159 ··· 175 175 struct snd_pcm_hw_params *hw_params) 176 176 { 177 177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 178 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 178 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 179 179 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 180 180 int ret; 181 181 ··· 194 194 { 195 195 struct snd_pcm_runtime *runtime = substream->runtime; 196 196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 197 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 197 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 198 198 199 199 pr_debug("PCM data: addr 0x%08lx len %d\n", 200 200 (u32)runtime->dma_addr, runtime->dma_bytes); ··· 242 242 struct snd_pcm_substream *substream, int cmd) 243 243 { 244 244 struct snd_soc_pcm_runtime *rtd = substream->private_data; 245 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 245 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 246 246 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 247 247 248 248 switch (cmd) { ··· 270 270 { 271 271 struct snd_pcm_runtime *runtime = substream->runtime; 272 272 struct snd_soc_pcm_runtime *rtd = substream->private_data; 273 - struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 273 + struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; 274 274 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 275 275 unsigned long pos; 276 276
+2 -3
sound/soc/sh/fsi.c
··· 408 408 { 409 409 struct snd_soc_pcm_runtime *rtd = substream->private_data; 410 410 411 - return rtd->cpu_dai; 411 + return asoc_rtd_to_cpu(rtd, 0); 412 412 } 413 413 414 414 static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai) ··· 1938 1938 if (!master) 1939 1939 return -ENOMEM; 1940 1940 1941 - master->base = devm_ioremap(&pdev->dev, 1942 - res->start, resource_size(res)); 1941 + master->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 1943 1942 if (!master->base) { 1944 1943 dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n"); 1945 1944 return -ENXIO;
+3 -3
sound/soc/sh/migor.c
··· 46 46 struct snd_pcm_hw_params *params) 47 47 { 48 48 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 49 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 50 50 int ret; 51 51 unsigned int rate = params_rate(params); 52 52 ··· 67 67 clk_set_rate(&siumckb_clk, codec_freq); 68 68 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq); 69 69 70 - ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, SIU_CLKB_EXT, 70 + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), SIU_CLKB_EXT, 71 71 codec_freq / 2, SND_SOC_CLOCK_IN); 72 72 73 73 if (!ret) ··· 79 79 static int migor_hw_free(struct snd_pcm_substream *substream) 80 80 { 81 81 struct snd_soc_pcm_runtime *rtd = substream->private_data; 82 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 82 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 83 83 84 84 if (use_count) { 85 85 use_count--;
+1 -1
sound/soc/sh/rcar/core.c
··· 696 696 { 697 697 struct snd_soc_pcm_runtime *rtd = substream->private_data; 698 698 699 - return rtd->cpu_dai; 699 + return asoc_rtd_to_cpu(rtd, 0); 700 700 } 701 701 702 702 static
+3 -2
sound/soc/soc-compress.c
··· 810 810 int playback = 0, capture = 0; 811 811 int i; 812 812 813 - if (rtd->num_codecs > 1) { 813 + if (rtd->num_cpus > 1 || 814 + rtd->num_codecs > 1) { 814 815 dev_err(rtd->card->dev, 815 - "Compress ASoC: Multicodec not supported\n"); 816 + "Compress ASoC: Multi CPU/Codec not supported\n"); 816 817 return -EINVAL; 817 818 } 818 819
+156 -134
sound/soc/soc-core.c
··· 365 365 void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd) 366 366 { 367 367 struct snd_soc_dai *codec_dai = rtd->codec_dai; 368 + int playback = SNDRV_PCM_STREAM_PLAYBACK; 368 369 369 370 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 370 371 371 372 dev_dbg(rtd->dev, 372 373 "ASoC: pop wq checking: %s status: %s waiting: %s\n", 373 374 codec_dai->driver->playback.stream_name, 374 - codec_dai->playback_active ? "active" : "inactive", 375 + codec_dai->stream_active[playback] ? "active" : "inactive", 375 376 rtd->pop_wait ? "yes" : "no"); 376 377 377 378 /* are we waiting on this codec DAI stream */ 378 379 if (rtd->pop_wait == 1) { 379 380 rtd->pop_wait = 0; 380 - snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 381 + snd_soc_dapm_stream_event(rtd, playback, 381 382 SND_SOC_DAPM_STREAM_STOP); 382 383 } 383 384 ··· 432 431 struct snd_soc_component *component; 433 432 struct device *dev; 434 433 int ret; 434 + int stream; 435 435 436 436 /* 437 437 * for rtd->dev ··· 467 465 468 466 rtd->dev = dev; 469 467 INIT_LIST_HEAD(&rtd->list); 470 - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); 471 - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients); 472 - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients); 473 - INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); 468 + for_each_pcm_streams(stream) { 469 + INIT_LIST_HEAD(&rtd->dpcm[stream].be_clients); 470 + INIT_LIST_HEAD(&rtd->dpcm[stream].fe_clients); 471 + } 474 472 dev_set_drvdata(dev, rtd); 475 473 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 476 474 477 475 /* 478 - * for rtd->codec_dais 476 + * for rtd->dais 479 477 */ 480 - rtd->codec_dais = devm_kcalloc(dev, dai_link->num_codecs, 478 + rtd->dais = devm_kcalloc(dev, dai_link->num_cpus + dai_link->num_codecs, 481 479 sizeof(struct snd_soc_dai *), 482 480 GFP_KERNEL); 483 - if (!rtd->codec_dais) 481 + if (!rtd->dais) 484 482 goto free_rtd; 483 + 484 + /* 485 + * dais = [][][][][][][][][][][][][][][][][][] 486 + * ^cpu_dais ^codec_dais 487 + * |--- num_cpus ---|--- num_codecs --| 488 + */ 489 + rtd->cpu_dais = &rtd->dais[0]; 490 + rtd->codec_dais = &rtd->dais[dai_link->num_cpus]; 485 491 486 492 /* 487 493 * rtd remaining settings ··· 524 514 struct snd_soc_card *card = dev_get_drvdata(dev); 525 515 struct snd_soc_component *component; 526 516 struct snd_soc_pcm_runtime *rtd; 517 + int playback = SNDRV_PCM_STREAM_PLAYBACK; 527 518 int i; 528 519 529 520 /* If the card is not initialized yet there is nothing to do */ ··· 547 536 if (rtd->dai_link->ignore_suspend) 548 537 continue; 549 538 550 - for_each_rtd_codec_dai(rtd, i, dai) { 551 - if (dai->playback_active) 552 - snd_soc_dai_digital_mute(dai, 1, 553 - SNDRV_PCM_STREAM_PLAYBACK); 539 + for_each_rtd_codec_dais(rtd, i, dai) { 540 + if (dai->stream_active[playback]) 541 + snd_soc_dai_digital_mute(dai, 1, playback); 554 542 } 555 543 } 556 544 ··· 568 558 snd_soc_flush_all_delayed_work(card); 569 559 570 560 for_each_card_rtds(card, rtd) { 561 + int stream; 571 562 572 563 if (rtd->dai_link->ignore_suspend) 573 564 continue; 574 565 575 - snd_soc_dapm_stream_event(rtd, 576 - SNDRV_PCM_STREAM_PLAYBACK, 577 - SND_SOC_DAPM_STREAM_SUSPEND); 578 - 579 - snd_soc_dapm_stream_event(rtd, 580 - SNDRV_PCM_STREAM_CAPTURE, 581 - SND_SOC_DAPM_STREAM_SUSPEND); 566 + for_each_pcm_streams(stream) 567 + snd_soc_dapm_stream_event(rtd, stream, 568 + SND_SOC_DAPM_STREAM_SUSPEND); 582 569 } 583 570 584 571 /* Recheck all endpoints too, their state is affected by suspend */ ··· 671 664 } 672 665 673 666 for_each_card_rtds(card, rtd) { 667 + int stream; 674 668 675 669 if (rtd->dai_link->ignore_suspend) 676 670 continue; 677 671 678 - snd_soc_dapm_stream_event(rtd, 679 - SNDRV_PCM_STREAM_PLAYBACK, 680 - SND_SOC_DAPM_STREAM_RESUME); 681 - 682 - snd_soc_dapm_stream_event(rtd, 683 - SNDRV_PCM_STREAM_CAPTURE, 684 - SND_SOC_DAPM_STREAM_RESUME); 672 + for_each_pcm_streams(stream) 673 + snd_soc_dapm_stream_event(rtd, stream, 674 + SND_SOC_DAPM_STREAM_RESUME); 685 675 } 686 676 687 677 /* unmute any active DACs */ 688 678 for_each_card_rtds(card, rtd) { 689 679 struct snd_soc_dai *dai; 680 + int playback = SNDRV_PCM_STREAM_PLAYBACK; 690 681 691 682 if (rtd->dai_link->ignore_suspend) 692 683 continue; 693 684 694 - for_each_rtd_codec_dai(rtd, i, dai) { 695 - if (dai->playback_active) 696 - snd_soc_dai_digital_mute(dai, 0, 697 - SNDRV_PCM_STREAM_PLAYBACK); 685 + for_each_rtd_codec_dais(rtd, i, dai) { 686 + if (dai->stream_active[playback]) 687 + snd_soc_dai_digital_mute(dai, 0, playback); 698 688 } 699 689 } 700 690 ··· 841 837 struct snd_soc_dai_link *link) 842 838 { 843 839 int i; 844 - struct snd_soc_dai_link_component *codec, *platform; 840 + struct snd_soc_dai_link_component *cpu, *codec, *platform; 845 841 846 842 for_each_link_codecs(link, i, codec) { 847 843 /* ··· 890 886 return -EPROBE_DEFER; 891 887 } 892 888 893 - /* FIXME */ 894 - if (link->num_cpus > 1) { 895 - dev_err(card->dev, 896 - "ASoC: multi cpu is not yet supported %s\n", 897 - link->name); 898 - return -EINVAL; 899 - } 889 + for_each_link_cpus(link, i, cpu) { 890 + /* 891 + * CPU device may be specified by either name or OF node, but 892 + * can be left unspecified, and will be matched based on DAI 893 + * name alone.. 894 + */ 895 + if (cpu->name && cpu->of_node) { 896 + dev_err(card->dev, 897 + "ASoC: Neither/both cpu name/of_node are set for %s\n", 898 + link->name); 899 + return -EINVAL; 900 + } 900 901 901 - /* 902 - * CPU device may be specified by either name or OF node, but 903 - * can be left unspecified, and will be matched based on DAI 904 - * name alone.. 905 - */ 906 - if (link->cpus->name && link->cpus->of_node) { 907 - dev_err(card->dev, 908 - "ASoC: Neither/both cpu name/of_node are set for %s\n", 909 - link->name); 910 - return -EINVAL; 911 - } 902 + /* 903 + * Defer card registration if cpu dai component is not added to 904 + * component list. 905 + */ 906 + if ((cpu->of_node || cpu->name) && 907 + !soc_find_component(cpu)) 908 + return -EPROBE_DEFER; 912 909 913 - /* 914 - * Defer card registration if cpu dai component is not added to 915 - * component list. 916 - */ 917 - if ((link->cpus->of_node || link->cpus->name) && 918 - !soc_find_component(link->cpus)) 919 - return -EPROBE_DEFER; 920 - 921 - /* 922 - * At least one of CPU DAI name or CPU device name/node must be 923 - * specified 924 - */ 925 - if (!link->cpus->dai_name && 926 - !(link->cpus->name || link->cpus->of_node)) { 927 - dev_err(card->dev, 928 - "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", 929 - link->name); 930 - return -EINVAL; 910 + /* 911 + * At least one of CPU DAI name or CPU device name/node must be 912 + * specified 913 + */ 914 + if (!cpu->dai_name && 915 + !(cpu->name || cpu->of_node)) { 916 + dev_err(card->dev, 917 + "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", 918 + link->name); 919 + return -EINVAL; 920 + } 931 921 } 932 922 933 923 return 0; ··· 964 966 struct snd_soc_dai_link *dai_link) 965 967 { 966 968 struct snd_soc_pcm_runtime *rtd; 967 - struct snd_soc_dai_link_component *codec, *platform; 969 + struct snd_soc_dai_link_component *codec, *platform, *cpu; 968 970 struct snd_soc_component *component; 969 971 int i, ret; 970 972 ··· 989 991 if (!rtd) 990 992 return -ENOMEM; 991 993 992 - /* FIXME: we need multi CPU support in the future */ 993 - rtd->cpu_dai = snd_soc_find_dai(dai_link->cpus); 994 - if (!rtd->cpu_dai) { 995 - dev_info(card->dev, "ASoC: CPU DAI %s not registered\n", 996 - dai_link->cpus->dai_name); 997 - goto _err_defer; 994 + rtd->num_cpus = dai_link->num_cpus; 995 + for_each_link_cpus(dai_link, i, cpu) { 996 + rtd->cpu_dais[i] = snd_soc_find_dai(cpu); 997 + if (!rtd->cpu_dais[i]) { 998 + dev_info(card->dev, "ASoC: CPU DAI %s not registered\n", 999 + cpu->dai_name); 1000 + goto _err_defer; 1001 + } 1002 + snd_soc_rtd_add_component(rtd, rtd->cpu_dais[i]->component); 998 1003 } 999 - snd_soc_rtd_add_component(rtd, rtd->cpu_dai->component); 1004 + 1005 + /* Single cpu links expect cpu and cpu_dai in runtime data */ 1006 + rtd->cpu_dai = rtd->cpu_dais[0]; 1000 1007 1001 1008 /* Find CODEC from registered CODECs */ 1002 1009 rtd->num_codecs = dai_link->num_codecs; ··· 1037 1034 } 1038 1035 EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtime); 1039 1036 1040 - static int soc_dai_pcm_new(struct snd_soc_dai **dais, int num_dais, 1041 - struct snd_soc_pcm_runtime *rtd) 1037 + static int soc_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) 1042 1038 { 1039 + struct snd_soc_dai *dai; 1043 1040 int i, ret = 0; 1044 1041 1045 - for (i = 0; i < num_dais; ++i) { 1046 - struct snd_soc_dai_driver *drv = dais[i]->driver; 1042 + for_each_rtd_dais(rtd, i, dai) { 1043 + struct snd_soc_dai_driver *drv = dai->driver; 1047 1044 1048 1045 if (drv->pcm_new) 1049 - ret = drv->pcm_new(rtd, dais[i]); 1046 + ret = drv->pcm_new(rtd, dai); 1050 1047 if (ret < 0) { 1051 - dev_err(dais[i]->dev, 1048 + dev_err(dai->dev, 1052 1049 "ASoC: Failed to bind %s with pcm device\n", 1053 - dais[i]->name); 1050 + dai->name); 1054 1051 return ret; 1055 1052 } 1056 1053 } ··· 1121 1118 dai_link->stream_name, ret); 1122 1119 return ret; 1123 1120 } 1124 - ret = soc_dai_pcm_new(&cpu_dai, 1, rtd); 1125 - if (ret < 0) 1126 - return ret; 1127 - ret = soc_dai_pcm_new(rtd->codec_dais, 1128 - rtd->num_codecs, rtd); 1129 - return ret; 1121 + 1122 + return soc_dai_pcm_new(rtd); 1130 1123 } 1131 1124 1132 1125 static void soc_set_name_prefix(struct snd_soc_card *card, ··· 1255 1256 ret = snd_soc_dapm_add_routes(dapm, 1256 1257 component->driver->dapm_routes, 1257 1258 component->driver->num_dapm_routes); 1258 - if (ret < 0) 1259 - goto err_probe; 1259 + if (ret < 0) { 1260 + if (card->disable_route_checks) { 1261 + dev_info(card->dev, 1262 + "%s: disable_route_checks set, ignoring errors on add_routes\n", 1263 + __func__); 1264 + } else { 1265 + dev_err(card->dev, 1266 + "%s: snd_soc_dapm_add_routes failed: %d\n", 1267 + __func__, ret); 1268 + goto err_probe; 1269 + } 1270 + } 1260 1271 1261 1272 /* see for_each_card_components */ 1262 1273 list_add(&component->card_list, &card->component_dev_list); ··· 1318 1309 static void soc_remove_link_dais(struct snd_soc_card *card) 1319 1310 { 1320 1311 int i; 1321 - struct snd_soc_dai *codec_dai; 1312 + struct snd_soc_dai *dai; 1322 1313 struct snd_soc_pcm_runtime *rtd; 1323 1314 int order; 1324 1315 1325 1316 for_each_comp_order(order) { 1326 1317 for_each_card_rtds(card, rtd) { 1327 - /* remove the CODEC DAI */ 1328 - for_each_rtd_codec_dai(rtd, i, codec_dai) 1329 - soc_remove_dai(codec_dai, order); 1330 - 1331 - soc_remove_dai(rtd->cpu_dai, order); 1318 + /* remove DAIs */ 1319 + for_each_rtd_dais(rtd, i, dai) 1320 + soc_remove_dai(dai, order); 1332 1321 } 1333 1322 } 1334 1323 } 1335 1324 1336 1325 static int soc_probe_link_dais(struct snd_soc_card *card) 1337 1326 { 1338 - struct snd_soc_dai *codec_dai; 1327 + struct snd_soc_dai *dai; 1339 1328 struct snd_soc_pcm_runtime *rtd; 1340 1329 int i, order, ret; 1341 1330 ··· 1344 1337 "ASoC: probe %s dai link %d late %d\n", 1345 1338 card->name, rtd->num, order); 1346 1339 1347 - ret = soc_probe_dai(rtd->cpu_dai, order); 1348 - if (ret) 1349 - return ret; 1350 - 1351 - /* probe the CODEC DAI */ 1352 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1353 - ret = soc_probe_dai(codec_dai, order); 1340 + /* probe the CPU DAI */ 1341 + for_each_rtd_dais(rtd, i, dai) { 1342 + ret = soc_probe_dai(dai, order); 1354 1343 if (ret) 1355 1344 return ret; 1356 1345 } ··· 1474 1471 int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, 1475 1472 unsigned int dai_fmt) 1476 1473 { 1477 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1474 + struct snd_soc_dai *cpu_dai; 1478 1475 struct snd_soc_dai *codec_dai; 1476 + unsigned int inv_dai_fmt; 1479 1477 unsigned int i; 1480 1478 int ret; 1481 1479 1482 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1480 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 1483 1481 ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt); 1484 1482 if (ret != 0 && ret != -ENOTSUPP) { 1485 1483 dev_warn(codec_dai->dev, ··· 1493 1489 * Flip the polarity for the "CPU" end of a CODEC<->CODEC link 1494 1490 * the component which has non_legacy_dai_naming is Codec 1495 1491 */ 1496 - if (cpu_dai->component->driver->non_legacy_dai_naming) { 1497 - unsigned int inv_dai_fmt; 1498 - 1499 - inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; 1500 - switch (dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1501 - case SND_SOC_DAIFMT_CBM_CFM: 1502 - inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; 1503 - break; 1504 - case SND_SOC_DAIFMT_CBM_CFS: 1505 - inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFM; 1506 - break; 1507 - case SND_SOC_DAIFMT_CBS_CFM: 1508 - inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; 1509 - break; 1510 - case SND_SOC_DAIFMT_CBS_CFS: 1511 - inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 1512 - break; 1513 - } 1514 - 1515 - dai_fmt = inv_dai_fmt; 1492 + inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; 1493 + switch (dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1494 + case SND_SOC_DAIFMT_CBM_CFM: 1495 + inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; 1496 + break; 1497 + case SND_SOC_DAIFMT_CBM_CFS: 1498 + inv_dai_fmt |= SND_SOC_DAIFMT_CBS_CFM; 1499 + break; 1500 + case SND_SOC_DAIFMT_CBS_CFM: 1501 + inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; 1502 + break; 1503 + case SND_SOC_DAIFMT_CBS_CFS: 1504 + inv_dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 1505 + break; 1516 1506 } 1507 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1508 + unsigned int fmt = dai_fmt; 1517 1509 1518 - ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt); 1519 - if (ret != 0 && ret != -ENOTSUPP) { 1520 - dev_warn(cpu_dai->dev, 1521 - "ASoC: Failed to set DAI format: %d\n", ret); 1522 - return ret; 1510 + if (cpu_dai->component->driver->non_legacy_dai_naming) 1511 + fmt = inv_dai_fmt; 1512 + 1513 + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 1514 + if (ret != 0 && ret != -ENOTSUPP) { 1515 + dev_warn(cpu_dai->dev, 1516 + "ASoC: Failed to set DAI format: %d\n", ret); 1517 + return ret; 1518 + } 1523 1519 } 1524 1520 1525 1521 return 0; ··· 1942 1938 1943 1939 ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1944 1940 card->num_dapm_routes); 1945 - if (ret < 0) 1946 - goto probe_end; 1941 + if (ret < 0) { 1942 + if (card->disable_route_checks) { 1943 + dev_info(card->dev, 1944 + "%s: disable_route_checks set, ignoring errors on add_routes\n", 1945 + __func__); 1946 + } else { 1947 + dev_err(card->dev, 1948 + "%s: snd_soc_dapm_add_routes failed: %d\n", 1949 + __func__, ret); 1950 + goto probe_end; 1951 + } 1952 + } 1947 1953 1948 1954 ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 1949 1955 card->num_of_dapm_routes); ··· 3116 3102 *dai_name = dai->driver->name; 3117 3103 if (!*dai_name) 3118 3104 *dai_name = pos->name; 3105 + } else if (ret) { 3106 + /* 3107 + * if another error than ENOTSUPP is returned go on and 3108 + * check if another component is provided with the same 3109 + * node. This may happen if a device provides several 3110 + * components 3111 + */ 3112 + continue; 3119 3113 } 3120 3114 3121 3115 break;
+10 -8
sound/soc/soc-dai.c
··· 295 295 { 296 296 int ret = 0; 297 297 298 - if (dai->driver->ops->startup) 298 + if (!dai->started && 299 + dai->driver->ops->startup) 299 300 ret = dai->driver->ops->startup(substream, dai); 301 + 302 + if (ret == 0) 303 + dai->started = 1; 300 304 301 305 return ret; 302 306 } ··· 308 304 void snd_soc_dai_shutdown(struct snd_soc_dai *dai, 309 305 struct snd_pcm_substream *substream) 310 306 { 311 - if (dai->driver->ops->shutdown) 307 + if (dai->started && 308 + dai->driver->ops->shutdown) 312 309 dai->driver->ops->shutdown(substream, dai); 310 + 311 + dai->started = 0; 313 312 } 314 313 315 314 int snd_soc_dai_prepare(struct snd_soc_dai *dai, ··· 390 383 */ 391 384 bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir) 392 385 { 393 - struct snd_soc_pcm_stream *stream; 394 - 395 - if (dir == SNDRV_PCM_STREAM_PLAYBACK) 396 - stream = &dai->driver->playback; 397 - else 398 - stream = &dai->driver->capture; 386 + struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, dir); 399 387 400 388 /* If the codec specifies any channels at all, it supports the stream */ 401 389 return stream->channels_min;
+117 -97
sound/soc/soc-dapm.c
··· 302 302 303 303 mutex_lock(&card->dapm_mutex); 304 304 305 - list_for_each_entry(w, &card->widgets, list) { 305 + for_each_card_widgets(card, w) { 306 306 if (w->is_ep) { 307 307 dapm_mark_dirty(w, "Rechecking endpoints"); 308 308 if (w->is_ep & SND_SOC_DAPM_EP_SINK) ··· 589 589 590 590 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 591 591 592 - list_for_each_entry(w, &card->widgets, list) { 592 + for_each_card_widgets(card, w) { 593 593 w->new_power = w->power; 594 594 w->power_checked = false; 595 595 } ··· 833 833 834 834 *kcontrol = NULL; 835 835 836 - list_for_each_entry(w, &dapm->card->widgets, list) { 836 + for_each_card_widgets(dapm->card, w) { 837 837 if (w == kcontrolw || w->dapm != kcontrolw->dapm) 838 838 continue; 839 839 for (i = 0; i < w->num_kcontrols; i++) { ··· 1105 1105 } 1106 1106 } 1107 1107 1108 + static void dapm_widget_list_free(struct snd_soc_dapm_widget_list **list) 1109 + { 1110 + kfree(*list); 1111 + } 1112 + 1108 1113 static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list, 1109 1114 struct list_head *widgets) 1110 1115 { ··· 1313 1308 mutex_unlock(&card->dapm_mutex); 1314 1309 1315 1310 return paths; 1311 + } 1312 + 1313 + void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list) 1314 + { 1315 + dapm_widget_list_free(list); 1316 1316 } 1317 1317 1318 1318 /* ··· 1716 1706 i, cur_subseq); 1717 1707 } 1718 1708 1719 - list_for_each_entry(d, &card->dapm_list, list) { 1709 + for_each_card_dapms(card, d) 1720 1710 soc_dapm_async_complete(d); 1721 - } 1722 1711 } 1723 1712 1724 1713 static void dapm_widget_update(struct snd_soc_card *card) ··· 1733 1724 1734 1725 wlist = dapm_kcontrol_get_wlist(update->kcontrol); 1735 1726 1736 - for (wi = 0; wi < wlist->num_widgets; wi++) { 1737 - w = wlist->widgets[wi]; 1738 - 1727 + for_each_dapm_widgets(wlist, wi, w) { 1739 1728 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) { 1740 1729 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); 1741 1730 if (ret != 0) ··· 1760 1753 w->name, ret); 1761 1754 } 1762 1755 1763 - for (wi = 0; wi < wlist->num_widgets; wi++) { 1764 - w = wlist->widgets[wi]; 1765 - 1756 + for_each_dapm_widgets(wlist, wi, w) { 1766 1757 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) { 1767 1758 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); 1768 1759 if (ret != 0) ··· 1948 1943 1949 1944 trace_snd_soc_dapm_start(card); 1950 1945 1951 - list_for_each_entry(d, &card->dapm_list, list) { 1946 + for_each_card_dapms(card, d) { 1952 1947 if (dapm_idle_bias_off(d)) 1953 1948 d->target_bias_level = SND_SOC_BIAS_OFF; 1954 1949 else ··· 1967 1962 dapm_power_one_widget(w, &up_list, &down_list); 1968 1963 } 1969 1964 1970 - list_for_each_entry(w, &card->widgets, list) { 1965 + for_each_card_widgets(card, w) { 1971 1966 switch (w->id) { 1972 1967 case snd_soc_dapm_pre: 1973 1968 case snd_soc_dapm_post: ··· 2012 2007 * they're not ground referenced. 2013 2008 */ 2014 2009 bias = SND_SOC_BIAS_OFF; 2015 - list_for_each_entry(d, &card->dapm_list, list) 2010 + for_each_card_dapms(card, d) 2016 2011 if (d->target_bias_level > bias) 2017 2012 bias = d->target_bias_level; 2018 - list_for_each_entry(d, &card->dapm_list, list) 2013 + for_each_card_dapms(card, d) 2019 2014 if (!dapm_idle_bias_off(d)) 2020 2015 d->target_bias_level = bias; 2021 2016 ··· 2024 2019 /* Run card bias changes at first */ 2025 2020 dapm_pre_sequence_async(&card->dapm, 0); 2026 2021 /* Run other bias changes in parallel */ 2027 - list_for_each_entry(d, &card->dapm_list, list) { 2022 + for_each_card_dapms(card, d) { 2028 2023 if (d != &card->dapm && d->bias_level != d->target_bias_level) 2029 2024 async_schedule_domain(dapm_pre_sequence_async, d, 2030 2025 &async_domain); ··· 2048 2043 dapm_seq_run(card, &up_list, event, true); 2049 2044 2050 2045 /* Run all the bias changes in parallel */ 2051 - list_for_each_entry(d, &card->dapm_list, list) { 2046 + for_each_card_dapms(card, d) { 2052 2047 if (d != &card->dapm && d->bias_level != d->target_bias_level) 2053 2048 async_schedule_domain(dapm_post_sequence_async, d, 2054 2049 &async_domain); ··· 2058 2053 dapm_post_sequence_async(&card->dapm, 0); 2059 2054 2060 2055 /* do we need to notify any clients that DAPM event is complete */ 2061 - list_for_each_entry(d, &card->dapm_list, list) { 2056 + for_each_card_dapms(card, d) { 2062 2057 if (!d->component) 2063 2058 continue; 2064 2059 ··· 2291 2286 card->update = NULL; 2292 2287 mutex_unlock(&card->dapm_mutex); 2293 2288 if (ret > 0) 2294 - soc_dpcm_runtime_update(card); 2289 + snd_soc_dpcm_runtime_update(card); 2295 2290 return ret; 2296 2291 } 2297 2292 EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); ··· 2356 2351 card->update = NULL; 2357 2352 mutex_unlock(&card->dapm_mutex); 2358 2353 if (ret > 0) 2359 - soc_dpcm_runtime_update(card); 2354 + snd_soc_dpcm_runtime_update(card); 2360 2355 return ret; 2361 2356 } 2362 2357 EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); ··· 2376 2371 if (!cmpnt->card) 2377 2372 return 0; 2378 2373 2379 - list_for_each_entry(w, &cmpnt->card->widgets, list) { 2374 + for_each_card_widgets(cmpnt->card, w) { 2380 2375 if (w->dapm != dapm) 2381 2376 continue; 2382 2377 ··· 2436 2431 2437 2432 mutex_lock(&rtd->card->dapm_mutex); 2438 2433 2439 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 2434 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 2440 2435 struct snd_soc_component *cmpnt = codec_dai->component; 2441 2436 2442 2437 count += dapm_widget_show_component(cmpnt, buf + count); ··· 2496 2491 { 2497 2492 struct snd_soc_dapm_widget *w, *next_w; 2498 2493 2499 - list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) { 2494 + for_each_card_widgets_safe(dapm->card, w, next_w) { 2500 2495 if (w->dapm != dapm) 2501 2496 continue; 2502 2497 snd_soc_dapm_free_widget(w); ··· 2511 2506 struct snd_soc_dapm_widget *w; 2512 2507 struct snd_soc_dapm_widget *fallback = NULL; 2513 2508 2514 - list_for_each_entry(w, &dapm->card->widgets, list) { 2509 + for_each_card_widgets(dapm->card, w) { 2515 2510 if (!strcmp(w->name, pin)) { 2516 2511 if (w->dapm == dapm) 2517 2512 return w; ··· 2629 2624 struct snd_soc_dapm_widget *w; 2630 2625 int ret; 2631 2626 2632 - if (dir == SNDRV_PCM_STREAM_PLAYBACK) 2633 - w = dai->playback_widget; 2634 - else 2635 - w = dai->capture_widget; 2627 + w = snd_soc_dai_get_widget(dai, dir); 2636 2628 2637 2629 if (!w) 2638 2630 return 0; ··· 2910 2908 * find src and dest widgets over all widgets but favor a widget from 2911 2909 * current DAPM context 2912 2910 */ 2913 - list_for_each_entry(w, &dapm->card->widgets, list) { 2911 + for_each_card_widgets(dapm->card, w) { 2914 2912 if (!wsink && !(strcmp(w->name, sink))) { 2915 2913 wtsink = w; 2916 2914 if (w->dapm == dapm) { ··· 3189 3187 3190 3188 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 3191 3189 3192 - list_for_each_entry(w, &card->widgets, list) 3190 + for_each_card_widgets(card, w) 3193 3191 { 3194 3192 if (w->new) 3195 3193 continue; ··· 3396 3394 mutex_unlock(&card->dapm_mutex); 3397 3395 3398 3396 if (ret > 0) 3399 - soc_dpcm_runtime_update(card); 3397 + snd_soc_dpcm_runtime_update(card); 3400 3398 3401 3399 return change; 3402 3400 } ··· 3501 3499 mutex_unlock(&card->dapm_mutex); 3502 3500 3503 3501 if (ret > 0) 3504 - soc_dpcm_runtime_update(card); 3502 + snd_soc_dpcm_runtime_update(card); 3505 3503 3506 3504 return change; 3507 3505 } ··· 3606 3604 ret = PTR_ERR(w->pinctrl); 3607 3605 goto request_failed; 3608 3606 } 3607 + 3608 + /* set to sleep_state when initializing */ 3609 + dapm_pinctrl_event(w, NULL, SND_SOC_DAPM_POST_PMD); 3609 3610 break; 3610 3611 case snd_soc_dapm_clock_supply: 3611 3612 w->clk = devm_clk_get(dapm->dev, w->name); ··· 3703 3698 w->dapm = dapm; 3704 3699 INIT_LIST_HEAD(&w->list); 3705 3700 INIT_LIST_HEAD(&w->dirty); 3701 + /* see for_each_card_widgets */ 3706 3702 list_add_tail(&w->list, &dapm->card->widgets); 3707 3703 3708 3704 snd_soc_dapm_for_each_direction(dir) { ··· 4228 4222 struct snd_soc_dai *dai; 4229 4223 4230 4224 /* For each DAI widget... */ 4231 - list_for_each_entry(dai_w, &card->widgets, list) { 4225 + for_each_card_widgets(card, dai_w) { 4232 4226 switch (dai_w->id) { 4233 4227 case snd_soc_dapm_dai_in: 4234 4228 case snd_soc_dapm_dai_out: ··· 4247 4241 dai = dai_w->priv; 4248 4242 4249 4243 /* ...find all widgets with the same stream and link them */ 4250 - list_for_each_entry(w, &card->widgets, list) { 4244 + for_each_card_widgets(card, w) { 4251 4245 if (w->dapm != dai_w->dapm) 4252 4246 continue; 4253 4247 ··· 4277 4271 return 0; 4278 4272 } 4279 4273 4280 - static void dapm_connect_dai_link_widgets(struct snd_soc_card *card, 4281 - struct snd_soc_pcm_runtime *rtd) 4274 + static void dapm_add_valid_dai_widget(struct snd_soc_card *card, 4275 + struct snd_soc_pcm_runtime *rtd, 4276 + struct snd_soc_dai *codec_dai, 4277 + struct snd_soc_dai *cpu_dai) 4282 4278 { 4283 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 4284 - struct snd_soc_dai *codec_dai; 4285 4279 struct snd_soc_dapm_widget *playback = NULL, *capture = NULL; 4286 4280 struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu; 4287 4281 struct snd_pcm_substream *substream; 4288 4282 struct snd_pcm_str *streams = rtd->pcm->streams; 4289 - int i; 4290 4283 4291 4284 if (rtd->dai_link->params) { 4292 4285 playback_cpu = cpu_dai->capture_widget; ··· 4297 4292 capture_cpu = capture; 4298 4293 } 4299 4294 4300 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 4301 - /* connect BE DAI playback if widgets are valid */ 4302 - codec = codec_dai->playback_widget; 4295 + /* connect BE DAI playback if widgets are valid */ 4296 + codec = codec_dai->playback_widget; 4303 4297 4304 - if (playback_cpu && codec) { 4305 - if (!playback) { 4306 - substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 4307 - playback = snd_soc_dapm_new_dai(card, substream, 4308 - "playback"); 4309 - if (IS_ERR(playback)) { 4310 - dev_err(rtd->dev, 4311 - "ASoC: Failed to create DAI %s: %ld\n", 4312 - codec_dai->name, 4313 - PTR_ERR(playback)); 4314 - continue; 4315 - } 4316 - 4317 - snd_soc_dapm_add_path(&card->dapm, playback_cpu, 4318 - playback, NULL, NULL); 4298 + if (playback_cpu && codec) { 4299 + if (!playback) { 4300 + substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 4301 + playback = snd_soc_dapm_new_dai(card, substream, 4302 + "playback"); 4303 + if (IS_ERR(playback)) { 4304 + dev_err(rtd->dev, 4305 + "ASoC: Failed to create DAI %s: %ld\n", 4306 + codec_dai->name, 4307 + PTR_ERR(playback)); 4308 + goto capture; 4319 4309 } 4320 4310 4321 - dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 4322 - cpu_dai->component->name, playback_cpu->name, 4323 - codec_dai->component->name, codec->name); 4324 - 4325 - snd_soc_dapm_add_path(&card->dapm, playback, codec, 4326 - NULL, NULL); 4311 + snd_soc_dapm_add_path(&card->dapm, playback_cpu, 4312 + playback, NULL, NULL); 4327 4313 } 4314 + 4315 + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 4316 + cpu_dai->component->name, playback_cpu->name, 4317 + codec_dai->component->name, codec->name); 4318 + 4319 + snd_soc_dapm_add_path(&card->dapm, playback, codec, 4320 + NULL, NULL); 4328 4321 } 4329 4322 4330 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 4331 - /* connect BE DAI capture if widgets are valid */ 4332 - codec = codec_dai->capture_widget; 4323 + capture: 4324 + /* connect BE DAI capture if widgets are valid */ 4325 + codec = codec_dai->capture_widget; 4333 4326 4334 - if (codec && capture_cpu) { 4335 - if (!capture) { 4336 - substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream; 4337 - capture = snd_soc_dapm_new_dai(card, substream, 4338 - "capture"); 4339 - if (IS_ERR(capture)) { 4340 - dev_err(rtd->dev, 4341 - "ASoC: Failed to create DAI %s: %ld\n", 4342 - codec_dai->name, 4343 - PTR_ERR(capture)); 4344 - continue; 4345 - } 4346 - 4347 - snd_soc_dapm_add_path(&card->dapm, capture, 4348 - capture_cpu, NULL, NULL); 4327 + if (codec && capture_cpu) { 4328 + if (!capture) { 4329 + substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream; 4330 + capture = snd_soc_dapm_new_dai(card, substream, 4331 + "capture"); 4332 + if (IS_ERR(capture)) { 4333 + dev_err(rtd->dev, 4334 + "ASoC: Failed to create DAI %s: %ld\n", 4335 + codec_dai->name, 4336 + PTR_ERR(capture)); 4337 + return; 4349 4338 } 4350 4339 4351 - dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 4352 - codec_dai->component->name, codec->name, 4353 - cpu_dai->component->name, capture_cpu->name); 4354 - 4355 - snd_soc_dapm_add_path(&card->dapm, codec, capture, 4356 - NULL, NULL); 4340 + snd_soc_dapm_add_path(&card->dapm, capture, 4341 + capture_cpu, NULL, NULL); 4357 4342 } 4343 + 4344 + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", 4345 + codec_dai->component->name, codec->name, 4346 + cpu_dai->component->name, capture_cpu->name); 4347 + 4348 + snd_soc_dapm_add_path(&card->dapm, codec, capture, 4349 + NULL, NULL); 4358 4350 } 4351 + } 4352 + 4353 + static void dapm_connect_dai_link_widgets(struct snd_soc_card *card, 4354 + struct snd_soc_pcm_runtime *rtd) 4355 + { 4356 + struct snd_soc_dai *codec_dai; 4357 + int i; 4358 + 4359 + if (rtd->num_cpus == 1) { 4360 + for_each_rtd_codec_dais(rtd, i, codec_dai) 4361 + dapm_add_valid_dai_widget(card, rtd, codec_dai, 4362 + rtd->cpu_dais[0]); 4363 + } else if (rtd->num_codecs == rtd->num_cpus) { 4364 + for_each_rtd_codec_dais(rtd, i, codec_dai) 4365 + dapm_add_valid_dai_widget(card, rtd, codec_dai, 4366 + rtd->cpu_dais[i]); 4367 + } else { 4368 + dev_err(card->dev, 4369 + "N cpus to M codecs link is not supported yet\n"); 4370 + } 4371 + 4359 4372 } 4360 4373 4361 4374 static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, ··· 4382 4359 struct snd_soc_dapm_widget *w; 4383 4360 unsigned int ep; 4384 4361 4385 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 4386 - w = dai->playback_widget; 4387 - else 4388 - w = dai->capture_widget; 4362 + w = snd_soc_dai_get_widget(dai, stream); 4389 4363 4390 4364 if (w) { 4391 4365 dapm_mark_dirty(w, "stream event"); ··· 4433 4413 static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 4434 4414 int event) 4435 4415 { 4436 - struct snd_soc_dai *codec_dai; 4416 + struct snd_soc_dai *dai; 4437 4417 int i; 4438 4418 4439 - soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event); 4440 - for_each_rtd_codec_dai(rtd, i, codec_dai) 4441 - soc_dapm_dai_stream_event(codec_dai, stream, event); 4419 + for_each_rtd_dais(rtd, i, dai) 4420 + soc_dapm_dai_stream_event(dai, stream, event); 4442 4421 4443 4422 dapm_power_widgets(rtd->card, event); 4444 4423 } ··· 4773 4754 } 4774 4755 4775 4756 INIT_LIST_HEAD(&dapm->list); 4757 + /* see for_each_card_dapms */ 4776 4758 list_add(&dapm->list, &card->dapm_list); 4777 4759 } 4778 4760 EXPORT_SYMBOL_GPL(snd_soc_dapm_init); ··· 4787 4767 4788 4768 mutex_lock(&card->dapm_mutex); 4789 4769 4790 - list_for_each_entry(w, &dapm->card->widgets, list) { 4770 + for_each_card_widgets(dapm->card, w) { 4791 4771 if (w->dapm != dapm) 4792 4772 continue; 4793 4773 if (w->power) { ··· 4820 4800 { 4821 4801 struct snd_soc_dapm_context *dapm; 4822 4802 4823 - list_for_each_entry(dapm, &card->dapm_list, list) { 4803 + for_each_card_dapms(card, dapm) { 4824 4804 if (dapm != &card->dapm) { 4825 4805 soc_dapm_shutdown_dapm(dapm); 4826 4806 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
+21 -5
sound/soc/soc-generic-dmaengine-pcm.c
··· 62 62 struct snd_dmaengine_dai_dma_data *dma_data; 63 63 int ret; 64 64 65 + if (rtd->num_cpus > 1) { 66 + dev_err(rtd->dev, 67 + "%s doesn't support Multi CPU yet\n", __func__); 68 + return -EINVAL; 69 + } 70 + 65 71 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 66 72 67 73 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); ··· 123 117 struct dma_chan *chan = pcm->chan[substream->stream]; 124 118 struct snd_dmaengine_dai_dma_data *dma_data; 125 119 struct snd_pcm_hardware hw; 120 + 121 + if (rtd->num_cpus > 1) { 122 + dev_err(rtd->dev, 123 + "%s doesn't support Multi CPU yet\n", __func__); 124 + return -EINVAL; 125 + } 126 126 127 127 if (pcm->config && pcm->config->pcm_hardware) 128 128 return snd_soc_set_runtime_hwparams(substream, ··· 197 185 struct snd_dmaengine_dai_dma_data *dma_data; 198 186 dma_filter_fn fn = NULL; 199 187 188 + if (rtd->num_cpus > 1) { 189 + dev_err(rtd->dev, 190 + "%s doesn't support Multi CPU yet\n", __func__); 191 + return NULL; 192 + } 193 + 200 194 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 201 195 202 196 if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) ··· 255 237 max_buffer_size = SIZE_MAX; 256 238 } 257 239 258 - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { 240 + for_each_pcm_streams(i) { 259 241 substream = rtd->pcm->streams[i].substream; 260 242 if (!substream) 261 243 continue; ··· 389 371 dev = config->dma_dev; 390 372 } 391 373 392 - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; 393 - i++) { 374 + for_each_pcm_streams(i) { 394 375 if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) 395 376 name = "rx-tx"; 396 377 else ··· 418 401 { 419 402 unsigned int i; 420 403 421 - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; 422 - i++) { 404 + for_each_pcm_streams(i) { 423 405 if (!pcm->chan[i]) 424 406 continue; 425 407 dma_release_channel(pcm->chan[i]);
+754 -877
sound/soc/soc-pcm.c
··· 28 28 29 29 #define DPCM_MAX_BE_USERS 8 30 30 31 + #ifdef CONFIG_DEBUG_FS 32 + static const char *dpcm_state_string(enum snd_soc_dpcm_state state) 33 + { 34 + switch (state) { 35 + case SND_SOC_DPCM_STATE_NEW: 36 + return "new"; 37 + case SND_SOC_DPCM_STATE_OPEN: 38 + return "open"; 39 + case SND_SOC_DPCM_STATE_HW_PARAMS: 40 + return "hw_params"; 41 + case SND_SOC_DPCM_STATE_PREPARE: 42 + return "prepare"; 43 + case SND_SOC_DPCM_STATE_START: 44 + return "start"; 45 + case SND_SOC_DPCM_STATE_STOP: 46 + return "stop"; 47 + case SND_SOC_DPCM_STATE_SUSPEND: 48 + return "suspend"; 49 + case SND_SOC_DPCM_STATE_PAUSED: 50 + return "paused"; 51 + case SND_SOC_DPCM_STATE_HW_FREE: 52 + return "hw_free"; 53 + case SND_SOC_DPCM_STATE_CLOSE: 54 + return "close"; 55 + } 56 + 57 + return "unknown"; 58 + } 59 + 60 + static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, 61 + int stream, char *buf, size_t size) 62 + { 63 + struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; 64 + struct snd_soc_dpcm *dpcm; 65 + ssize_t offset = 0; 66 + unsigned long flags; 67 + 68 + /* FE state */ 69 + offset += scnprintf(buf + offset, size - offset, 70 + "[%s - %s]\n", fe->dai_link->name, 71 + stream ? "Capture" : "Playback"); 72 + 73 + offset += scnprintf(buf + offset, size - offset, "State: %s\n", 74 + dpcm_state_string(fe->dpcm[stream].state)); 75 + 76 + if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && 77 + (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) 78 + offset += scnprintf(buf + offset, size - offset, 79 + "Hardware Params: " 80 + "Format = %s, Channels = %d, Rate = %d\n", 81 + snd_pcm_format_name(params_format(params)), 82 + params_channels(params), 83 + params_rate(params)); 84 + 85 + /* BEs state */ 86 + offset += scnprintf(buf + offset, size - offset, "Backends:\n"); 87 + 88 + if (list_empty(&fe->dpcm[stream].be_clients)) { 89 + offset += scnprintf(buf + offset, size - offset, 90 + " No active DSP links\n"); 91 + goto out; 92 + } 93 + 94 + spin_lock_irqsave(&fe->card->dpcm_lock, flags); 95 + for_each_dpcm_be(fe, stream, dpcm) { 96 + struct snd_soc_pcm_runtime *be = dpcm->be; 97 + params = &dpcm->hw_params; 98 + 99 + offset += scnprintf(buf + offset, size - offset, 100 + "- %s\n", be->dai_link->name); 101 + 102 + offset += scnprintf(buf + offset, size - offset, 103 + " State: %s\n", 104 + dpcm_state_string(be->dpcm[stream].state)); 105 + 106 + if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && 107 + (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) 108 + offset += scnprintf(buf + offset, size - offset, 109 + " Hardware Params: " 110 + "Format = %s, Channels = %d, Rate = %d\n", 111 + snd_pcm_format_name(params_format(params)), 112 + params_channels(params), 113 + params_rate(params)); 114 + } 115 + spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); 116 + out: 117 + return offset; 118 + } 119 + 120 + static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf, 121 + size_t count, loff_t *ppos) 122 + { 123 + struct snd_soc_pcm_runtime *fe = file->private_data; 124 + ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0; 125 + int stream; 126 + char *buf; 127 + 128 + if (fe->num_cpus > 1) { 129 + dev_err(fe->dev, 130 + "%s doesn't support Multi CPU yet\n", __func__); 131 + return -EINVAL; 132 + } 133 + 134 + buf = kmalloc(out_count, GFP_KERNEL); 135 + if (!buf) 136 + return -ENOMEM; 137 + 138 + for_each_pcm_streams(stream) 139 + if (snd_soc_dai_stream_valid(fe->cpu_dai, stream)) 140 + offset += dpcm_show_state(fe, stream, 141 + buf + offset, 142 + out_count - offset); 143 + 144 + ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset); 145 + 146 + kfree(buf); 147 + return ret; 148 + } 149 + 150 + static const struct file_operations dpcm_state_fops = { 151 + .open = simple_open, 152 + .read = dpcm_state_read_file, 153 + .llseek = default_llseek, 154 + }; 155 + 156 + void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) 157 + { 158 + if (!rtd->dai_link) 159 + return; 160 + 161 + if (!rtd->dai_link->dynamic) 162 + return; 163 + 164 + if (!rtd->card->debugfs_card_root) 165 + return; 166 + 167 + rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 168 + rtd->card->debugfs_card_root); 169 + 170 + debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, 171 + rtd, &dpcm_state_fops); 172 + } 173 + 174 + static void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm, int stream) 175 + { 176 + char *name; 177 + 178 + name = kasprintf(GFP_KERNEL, "%s:%s", dpcm->be->dai_link->name, 179 + stream ? "capture" : "playback"); 180 + if (name) { 181 + dpcm->debugfs_state = debugfs_create_dir( 182 + name, dpcm->fe->debugfs_dpcm_root); 183 + debugfs_create_u32("state", 0644, dpcm->debugfs_state, 184 + &dpcm->state); 185 + kfree(name); 186 + } 187 + } 188 + 189 + static void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm) 190 + { 191 + debugfs_remove_recursive(dpcm->debugfs_state); 192 + } 193 + 194 + #else 195 + static inline void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm, 196 + int stream) 197 + { 198 + } 199 + 200 + static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm) 201 + { 202 + } 203 + #endif 204 + 31 205 static int soc_rtd_startup(struct snd_soc_pcm_runtime *rtd, 32 206 struct snd_pcm_substream *substream) 33 207 { ··· 256 82 return 0; 257 83 } 258 84 85 + static void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd, 86 + int stream, int action) 87 + { 88 + struct snd_soc_dai *dai; 89 + int i; 90 + 91 + lockdep_assert_held(&rtd->card->pcm_mutex); 92 + 93 + for_each_rtd_dais(rtd, i, dai) { 94 + dai->stream_active[stream] += action; 95 + dai->active += action; 96 + dai->component->active += action; 97 + } 98 + } 99 + 259 100 /** 260 101 * snd_soc_runtime_activate() - Increment active count for PCM runtime components 261 102 * @rtd: ASoC PCM runtime that is activated ··· 283 94 */ 284 95 void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream) 285 96 { 286 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 287 - struct snd_soc_dai *codec_dai; 288 - int i; 289 - 290 - lockdep_assert_held(&rtd->card->pcm_mutex); 291 - 292 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 293 - cpu_dai->playback_active++; 294 - for_each_rtd_codec_dai(rtd, i, codec_dai) 295 - codec_dai->playback_active++; 296 - } else { 297 - cpu_dai->capture_active++; 298 - for_each_rtd_codec_dai(rtd, i, codec_dai) 299 - codec_dai->capture_active++; 300 - } 301 - 302 - cpu_dai->active++; 303 - cpu_dai->component->active++; 304 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 305 - codec_dai->active++; 306 - codec_dai->component->active++; 307 - } 97 + snd_soc_runtime_action(rtd, stream, 1); 308 98 } 99 + EXPORT_SYMBOL_GPL(snd_soc_runtime_activate); 309 100 310 101 /** 311 102 * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components ··· 299 130 */ 300 131 void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) 301 132 { 302 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 303 - struct snd_soc_dai *codec_dai; 304 - int i; 305 - 306 - lockdep_assert_held(&rtd->card->pcm_mutex); 307 - 308 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 309 - cpu_dai->playback_active--; 310 - for_each_rtd_codec_dai(rtd, i, codec_dai) 311 - codec_dai->playback_active--; 312 - } else { 313 - cpu_dai->capture_active--; 314 - for_each_rtd_codec_dai(rtd, i, codec_dai) 315 - codec_dai->capture_active--; 316 - } 317 - 318 - cpu_dai->active--; 319 - cpu_dai->component->active--; 320 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 321 - codec_dai->component->active--; 322 - codec_dai->active--; 323 - } 133 + snd_soc_runtime_action(rtd, stream, -1); 324 134 } 135 + EXPORT_SYMBOL_GPL(snd_soc_runtime_deactivate); 325 136 326 137 /** 327 138 * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay ··· 436 287 struct snd_pcm_hw_params *params) 437 288 { 438 289 struct snd_soc_pcm_runtime *rtd = substream->private_data; 439 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 440 - struct snd_soc_dai *codec_dai; 290 + struct snd_soc_dai *dai; 291 + struct snd_soc_dai *cpu_dai; 441 292 unsigned int rate, channels, sample_bits, symmetry, i; 442 293 443 294 rate = params_rate(params); ··· 445 296 sample_bits = snd_pcm_format_physical_width(params_format(params)); 446 297 447 298 /* reject unmatched parameters when applying symmetry */ 448 - symmetry = cpu_dai->driver->symmetric_rates || 449 - rtd->dai_link->symmetric_rates; 299 + symmetry = rtd->dai_link->symmetric_rates; 450 300 451 - for_each_rtd_codec_dai(rtd, i, codec_dai) 452 - symmetry |= codec_dai->driver->symmetric_rates; 301 + for_each_rtd_cpu_dais(rtd, i, dai) 302 + symmetry |= dai->driver->symmetric_rates; 453 303 454 - if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) { 455 - dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", 456 - cpu_dai->rate, rate); 457 - return -EINVAL; 304 + if (symmetry) { 305 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 306 + if (cpu_dai->rate && cpu_dai->rate != rate) { 307 + dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", 308 + cpu_dai->rate, rate); 309 + return -EINVAL; 310 + } 311 + } 458 312 } 459 313 460 - symmetry = cpu_dai->driver->symmetric_channels || 461 - rtd->dai_link->symmetric_channels; 314 + symmetry = rtd->dai_link->symmetric_channels; 462 315 463 - for_each_rtd_codec_dai(rtd, i, codec_dai) 464 - symmetry |= codec_dai->driver->symmetric_channels; 316 + for_each_rtd_dais(rtd, i, dai) 317 + symmetry |= dai->driver->symmetric_channels; 465 318 466 - if (symmetry && cpu_dai->channels && cpu_dai->channels != channels) { 467 - dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", 468 - cpu_dai->channels, channels); 469 - return -EINVAL; 319 + if (symmetry) { 320 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 321 + if (cpu_dai->channels && 322 + cpu_dai->channels != channels) { 323 + dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", 324 + cpu_dai->channels, channels); 325 + return -EINVAL; 326 + } 327 + } 470 328 } 471 329 472 - symmetry = cpu_dai->driver->symmetric_samplebits || 473 - rtd->dai_link->symmetric_samplebits; 330 + symmetry = rtd->dai_link->symmetric_samplebits; 474 331 475 - for_each_rtd_codec_dai(rtd, i, codec_dai) 476 - symmetry |= codec_dai->driver->symmetric_samplebits; 332 + for_each_rtd_dais(rtd, i, dai) 333 + symmetry |= dai->driver->symmetric_samplebits; 477 334 478 - if (symmetry && cpu_dai->sample_bits && cpu_dai->sample_bits != sample_bits) { 479 - dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", 480 - cpu_dai->sample_bits, sample_bits); 481 - return -EINVAL; 335 + if (symmetry) { 336 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 337 + if (cpu_dai->sample_bits && 338 + cpu_dai->sample_bits != sample_bits) { 339 + dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", 340 + cpu_dai->sample_bits, sample_bits); 341 + return -EINVAL; 342 + } 343 + } 482 344 } 483 345 484 346 return 0; ··· 498 338 static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) 499 339 { 500 340 struct snd_soc_pcm_runtime *rtd = substream->private_data; 501 - struct snd_soc_dai_driver *cpu_driver = rtd->cpu_dai->driver; 502 341 struct snd_soc_dai_link *link = rtd->dai_link; 503 - struct snd_soc_dai *codec_dai; 342 + struct snd_soc_dai *dai; 504 343 unsigned int symmetry, i; 505 344 506 - symmetry = cpu_driver->symmetric_rates || link->symmetric_rates || 507 - cpu_driver->symmetric_channels || link->symmetric_channels || 508 - cpu_driver->symmetric_samplebits || link->symmetric_samplebits; 345 + symmetry = link->symmetric_rates || 346 + link->symmetric_channels || 347 + link->symmetric_samplebits; 509 348 510 - for_each_rtd_codec_dai(rtd, i, codec_dai) 349 + for_each_rtd_dais(rtd, i, dai) 511 350 symmetry = symmetry || 512 - codec_dai->driver->symmetric_rates || 513 - codec_dai->driver->symmetric_channels || 514 - codec_dai->driver->symmetric_samplebits; 351 + dai->driver->symmetric_rates || 352 + dai->driver->symmetric_channels || 353 + dai->driver->symmetric_samplebits; 515 354 516 355 return symmetry; 517 356 } ··· 532 373 static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) 533 374 { 534 375 struct snd_soc_pcm_runtime *rtd = substream->private_data; 535 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 376 + struct snd_soc_dai *cpu_dai; 536 377 struct snd_soc_dai *codec_dai; 378 + struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu; 379 + int stream = substream->stream; 537 380 int i; 538 - unsigned int bits = 0, cpu_bits; 381 + unsigned int bits = 0, cpu_bits = 0; 539 382 540 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 541 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 542 - if (codec_dai->driver->playback.sig_bits == 0) { 543 - bits = 0; 544 - break; 545 - } 546 - bits = max(codec_dai->driver->playback.sig_bits, bits); 383 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 384 + pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream); 385 + 386 + if (pcm_codec->sig_bits == 0) { 387 + bits = 0; 388 + break; 547 389 } 548 - cpu_bits = cpu_dai->driver->playback.sig_bits; 549 - } else { 550 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 551 - if (codec_dai->driver->capture.sig_bits == 0) { 552 - bits = 0; 553 - break; 554 - } 555 - bits = max(codec_dai->driver->capture.sig_bits, bits); 390 + bits = max(pcm_codec->sig_bits, bits); 391 + } 392 + 393 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 394 + pcm_cpu = snd_soc_dai_get_pcm_stream(cpu_dai, stream); 395 + 396 + if (pcm_cpu->sig_bits == 0) { 397 + cpu_bits = 0; 398 + break; 556 399 } 557 - cpu_bits = cpu_dai->driver->capture.sig_bits; 400 + cpu_bits = max(pcm_cpu->sig_bits, cpu_bits); 558 401 } 559 402 560 403 soc_pcm_set_msb(substream, bits); 561 404 soc_pcm_set_msb(substream, cpu_bits); 562 405 } 563 406 564 - static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) 407 + /** 408 + * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream 409 + * @rtd: ASoC PCM runtime 410 + * @hw: PCM hardware parameters (output) 411 + * @stream: Direction of the PCM stream 412 + * 413 + * Calculates the subset of stream parameters supported by all DAIs 414 + * associated with the PCM stream. 415 + */ 416 + int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, 417 + struct snd_pcm_hardware *hw, int stream) 565 418 { 566 - struct snd_pcm_runtime *runtime = substream->runtime; 567 - struct snd_pcm_hardware *hw = &runtime->hw; 568 - struct snd_soc_pcm_runtime *rtd = substream->private_data; 569 419 struct snd_soc_dai *codec_dai; 570 - struct snd_soc_dai_driver *cpu_dai_drv = rtd->cpu_dai->driver; 571 - struct snd_soc_dai_driver *codec_dai_drv; 420 + struct snd_soc_dai *cpu_dai; 572 421 struct snd_soc_pcm_stream *codec_stream; 573 422 struct snd_soc_pcm_stream *cpu_stream; 574 423 unsigned int chan_min = 0, chan_max = UINT_MAX; 424 + unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX; 575 425 unsigned int rate_min = 0, rate_max = UINT_MAX; 576 - unsigned int rates = UINT_MAX; 426 + unsigned int cpu_rate_min = 0, cpu_rate_max = UINT_MAX; 427 + unsigned int rates = UINT_MAX, cpu_rates = UINT_MAX; 577 428 u64 formats = ULLONG_MAX; 578 429 int i; 579 430 580 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 581 - cpu_stream = &cpu_dai_drv->playback; 582 - else 583 - cpu_stream = &cpu_dai_drv->capture; 431 + /* first calculate min/max only for CPUs in the DAI link */ 432 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 584 433 585 - /* first calculate min/max only for CODECs in the DAI link */ 586 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 434 + /* 435 + * Skip CPUs which don't support the current stream type. 436 + * Otherwise, since the rate, channel, and format values will 437 + * zero in that case, we would have no usable settings left, 438 + * causing the resulting setup to fail. 439 + */ 440 + if (!snd_soc_dai_stream_valid(cpu_dai, stream)) 441 + continue; 442 + 443 + cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream); 444 + 445 + cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); 446 + cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); 447 + cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min); 448 + cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max); 449 + formats &= cpu_stream->formats; 450 + cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates, 451 + cpu_rates); 452 + } 453 + 454 + /* second calculate min/max only for CODECs in the DAI link */ 455 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 587 456 588 457 /* 589 458 * Skip CODECs which don't support the current stream type. 590 459 * Otherwise, since the rate, channel, and format values will 591 460 * zero in that case, we would have no usable settings left, 592 461 * causing the resulting setup to fail. 593 - * At least one CODEC should match, otherwise we should have 594 - * bailed out on a higher level, since there would be no 595 - * CODEC to support the transfer direction in that case. 596 462 */ 597 - if (!snd_soc_dai_stream_valid(codec_dai, 598 - substream->stream)) 463 + if (!snd_soc_dai_stream_valid(codec_dai, stream)) 599 464 continue; 600 465 601 - codec_dai_drv = codec_dai->driver; 602 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 603 - codec_stream = &codec_dai_drv->playback; 604 - else 605 - codec_stream = &codec_dai_drv->capture; 466 + codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream); 467 + 606 468 chan_min = max(chan_min, codec_stream->channels_min); 607 469 chan_max = min(chan_max, codec_stream->channels_max); 608 470 rate_min = max(rate_min, codec_stream->rate_min); ··· 632 452 rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates); 633 453 } 634 454 455 + /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ 456 + if (!chan_min || !cpu_chan_min) 457 + return -EINVAL; 458 + 635 459 /* 636 460 * chan min/max cannot be enforced if there are multiple CODEC DAIs 637 - * connected to a single CPU DAI, use CPU DAI's directly and let 461 + * connected to CPU DAI(s), use CPU DAI's directly and let 638 462 * channel allocation be fixed up later 639 463 */ 640 464 if (rtd->num_codecs > 1) { 641 - chan_min = cpu_stream->channels_min; 642 - chan_max = cpu_stream->channels_max; 465 + chan_min = cpu_chan_min; 466 + chan_max = cpu_chan_max; 643 467 } 644 468 645 - hw->channels_min = max(chan_min, cpu_stream->channels_min); 646 - hw->channels_max = min(chan_max, cpu_stream->channels_max); 647 - if (hw->formats) 648 - hw->formats &= formats & cpu_stream->formats; 649 - else 650 - hw->formats = formats & cpu_stream->formats; 651 - hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_stream->rates); 469 + /* finally find a intersection between CODECs and CPUs */ 470 + hw->channels_min = max(chan_min, cpu_chan_min); 471 + hw->channels_max = min(chan_max, cpu_chan_max); 472 + hw->formats = formats; 473 + hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_rates); 652 474 653 - snd_pcm_limit_hw_rates(runtime); 475 + snd_pcm_hw_limit_rates(hw); 654 476 655 - hw->rate_min = max(hw->rate_min, cpu_stream->rate_min); 477 + hw->rate_min = max(hw->rate_min, cpu_rate_min); 656 478 hw->rate_min = max(hw->rate_min, rate_min); 657 - hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max); 479 + hw->rate_max = min_not_zero(hw->rate_max, cpu_rate_max); 658 480 hw->rate_max = min_not_zero(hw->rate_max, rate_max); 481 + 482 + return 0; 483 + } 484 + EXPORT_SYMBOL_GPL(snd_soc_runtime_calc_hw); 485 + 486 + static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) 487 + { 488 + struct snd_pcm_hardware *hw = &substream->runtime->hw; 489 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 490 + u64 formats = hw->formats; 491 + 492 + /* 493 + * At least one CPU and one CODEC should match. Otherwise, we should 494 + * have bailed out on a higher level, since there would be no CPU or 495 + * CODEC to support the transfer direction in that case. 496 + */ 497 + snd_soc_runtime_calc_hw(rtd, hw, substream->stream); 498 + 499 + if (formats) 500 + hw->formats &= formats; 659 501 } 660 502 661 - static int soc_pcm_components_open(struct snd_pcm_substream *substream, 662 - struct snd_soc_component **last) 503 + static int soc_pcm_components_open(struct snd_pcm_substream *substream) 663 504 { 664 505 struct snd_soc_pcm_runtime *rtd = substream->private_data; 506 + struct snd_soc_component *last = NULL; 665 507 struct snd_soc_component *component; 666 508 int i, ret = 0; 667 509 668 510 for_each_rtd_components(rtd, i, component) { 669 - *last = component; 511 + last = component; 670 512 671 513 ret = snd_soc_component_module_get_when_open(component); 672 514 if (ret < 0) { 673 515 dev_err(component->dev, 674 516 "ASoC: can't get module %s\n", 675 517 component->name); 676 - return ret; 518 + break; 677 519 } 678 520 679 521 ret = snd_soc_component_open(component, substream); 680 522 if (ret < 0) { 523 + snd_soc_component_module_put_when_close(component); 681 524 dev_err(component->dev, 682 525 "ASoC: can't open component %s: %d\n", 683 526 component->name, ret); 684 - return ret; 527 + break; 685 528 } 686 529 } 687 - *last = NULL; 688 - return 0; 530 + 531 + if (ret < 0) { 532 + /* rollback on error */ 533 + for_each_rtd_components(rtd, i, component) { 534 + if (component == last) 535 + break; 536 + 537 + snd_soc_component_close(component, substream); 538 + snd_soc_component_module_put_when_close(component); 539 + } 540 + } 541 + 542 + return ret; 689 543 } 690 544 691 - static int soc_pcm_components_close(struct snd_pcm_substream *substream, 692 - struct snd_soc_component *last) 545 + static int soc_pcm_components_close(struct snd_pcm_substream *substream) 693 546 { 694 547 struct snd_soc_pcm_runtime *rtd = substream->private_data; 695 548 struct snd_soc_component *component; 696 - int i, ret = 0; 549 + int i, r, ret = 0; 697 550 698 551 for_each_rtd_components(rtd, i, component) { 699 - if (component == last) 700 - break; 552 + r = snd_soc_component_close(component, substream); 553 + if (r < 0) 554 + ret = r; /* use last ret */ 701 555 702 - ret |= snd_soc_component_close(component, substream); 703 556 snd_soc_component_module_put_when_close(component); 704 557 } 705 558 706 559 return ret; 560 + } 561 + 562 + /* 563 + * Called by ALSA when a PCM substream is closed. Private data can be 564 + * freed here. The cpu DAI, codec DAI, machine and components are also 565 + * shutdown. 566 + */ 567 + static int soc_pcm_close(struct snd_pcm_substream *substream) 568 + { 569 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 570 + struct snd_soc_component *component; 571 + struct snd_soc_dai *dai; 572 + int i; 573 + 574 + mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 575 + 576 + snd_soc_runtime_deactivate(rtd, substream->stream); 577 + 578 + for_each_rtd_dais(rtd, i, dai) 579 + snd_soc_dai_shutdown(dai, substream); 580 + 581 + soc_rtd_shutdown(rtd, substream); 582 + 583 + soc_pcm_components_close(substream); 584 + 585 + snd_soc_dapm_stream_stop(rtd, substream->stream); 586 + 587 + mutex_unlock(&rtd->card->pcm_mutex); 588 + 589 + for_each_rtd_components(rtd, i, component) { 590 + pm_runtime_mark_last_busy(component->dev); 591 + pm_runtime_put_autosuspend(component->dev); 592 + } 593 + 594 + for_each_rtd_components(rtd, i, component) 595 + if (!component->active) 596 + pinctrl_pm_select_sleep_state(component->dev); 597 + 598 + return 0; 707 599 } 708 600 709 601 /* ··· 788 536 struct snd_soc_pcm_runtime *rtd = substream->private_data; 789 537 struct snd_pcm_runtime *runtime = substream->runtime; 790 538 struct snd_soc_component *component; 791 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 792 - struct snd_soc_dai *codec_dai; 539 + struct snd_soc_dai *dai; 793 540 const char *codec_dai_name = "multicodec"; 541 + const char *cpu_dai_name = "multicpu"; 794 542 int i, ret = 0; 795 543 796 544 for_each_rtd_components(rtd, i, component) ··· 801 549 802 550 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 803 551 804 - /* startup the audio subsystem */ 805 - ret = snd_soc_dai_startup(cpu_dai, substream); 806 - if (ret < 0) { 807 - dev_err(cpu_dai->dev, "ASoC: can't open interface %s: %d\n", 808 - cpu_dai->name, ret); 809 - goto out; 810 - } 811 - 812 - ret = soc_pcm_components_open(substream, &component); 552 + ret = soc_pcm_components_open(substream); 813 553 if (ret < 0) 814 554 goto component_err; 815 - 816 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 817 - ret = snd_soc_dai_startup(codec_dai, substream); 818 - if (ret < 0) { 819 - dev_err(codec_dai->dev, 820 - "ASoC: can't open codec %s: %d\n", 821 - codec_dai->name, ret); 822 - goto codec_dai_err; 823 - } 824 - 825 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 826 - codec_dai->tx_mask = 0; 827 - else 828 - codec_dai->rx_mask = 0; 829 - } 830 555 831 556 ret = soc_rtd_startup(rtd, substream); 832 557 if (ret < 0) { 833 558 pr_err("ASoC: %s startup failed: %d\n", 834 559 rtd->dai_link->name, ret); 835 - goto machine_err; 560 + goto rtd_startup_err; 561 + } 562 + 563 + /* startup the audio subsystem */ 564 + for_each_rtd_dais(rtd, i, dai) { 565 + ret = snd_soc_dai_startup(dai, substream); 566 + if (ret < 0) { 567 + dev_err(dai->dev, 568 + "ASoC: can't open DAI %s: %d\n", 569 + dai->name, ret); 570 + goto config_err; 571 + } 572 + 573 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 574 + dai->tx_mask = 0; 575 + else 576 + dai->rx_mask = 0; 836 577 } 837 578 838 579 /* Dynamic PCM DAI links compat checks use dynamic capabilities */ ··· 838 593 if (rtd->num_codecs == 1) 839 594 codec_dai_name = rtd->codec_dai->name; 840 595 596 + if (rtd->num_cpus == 1) 597 + cpu_dai_name = rtd->cpu_dai->name; 598 + 841 599 if (soc_pcm_has_symmetry(substream)) 842 600 runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; 843 601 844 602 ret = -EINVAL; 845 603 if (!runtime->hw.rates) { 846 604 printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", 847 - codec_dai_name, cpu_dai->name); 605 + codec_dai_name, cpu_dai_name); 848 606 goto config_err; 849 607 } 850 608 if (!runtime->hw.formats) { 851 609 printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", 852 - codec_dai_name, cpu_dai->name); 610 + codec_dai_name, cpu_dai_name); 853 611 goto config_err; 854 612 } 855 613 if (!runtime->hw.channels_min || !runtime->hw.channels_max || 856 614 runtime->hw.channels_min > runtime->hw.channels_max) { 857 615 printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", 858 - codec_dai_name, cpu_dai->name); 616 + codec_dai_name, cpu_dai_name); 859 617 goto config_err; 860 618 } 861 619 862 620 soc_pcm_apply_msb(substream); 863 621 864 622 /* Symmetry only applies if we've already got an active stream. */ 865 - if (cpu_dai->active) { 866 - ret = soc_pcm_apply_symmetry(substream, cpu_dai); 867 - if (ret != 0) 868 - goto config_err; 869 - } 870 - 871 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 872 - if (codec_dai->active) { 873 - ret = soc_pcm_apply_symmetry(substream, codec_dai); 623 + for_each_rtd_dais(rtd, i, dai) { 624 + if (dai->active) { 625 + ret = soc_pcm_apply_symmetry(substream, dai); 874 626 if (ret != 0) 875 627 goto config_err; 876 628 } 877 629 } 878 630 879 631 pr_debug("ASoC: %s <-> %s info:\n", 880 - codec_dai_name, cpu_dai->name); 632 + codec_dai_name, cpu_dai_name); 881 633 pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); 882 634 pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, 883 635 runtime->hw.channels_max); ··· 889 647 return 0; 890 648 891 649 config_err: 650 + for_each_rtd_dais(rtd, i, dai) 651 + snd_soc_dai_shutdown(dai, substream); 652 + 892 653 soc_rtd_shutdown(rtd, substream); 893 - 894 - machine_err: 895 - i = rtd->num_codecs; 896 - 897 - codec_dai_err: 898 - for_each_rtd_codec_dai_rollback(rtd, i, codec_dai) 899 - snd_soc_dai_shutdown(codec_dai, substream); 900 - 654 + rtd_startup_err: 655 + soc_pcm_components_close(substream); 901 656 component_err: 902 - soc_pcm_components_close(substream, component); 903 - 904 - snd_soc_dai_shutdown(cpu_dai, substream); 905 - out: 906 657 mutex_unlock(&rtd->card->pcm_mutex); 907 658 908 659 for_each_rtd_components(rtd, i, component) { ··· 921 686 } 922 687 923 688 /* 924 - * Called by ALSA when a PCM substream is closed. Private data can be 925 - * freed here. The cpu DAI, codec DAI, machine and components are also 926 - * shutdown. 927 - */ 928 - static int soc_pcm_close(struct snd_pcm_substream *substream) 929 - { 930 - struct snd_soc_pcm_runtime *rtd = substream->private_data; 931 - struct snd_soc_component *component; 932 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 933 - struct snd_soc_dai *codec_dai; 934 - int i; 935 - 936 - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 937 - 938 - snd_soc_runtime_deactivate(rtd, substream->stream); 939 - 940 - /* clear the corresponding DAIs rate when inactive */ 941 - if (!cpu_dai->active) 942 - cpu_dai->rate = 0; 943 - 944 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 945 - if (!codec_dai->active) 946 - codec_dai->rate = 0; 947 - } 948 - 949 - snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream); 950 - 951 - snd_soc_dai_shutdown(cpu_dai, substream); 952 - 953 - for_each_rtd_codec_dai(rtd, i, codec_dai) 954 - snd_soc_dai_shutdown(codec_dai, substream); 955 - 956 - soc_rtd_shutdown(rtd, substream); 957 - 958 - soc_pcm_components_close(substream, NULL); 959 - 960 - snd_soc_dapm_stream_stop(rtd, substream->stream); 961 - 962 - mutex_unlock(&rtd->card->pcm_mutex); 963 - 964 - for_each_rtd_components(rtd, i, component) { 965 - pm_runtime_mark_last_busy(component->dev); 966 - pm_runtime_put_autosuspend(component->dev); 967 - } 968 - 969 - for_each_rtd_components(rtd, i, component) 970 - if (!component->active) 971 - pinctrl_pm_select_sleep_state(component->dev); 972 - 973 - return 0; 974 - } 975 - 976 - /* 977 689 * Called by ALSA when the PCM substream is prepared, can set format, sample 978 690 * rate, etc. This function is non atomic and can be called multiple times, 979 691 * it can refer to the runtime info. ··· 929 747 { 930 748 struct snd_soc_pcm_runtime *rtd = substream->private_data; 931 749 struct snd_soc_component *component; 932 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 933 - struct snd_soc_dai *codec_dai; 750 + struct snd_soc_dai *dai; 934 751 int i, ret = 0; 935 752 936 753 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); ··· 950 769 } 951 770 } 952 771 953 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 954 - ret = snd_soc_dai_prepare(codec_dai, substream); 772 + for_each_rtd_dais(rtd, i, dai) { 773 + ret = snd_soc_dai_prepare(dai, substream); 955 774 if (ret < 0) { 956 - dev_err(codec_dai->dev, 957 - "ASoC: codec DAI prepare error: %d\n", 958 - ret); 775 + dev_err(dai->dev, 776 + "ASoC: DAI prepare error: %d\n", ret); 959 777 goto out; 960 778 } 961 - } 962 - 963 - ret = snd_soc_dai_prepare(cpu_dai, substream); 964 - if (ret < 0) { 965 - dev_err(cpu_dai->dev, 966 - "ASoC: cpu DAI prepare error: %d\n", ret); 967 - goto out; 968 779 } 969 780 970 781 /* cancel any delayed stream shutdown that is pending */ ··· 969 796 snd_soc_dapm_stream_event(rtd, substream->stream, 970 797 SND_SOC_DAPM_STREAM_START); 971 798 972 - for_each_rtd_codec_dai(rtd, i, codec_dai) 973 - snd_soc_dai_digital_mute(codec_dai, 0, 974 - substream->stream); 975 - snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream); 799 + for_each_rtd_dais(rtd, i, dai) 800 + snd_soc_dai_digital_mute(dai, 0, substream->stream); 976 801 977 802 out: 978 803 mutex_unlock(&rtd->card->pcm_mutex); ··· 993 822 { 994 823 struct snd_soc_pcm_runtime *rtd = substream->private_data; 995 824 struct snd_soc_component *component; 996 - int i, ret = 0; 825 + int i, r, ret = 0; 997 826 998 827 for_each_rtd_components(rtd, i, component) { 999 828 if (component == last) 1000 829 break; 1001 830 1002 - ret |= snd_soc_component_hw_free(component, substream); 831 + r = snd_soc_component_hw_free(component, substream); 832 + if (r < 0) 833 + ret = r; /* use last ret */ 1003 834 } 1004 835 1005 836 return ret; ··· 1017 844 { 1018 845 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1019 846 struct snd_soc_component *component; 1020 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 847 + struct snd_soc_dai *cpu_dai; 1021 848 struct snd_soc_dai *codec_dai; 1022 849 int i, ret = 0; 1023 850 ··· 1034 861 goto out; 1035 862 } 1036 863 1037 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 864 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 1038 865 struct snd_pcm_hw_params codec_params; 1039 866 1040 867 /* ··· 1081 908 snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); 1082 909 } 1083 910 1084 - ret = snd_soc_dai_hw_params(cpu_dai, substream, params); 1085 - if (ret < 0) 1086 - goto interface_err; 911 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 912 + /* 913 + * Skip CPUs which don't support the current stream 914 + * type. See soc_pcm_init_runtime_hw() for more details 915 + */ 916 + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) 917 + continue; 1087 918 1088 - /* store the parameters for each DAIs */ 1089 - cpu_dai->rate = params_rate(params); 1090 - cpu_dai->channels = params_channels(params); 1091 - cpu_dai->sample_bits = 1092 - snd_pcm_format_physical_width(params_format(params)); 919 + ret = snd_soc_dai_hw_params(cpu_dai, substream, params); 920 + if (ret < 0) 921 + goto interface_err; 1093 922 1094 - snd_soc_dapm_update_dai(substream, params, cpu_dai); 923 + /* store the parameters for each DAI */ 924 + cpu_dai->rate = params_rate(params); 925 + cpu_dai->channels = params_channels(params); 926 + cpu_dai->sample_bits = 927 + snd_pcm_format_physical_width(params_format(params)); 928 + 929 + snd_soc_dapm_update_dai(substream, params, cpu_dai); 930 + } 1095 931 1096 932 for_each_rtd_components(rtd, i, component) { 1097 933 ret = snd_soc_component_hw_params(component, substream, params); ··· 1120 938 component_err: 1121 939 soc_pcm_components_hw_free(substream, component); 1122 940 1123 - snd_soc_dai_hw_free(cpu_dai, substream); 1124 - cpu_dai->rate = 0; 941 + i = rtd->num_cpus; 1125 942 1126 943 interface_err: 944 + for_each_rtd_cpu_dais_rollback(rtd, i, cpu_dai) { 945 + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) 946 + continue; 947 + 948 + snd_soc_dai_hw_free(cpu_dai, substream); 949 + cpu_dai->rate = 0; 950 + } 951 + 1127 952 i = rtd->num_codecs; 1128 953 1129 954 codec_err: 1130 - for_each_rtd_codec_dai_rollback(rtd, i, codec_dai) { 955 + for_each_rtd_codec_dais_rollback(rtd, i, codec_dai) { 1131 956 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) 1132 957 continue; 1133 958 ··· 1154 965 static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 1155 966 { 1156 967 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1157 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1158 - struct snd_soc_dai *codec_dai; 1159 - bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 968 + struct snd_soc_dai *dai; 1160 969 int i; 1161 970 1162 971 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); 1163 972 1164 973 /* clear the corresponding DAIs parameters when going to be inactive */ 1165 - if (cpu_dai->active == 1) { 1166 - cpu_dai->rate = 0; 1167 - cpu_dai->channels = 0; 1168 - cpu_dai->sample_bits = 0; 1169 - } 974 + for_each_rtd_dais(rtd, i, dai) { 975 + int active = dai->stream_active[substream->stream]; 1170 976 1171 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1172 - if (codec_dai->active == 1) { 1173 - codec_dai->rate = 0; 1174 - codec_dai->channels = 0; 1175 - codec_dai->sample_bits = 0; 977 + if (dai->active == 1) { 978 + dai->rate = 0; 979 + dai->channels = 0; 980 + dai->sample_bits = 0; 1176 981 } 1177 - } 1178 982 1179 - /* apply codec digital mute */ 1180 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1181 - if ((playback && codec_dai->playback_active == 1) || 1182 - (!playback && codec_dai->capture_active == 1)) 1183 - snd_soc_dai_digital_mute(codec_dai, 1, 1184 - substream->stream); 983 + if (active == 1) 984 + snd_soc_dai_digital_mute(dai, 1, substream->stream); 1185 985 } 1186 986 1187 987 /* free any machine hw params */ ··· 1180 1002 soc_pcm_components_hw_free(substream, NULL); 1181 1003 1182 1004 /* now free hw params for the DAIs */ 1183 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1184 - if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) 1005 + for_each_rtd_dais(rtd, i, dai) { 1006 + if (!snd_soc_dai_stream_valid(dai, substream->stream)) 1185 1007 continue; 1186 1008 1187 - snd_soc_dai_hw_free(codec_dai, substream); 1009 + snd_soc_dai_hw_free(dai, substream); 1188 1010 } 1189 - 1190 - snd_soc_dai_hw_free(cpu_dai, substream); 1191 1011 1192 1012 mutex_unlock(&rtd->card->pcm_mutex); 1193 1013 return 0; ··· 1195 1019 { 1196 1020 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1197 1021 struct snd_soc_component *component; 1198 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1199 - struct snd_soc_dai *codec_dai; 1022 + struct snd_soc_dai *dai; 1200 1023 int i, ret; 1201 1024 1202 1025 ret = soc_rtd_trigger(rtd, substream, cmd); ··· 1208 1033 return ret; 1209 1034 } 1210 1035 1211 - ret = snd_soc_dai_trigger(cpu_dai, substream, cmd); 1212 - if (ret < 0) 1213 - return ret; 1214 - 1215 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1216 - ret = snd_soc_dai_trigger(codec_dai, substream, cmd); 1036 + for_each_rtd_dais(rtd, i, dai) { 1037 + ret = snd_soc_dai_trigger(dai, substream, cmd); 1217 1038 if (ret < 0) 1218 1039 return ret; 1219 1040 } ··· 1221 1050 { 1222 1051 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1223 1052 struct snd_soc_component *component; 1224 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1225 - struct snd_soc_dai *codec_dai; 1053 + struct snd_soc_dai *dai; 1226 1054 int i, ret; 1227 1055 1228 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1229 - ret = snd_soc_dai_trigger(codec_dai, substream, cmd); 1056 + for_each_rtd_dais(rtd, i, dai) { 1057 + ret = snd_soc_dai_trigger(dai, substream, cmd); 1230 1058 if (ret < 0) 1231 1059 return ret; 1232 1060 } 1233 - 1234 - ret = snd_soc_dai_trigger(cpu_dai, substream, cmd); 1235 - if (ret < 0) 1236 - return ret; 1237 1061 1238 1062 for_each_rtd_components(rtd, i, component) { 1239 1063 ret = snd_soc_component_trigger(component, substream, cmd); ··· 1269 1103 int cmd) 1270 1104 { 1271 1105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1272 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1273 - struct snd_soc_dai *codec_dai; 1106 + struct snd_soc_dai *dai; 1274 1107 int i, ret; 1275 1108 1276 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1277 - ret = snd_soc_dai_bespoke_trigger(codec_dai, substream, cmd); 1109 + for_each_rtd_dais(rtd, i, dai) { 1110 + ret = snd_soc_dai_bespoke_trigger(dai, substream, cmd); 1278 1111 if (ret < 0) 1279 1112 return ret; 1280 1113 } 1281 - 1282 - ret = snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd); 1283 - if (ret < 0) 1284 - return ret; 1285 1114 1286 1115 return 0; 1287 1116 } ··· 1288 1127 static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) 1289 1128 { 1290 1129 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1291 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1130 + struct snd_soc_dai *cpu_dai; 1292 1131 struct snd_soc_dai *codec_dai; 1293 1132 struct snd_pcm_runtime *runtime = substream->runtime; 1294 1133 snd_pcm_uframes_t offset = 0; 1295 1134 snd_pcm_sframes_t delay = 0; 1296 1135 snd_pcm_sframes_t codec_delay = 0; 1136 + snd_pcm_sframes_t cpu_delay = 0; 1297 1137 int i; 1298 1138 1299 1139 /* clearing the previous total delay */ ··· 1305 1143 /* base delay if assigned in pointer callback */ 1306 1144 delay = runtime->delay; 1307 1145 1308 - delay += snd_soc_dai_delay(cpu_dai, substream); 1146 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1147 + cpu_delay = max(cpu_delay, 1148 + snd_soc_dai_delay(cpu_dai, substream)); 1149 + } 1150 + delay += cpu_delay; 1309 1151 1310 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1152 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 1311 1153 codec_delay = max(codec_delay, 1312 1154 snd_soc_dai_delay(codec_dai, substream)); 1313 1155 } ··· 1328 1162 { 1329 1163 struct snd_soc_dpcm *dpcm; 1330 1164 unsigned long flags; 1331 - #ifdef CONFIG_DEBUG_FS 1332 - char *name; 1333 - #endif 1334 1165 1335 1166 /* only add new dpcms */ 1336 1167 for_each_dpcm_be(fe, stream, dpcm) { ··· 1352 1189 stream ? "capture" : "playback", fe->dai_link->name, 1353 1190 stream ? "<-" : "->", be->dai_link->name); 1354 1191 1355 - #ifdef CONFIG_DEBUG_FS 1356 - name = kasprintf(GFP_KERNEL, "%s:%s", be->dai_link->name, 1357 - stream ? "capture" : "playback"); 1358 - if (name) { 1359 - dpcm->debugfs_state = debugfs_create_dir(name, 1360 - fe->debugfs_dpcm_root); 1361 - debugfs_create_u32("state", 0644, dpcm->debugfs_state, 1362 - &dpcm->state); 1363 - kfree(name); 1364 - } 1365 - #endif 1192 + dpcm_create_debugfs_state(dpcm, stream); 1193 + 1366 1194 return 1; 1367 1195 } 1368 1196 ··· 1406 1252 /* BEs still alive need new FE */ 1407 1253 dpcm_be_reparent(fe, dpcm->be, stream); 1408 1254 1409 - #ifdef CONFIG_DEBUG_FS 1410 - debugfs_remove_recursive(dpcm->debugfs_state); 1411 - #endif 1255 + dpcm_remove_debugfs_state(dpcm); 1256 + 1412 1257 spin_lock_irqsave(&fe->card->dpcm_lock, flags); 1413 1258 list_del(&dpcm->list_be); 1414 1259 list_del(&dpcm->list_fe); ··· 1421 1268 struct snd_soc_dapm_widget *widget, int stream) 1422 1269 { 1423 1270 struct snd_soc_pcm_runtime *be; 1271 + struct snd_soc_dapm_widget *w; 1424 1272 struct snd_soc_dai *dai; 1425 1273 int i; 1426 1274 1427 1275 dev_dbg(card->dev, "ASoC: find BE for widget %s\n", widget->name); 1428 1276 1429 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1430 - for_each_card_rtds(card, be) { 1277 + for_each_card_rtds(card, be) { 1431 1278 1432 - if (!be->dai_link->no_pcm) 1433 - continue; 1279 + if (!be->dai_link->no_pcm) 1280 + continue; 1281 + 1282 + for_each_rtd_dais(be, i, dai) { 1283 + w = snd_soc_dai_get_widget(dai, stream); 1434 1284 1435 1285 dev_dbg(card->dev, "ASoC: try BE : %s\n", 1436 - be->cpu_dai->playback_widget ? 1437 - be->cpu_dai->playback_widget->name : "(not set)"); 1286 + w ? w->name : "(not set)"); 1438 1287 1439 - if (be->cpu_dai->playback_widget == widget) 1288 + if (w == widget) 1440 1289 return be; 1441 - 1442 - for_each_rtd_codec_dai(be, i, dai) { 1443 - if (dai->playback_widget == widget) 1444 - return be; 1445 - } 1446 - } 1447 - } else { 1448 - 1449 - for_each_card_rtds(card, be) { 1450 - 1451 - if (!be->dai_link->no_pcm) 1452 - continue; 1453 - 1454 - dev_dbg(card->dev, "ASoC: try BE %s\n", 1455 - be->cpu_dai->capture_widget ? 1456 - be->cpu_dai->capture_widget->name : "(not set)"); 1457 - 1458 - if (be->cpu_dai->capture_widget == widget) 1459 - return be; 1460 - 1461 - for_each_rtd_codec_dai(be, i, dai) { 1462 - if (dai->capture_widget == widget) 1463 - return be; 1464 - } 1465 1290 } 1466 1291 } 1467 1292 1468 - /* dai link name and stream name set correctly ? */ 1469 - dev_err(card->dev, "ASoC: can't get %s BE for %s\n", 1470 - stream ? "capture" : "playback", widget->name); 1293 + /* Widget provided is not a BE */ 1471 1294 return NULL; 1472 - } 1473 - 1474 - static inline struct snd_soc_dapm_widget * 1475 - dai_get_widget(struct snd_soc_dai *dai, int stream) 1476 - { 1477 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1478 - return dai->playback_widget; 1479 - else 1480 - return dai->capture_widget; 1481 1295 } 1482 1296 1483 1297 static int widget_in_list(struct snd_soc_dapm_widget_list *list, 1484 1298 struct snd_soc_dapm_widget *widget) 1485 1299 { 1300 + struct snd_soc_dapm_widget *w; 1486 1301 int i; 1487 1302 1488 - for (i = 0; i < list->num_widgets; i++) { 1489 - if (widget == list->widgets[i]) 1303 + for_each_dapm_widgets(list, i, w) 1304 + if (widget == w) 1490 1305 return 1; 1491 - } 1492 1306 1493 1307 return 0; 1494 1308 } ··· 1465 1345 { 1466 1346 struct snd_soc_card *card = widget->dapm->card; 1467 1347 struct snd_soc_pcm_runtime *rtd; 1468 - struct snd_soc_dai *dai; 1469 - int i; 1348 + int stream; 1470 1349 1471 - if (dir == SND_SOC_DAPM_DIR_OUT) { 1472 - for_each_card_rtds(card, rtd) { 1473 - if (!rtd->dai_link->no_pcm) 1474 - continue; 1350 + /* adjust dir to stream */ 1351 + if (dir == SND_SOC_DAPM_DIR_OUT) 1352 + stream = SNDRV_PCM_STREAM_PLAYBACK; 1353 + else 1354 + stream = SNDRV_PCM_STREAM_CAPTURE; 1475 1355 1476 - if (rtd->cpu_dai->playback_widget == widget) 1477 - return true; 1478 - 1479 - for_each_rtd_codec_dai(rtd, i, dai) { 1480 - if (dai->playback_widget == widget) 1481 - return true; 1482 - } 1483 - } 1484 - } else { /* SND_SOC_DAPM_DIR_IN */ 1485 - for_each_card_rtds(card, rtd) { 1486 - if (!rtd->dai_link->no_pcm) 1487 - continue; 1488 - 1489 - if (rtd->cpu_dai->capture_widget == widget) 1490 - return true; 1491 - 1492 - for_each_rtd_codec_dai(rtd, i, dai) { 1493 - if (dai->capture_widget == widget) 1494 - return true; 1495 - } 1496 - } 1497 - } 1356 + rtd = dpcm_get_be(card, widget, stream); 1357 + if (rtd) 1358 + return true; 1498 1359 1499 1360 return false; 1500 1361 } ··· 1485 1384 { 1486 1385 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 1487 1386 int paths; 1387 + 1388 + if (fe->num_cpus > 1) { 1389 + dev_err(fe->dev, 1390 + "%s doesn't support Multi CPU yet\n", __func__); 1391 + return -EINVAL; 1392 + } 1488 1393 1489 1394 /* get number of valid DAI paths and their widgets */ 1490 1395 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list, ··· 1502 1395 return paths; 1503 1396 } 1504 1397 1505 - static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, 1506 - struct snd_soc_dapm_widget_list **list_) 1398 + void dpcm_path_put(struct snd_soc_dapm_widget_list **list) 1507 1399 { 1508 - struct snd_soc_dpcm *dpcm; 1509 - struct snd_soc_dapm_widget_list *list = *list_; 1400 + snd_soc_dapm_dai_free_widgets(list); 1401 + } 1402 + 1403 + static bool dpcm_be_is_active(struct snd_soc_dpcm *dpcm, int stream, 1404 + struct snd_soc_dapm_widget_list *list) 1405 + { 1510 1406 struct snd_soc_dapm_widget *widget; 1511 1407 struct snd_soc_dai *dai; 1408 + unsigned int i; 1409 + 1410 + /* is there a valid DAI widget for this BE */ 1411 + for_each_rtd_dais(dpcm->be, i, dai) { 1412 + widget = snd_soc_dai_get_widget(dai, stream); 1413 + 1414 + /* 1415 + * The BE is pruned only if none of the dai 1416 + * widgets are in the active list. 1417 + */ 1418 + if (widget && widget_in_list(list, widget)) 1419 + return true; 1420 + } 1421 + 1422 + return false; 1423 + } 1424 + 1425 + static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, 1426 + struct snd_soc_dapm_widget_list **list_) 1427 + { 1428 + struct snd_soc_dpcm *dpcm; 1512 1429 int prune = 0; 1513 - int do_prune; 1514 1430 1515 1431 /* Destroy any old FE <--> BE connections */ 1516 1432 for_each_dpcm_be(fe, stream, dpcm) { 1517 - unsigned int i; 1518 - 1519 - /* is there a valid CPU DAI widget for this BE */ 1520 - widget = dai_get_widget(dpcm->be->cpu_dai, stream); 1521 - 1522 - /* prune the BE if it's no longer in our active list */ 1523 - if (widget && widget_in_list(list, widget)) 1524 - continue; 1525 - 1526 - /* is there a valid CODEC DAI widget for this BE */ 1527 - do_prune = 1; 1528 - for_each_rtd_codec_dai(dpcm->be, i, dai) { 1529 - widget = dai_get_widget(dai, stream); 1530 - 1531 - /* prune the BE if it's no longer in our active list */ 1532 - if (widget && widget_in_list(list, widget)) 1533 - do_prune = 0; 1534 - } 1535 - if (!do_prune) 1433 + if (dpcm_be_is_active(dpcm, stream, *list_)) 1536 1434 continue; 1537 1435 1538 1436 dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", ··· 1558 1446 struct snd_soc_card *card = fe->card; 1559 1447 struct snd_soc_dapm_widget_list *list = *list_; 1560 1448 struct snd_soc_pcm_runtime *be; 1449 + struct snd_soc_dapm_widget *widget; 1561 1450 int i, new = 0, err; 1562 1451 1563 1452 /* Create any new FE <--> BE connections */ 1564 - for (i = 0; i < list->num_widgets; i++) { 1453 + for_each_dapm_widgets(list, i, widget) { 1565 1454 1566 - switch (list->widgets[i]->id) { 1455 + switch (widget->id) { 1567 1456 case snd_soc_dapm_dai_in: 1568 1457 if (stream != SNDRV_PCM_STREAM_PLAYBACK) 1569 1458 continue; ··· 1578 1465 } 1579 1466 1580 1467 /* is there a valid BE rtd for this widget */ 1581 - be = dpcm_get_be(card, list->widgets[i], stream); 1468 + be = dpcm_get_be(card, widget, stream); 1582 1469 if (!be) { 1583 1470 dev_err(fe->dev, "ASoC: no BE found for %s\n", 1584 - list->widgets[i]->name); 1471 + widget->name); 1585 1472 continue; 1586 1473 } 1587 - 1588 - /* make sure BE is a real BE */ 1589 - if (!be->dai_link->no_pcm) 1590 - continue; 1591 1474 1592 1475 /* don't connect if FE is not running */ 1593 1476 if (!fe->dpcm[stream].runtime && !fe->fe_compr) ··· 1593 1484 err = dpcm_be_connect(fe, be, stream); 1594 1485 if (err < 0) { 1595 1486 dev_err(fe->dev, "ASoC: can't connect %s\n", 1596 - list->widgets[i]->name); 1487 + widget->name); 1597 1488 break; 1598 1489 } else if (err == 0) /* already connected */ 1599 1490 continue; ··· 1780 1671 1781 1672 for_each_dpcm_be(fe, stream, dpcm) { 1782 1673 struct snd_soc_pcm_runtime *be = dpcm->be; 1783 - struct snd_soc_dai_driver *codec_dai_drv; 1784 1674 struct snd_soc_pcm_stream *codec_stream; 1785 1675 int i; 1786 1676 1787 - for_each_rtd_codec_dai(be, i, dai) { 1677 + for_each_rtd_codec_dais(be, i, dai) { 1788 1678 /* 1789 1679 * Skip CODECs which don't support the current stream 1790 1680 * type. See soc_pcm_init_runtime_hw() for more details ··· 1791 1683 if (!snd_soc_dai_stream_valid(dai, stream)) 1792 1684 continue; 1793 1685 1794 - codec_dai_drv = dai->driver; 1795 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1796 - codec_stream = &codec_dai_drv->playback; 1797 - else 1798 - codec_stream = &codec_dai_drv->capture; 1686 + codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); 1799 1687 1800 1688 *formats &= codec_stream->formats; 1801 1689 } ··· 1816 1712 1817 1713 for_each_dpcm_be(fe, stream, dpcm) { 1818 1714 struct snd_soc_pcm_runtime *be = dpcm->be; 1819 - struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver; 1820 - struct snd_soc_dai_driver *codec_dai_drv; 1821 1715 struct snd_soc_pcm_stream *codec_stream; 1822 1716 struct snd_soc_pcm_stream *cpu_stream; 1717 + struct snd_soc_dai *dai; 1718 + int i; 1823 1719 1824 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1825 - cpu_stream = &cpu_dai_drv->playback; 1826 - else 1827 - cpu_stream = &cpu_dai_drv->capture; 1720 + for_each_rtd_cpu_dais(be, i, dai) { 1721 + /* 1722 + * Skip CPUs which don't support the current stream 1723 + * type. See soc_pcm_init_runtime_hw() for more details 1724 + */ 1725 + if (!snd_soc_dai_stream_valid(dai, stream)) 1726 + continue; 1828 1727 1829 - *channels_min = max(*channels_min, cpu_stream->channels_min); 1830 - *channels_max = min(*channels_max, cpu_stream->channels_max); 1728 + cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); 1729 + 1730 + *channels_min = max(*channels_min, 1731 + cpu_stream->channels_min); 1732 + *channels_max = min(*channels_max, 1733 + cpu_stream->channels_max); 1734 + } 1831 1735 1832 1736 /* 1833 1737 * chan min/max cannot be enforced if there are multiple CODEC 1834 1738 * DAIs connected to a single CPU DAI, use CPU DAI's directly 1835 1739 */ 1836 1740 if (be->num_codecs == 1) { 1837 - codec_dai_drv = be->codec_dais[0]->driver; 1838 - 1839 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1840 - codec_stream = &codec_dai_drv->playback; 1841 - else 1842 - codec_stream = &codec_dai_drv->capture; 1741 + codec_stream = snd_soc_dai_get_pcm_stream(be->codec_dais[0], stream); 1843 1742 1844 1743 *channels_min = max(*channels_min, 1845 1744 codec_stream->channels_min); ··· 1871 1764 1872 1765 for_each_dpcm_be(fe, stream, dpcm) { 1873 1766 struct snd_soc_pcm_runtime *be = dpcm->be; 1874 - struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver; 1875 - struct snd_soc_dai_driver *codec_dai_drv; 1876 - struct snd_soc_pcm_stream *codec_stream; 1877 - struct snd_soc_pcm_stream *cpu_stream; 1767 + struct snd_soc_pcm_stream *pcm; 1878 1768 struct snd_soc_dai *dai; 1879 1769 int i; 1880 1770 1881 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1882 - cpu_stream = &cpu_dai_drv->playback; 1883 - else 1884 - cpu_stream = &cpu_dai_drv->capture; 1885 - 1886 - *rate_min = max(*rate_min, cpu_stream->rate_min); 1887 - *rate_max = min_not_zero(*rate_max, cpu_stream->rate_max); 1888 - *rates = snd_pcm_rate_mask_intersect(*rates, cpu_stream->rates); 1889 - 1890 - for_each_rtd_codec_dai(be, i, dai) { 1771 + for_each_rtd_dais(be, i, dai) { 1891 1772 /* 1892 - * Skip CODECs which don't support the current stream 1773 + * Skip DAIs which don't support the current stream 1893 1774 * type. See soc_pcm_init_runtime_hw() for more details 1894 1775 */ 1895 1776 if (!snd_soc_dai_stream_valid(dai, stream)) 1896 1777 continue; 1897 1778 1898 - codec_dai_drv = dai->driver; 1899 - if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1900 - codec_stream = &codec_dai_drv->playback; 1901 - else 1902 - codec_stream = &codec_dai_drv->capture; 1779 + pcm = snd_soc_dai_get_pcm_stream(dai, stream); 1903 1780 1904 - *rate_min = max(*rate_min, codec_stream->rate_min); 1905 - *rate_max = min_not_zero(*rate_max, 1906 - codec_stream->rate_max); 1907 - *rates = snd_pcm_rate_mask_intersect(*rates, 1908 - codec_stream->rates); 1781 + *rate_min = max(*rate_min, pcm->rate_min); 1782 + *rate_max = min_not_zero(*rate_max, pcm->rate_max); 1783 + *rates = snd_pcm_rate_mask_intersect(*rates, pcm->rates); 1909 1784 } 1910 1785 } 1911 1786 } ··· 1896 1807 { 1897 1808 struct snd_pcm_runtime *runtime = substream->runtime; 1898 1809 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1899 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1900 - struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 1810 + struct snd_soc_dai *cpu_dai; 1811 + int i; 1901 1812 1902 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1903 - dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); 1904 - else 1905 - dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture); 1813 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1814 + /* 1815 + * Skip CPUs which don't support the current stream 1816 + * type. See soc_pcm_init_runtime_hw() for more details 1817 + */ 1818 + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) 1819 + continue; 1820 + 1821 + dpcm_init_runtime_hw(runtime, 1822 + snd_soc_dai_get_pcm_stream(cpu_dai, 1823 + substream->stream)); 1824 + } 1906 1825 1907 1826 dpcm_runtime_merge_format(substream, &runtime->hw.formats); 1908 1827 dpcm_runtime_merge_chan(substream, &runtime->hw.channels_min, ··· 1947 1850 { 1948 1851 struct snd_soc_dpcm *dpcm; 1949 1852 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1950 - struct snd_soc_dai *fe_cpu_dai = fe->cpu_dai; 1853 + struct snd_soc_dai *fe_cpu_dai; 1951 1854 int err; 1855 + int i; 1952 1856 1953 1857 /* apply symmetry for FE */ 1954 1858 if (soc_pcm_has_symmetry(fe_substream)) 1955 1859 fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; 1956 1860 1957 - /* Symmetry only applies if we've got an active stream. */ 1958 - if (fe_cpu_dai->active) { 1959 - err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai); 1960 - if (err < 0) 1961 - return err; 1861 + for_each_rtd_cpu_dais (fe, i, fe_cpu_dai) { 1862 + /* Symmetry only applies if we've got an active stream. */ 1863 + if (fe_cpu_dai->active) { 1864 + err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai); 1865 + if (err < 0) 1866 + return err; 1867 + } 1962 1868 } 1963 1869 1964 1870 /* apply symmetry for BE */ ··· 1970 1870 struct snd_pcm_substream *be_substream = 1971 1871 snd_soc_dpcm_get_substream(be, stream); 1972 1872 struct snd_soc_pcm_runtime *rtd; 1973 - struct snd_soc_dai *codec_dai; 1873 + struct snd_soc_dai *dai; 1974 1874 int i; 1975 1875 1976 1876 /* A backend may not have the requested substream */ ··· 1985 1885 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; 1986 1886 1987 1887 /* Symmetry only applies if we've got an active stream. */ 1988 - if (rtd->cpu_dai->active) { 1989 - err = soc_pcm_apply_symmetry(fe_substream, 1990 - rtd->cpu_dai); 1991 - if (err < 0) 1992 - return err; 1993 - } 1994 - 1995 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 1996 - if (codec_dai->active) { 1997 - err = soc_pcm_apply_symmetry(fe_substream, 1998 - codec_dai); 1888 + for_each_rtd_dais(rtd, i, dai) { 1889 + if (dai->active) { 1890 + err = soc_pcm_apply_symmetry(fe_substream, dai); 1999 1891 if (err < 0) 2000 1892 return err; 2001 1893 } ··· 2005 1913 2006 1914 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); 2007 1915 2008 - ret = dpcm_be_dai_startup(fe, fe_substream->stream); 1916 + ret = dpcm_be_dai_startup(fe, stream); 2009 1917 if (ret < 0) { 2010 1918 dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret); 2011 1919 goto be_err; ··· 2026 1934 snd_pcm_limit_hw_rates(runtime); 2027 1935 2028 1936 ret = dpcm_apply_symmetry(fe_substream, stream); 2029 - if (ret < 0) { 1937 + if (ret < 0) 2030 1938 dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n", 2031 1939 ret); 2032 - goto unwind; 2033 - } 2034 - 2035 - dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2036 - return 0; 2037 1940 2038 1941 unwind: 2039 - dpcm_be_dai_startup_unwind(fe, fe_substream->stream); 1942 + if (ret < 0) 1943 + dpcm_be_dai_startup_unwind(fe, stream); 2040 1944 be_err: 2041 1945 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2042 1946 return ret; ··· 2086 1998 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); 2087 1999 2088 2000 /* shutdown the BEs */ 2089 - dpcm_be_dai_shutdown(fe, substream->stream); 2001 + dpcm_be_dai_shutdown(fe, stream); 2090 2002 2091 2003 dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); 2092 2004 ··· 2264 2176 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2265 2177 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); 2266 2178 2267 - memcpy(&fe->dpcm[substream->stream].hw_params, params, 2179 + memcpy(&fe->dpcm[stream].hw_params, params, 2268 2180 sizeof(struct snd_pcm_hw_params)); 2269 - ret = dpcm_be_dai_hw_params(fe, substream->stream); 2181 + ret = dpcm_be_dai_hw_params(fe, stream); 2270 2182 if (ret < 0) { 2271 2183 dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret); 2272 2184 goto out; ··· 2588 2500 goto out; 2589 2501 } 2590 2502 2591 - ret = dpcm_be_dai_prepare(fe, substream->stream); 2503 + ret = dpcm_be_dai_prepare(fe, stream); 2592 2504 if (ret < 0) 2593 2505 goto out; 2594 2506 ··· 2740 2652 return ret; 2741 2653 } 2742 2654 2743 - static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream) 2744 - { 2745 - int ret; 2746 - 2747 - dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE); 2748 - ret = dpcm_run_update_startup(fe, stream); 2749 - if (ret < 0) 2750 - dev_err(fe->dev, "ASoC: failed to startup some BEs\n"); 2751 - dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2752 - 2753 - return ret; 2754 - } 2755 - 2756 - static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream) 2757 - { 2758 - int ret; 2759 - 2760 - dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE); 2761 - ret = dpcm_run_update_shutdown(fe, stream); 2762 - if (ret < 0) 2763 - dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); 2764 - dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2765 - 2766 - return ret; 2767 - } 2768 - 2769 2655 static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) 2770 2656 { 2771 2657 struct snd_soc_dapm_widget_list *list; 2658 + int stream; 2772 2659 int count, paths; 2660 + int ret; 2661 + 2662 + if (fe->num_cpus > 1) { 2663 + dev_err(fe->dev, 2664 + "%s doesn't support Multi CPU yet\n", __func__); 2665 + return -EINVAL; 2666 + } 2773 2667 2774 2668 if (!fe->dai_link->dynamic) 2775 2669 return 0; ··· 2764 2694 dev_dbg(fe->dev, "ASoC: DPCM %s runtime update for FE %s\n", 2765 2695 new ? "new" : "old", fe->dai_link->name); 2766 2696 2767 - /* skip if FE doesn't have playback capability */ 2768 - if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK) || 2769 - !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_PLAYBACK)) 2770 - goto capture; 2697 + for_each_pcm_streams(stream) { 2771 2698 2772 - /* skip if FE isn't currently playing */ 2773 - if (!fe->cpu_dai->playback_active || !fe->codec_dai->playback_active) 2774 - goto capture; 2699 + /* skip if FE doesn't have playback/capture capability */ 2700 + if (!snd_soc_dai_stream_valid(fe->cpu_dai, stream) || 2701 + !snd_soc_dai_stream_valid(fe->codec_dai, stream)) 2702 + continue; 2775 2703 2776 - paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); 2777 - if (paths < 0) { 2778 - dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2779 - fe->dai_link->name, "playback"); 2780 - return paths; 2704 + /* skip if FE isn't currently playing/capturing */ 2705 + if (!fe->cpu_dai->stream_active[stream] || 2706 + !fe->codec_dai->stream_active[stream]) 2707 + continue; 2708 + 2709 + paths = dpcm_path_get(fe, stream, &list); 2710 + if (paths < 0) { 2711 + dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2712 + fe->dai_link->name, 2713 + stream == SNDRV_PCM_STREAM_PLAYBACK ? 2714 + "playback" : "capture"); 2715 + return paths; 2716 + } 2717 + 2718 + /* update any playback/capture paths */ 2719 + count = dpcm_process_paths(fe, stream, &list, new); 2720 + if (count) { 2721 + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE); 2722 + if (new) 2723 + ret = dpcm_run_update_startup(fe, stream); 2724 + else 2725 + ret = dpcm_run_update_shutdown(fe, stream); 2726 + if (ret < 0) 2727 + dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); 2728 + dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2729 + 2730 + dpcm_clear_pending_state(fe, stream); 2731 + dpcm_be_disconnect(fe, stream); 2732 + } 2733 + 2734 + dpcm_path_put(&list); 2781 2735 } 2782 - 2783 - /* update any playback paths */ 2784 - count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, new); 2785 - if (count) { 2786 - if (new) 2787 - dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK); 2788 - else 2789 - dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK); 2790 - 2791 - dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK); 2792 - dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); 2793 - } 2794 - 2795 - dpcm_path_put(&list); 2796 - 2797 - capture: 2798 - /* skip if FE doesn't have capture capability */ 2799 - if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE) || 2800 - !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_CAPTURE)) 2801 - return 0; 2802 - 2803 - /* skip if FE isn't currently capturing */ 2804 - if (!fe->cpu_dai->capture_active || !fe->codec_dai->capture_active) 2805 - return 0; 2806 - 2807 - paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); 2808 - if (paths < 0) { 2809 - dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2810 - fe->dai_link->name, "capture"); 2811 - return paths; 2812 - } 2813 - 2814 - /* update any old capture paths */ 2815 - count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, new); 2816 - if (count) { 2817 - if (new) 2818 - dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE); 2819 - else 2820 - dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE); 2821 - 2822 - dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE); 2823 - dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); 2824 - } 2825 - 2826 - dpcm_path_put(&list); 2827 2736 2828 2737 return 0; 2829 2738 } ··· 2810 2761 /* Called by DAPM mixer/mux changes to update audio routing between PCMs and 2811 2762 * any DAI links. 2812 2763 */ 2813 - int soc_dpcm_runtime_update(struct snd_soc_card *card) 2764 + int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) 2814 2765 { 2815 2766 struct snd_soc_pcm_runtime *fe; 2816 2767 int ret = 0; ··· 2834 2785 mutex_unlock(&card->mutex); 2835 2786 return ret; 2836 2787 } 2837 - int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) 2788 + EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update); 2789 + 2790 + static void dpcm_fe_dai_cleanup(struct snd_pcm_substream *fe_substream) 2838 2791 { 2792 + struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 2839 2793 struct snd_soc_dpcm *dpcm; 2840 - struct snd_soc_dai *dai; 2794 + int stream = fe_substream->stream; 2841 2795 2842 - for_each_dpcm_be(fe, SNDRV_PCM_STREAM_PLAYBACK, dpcm) { 2796 + /* mark FE's links ready to prune */ 2797 + for_each_dpcm_be(fe, stream, dpcm) 2798 + dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 2843 2799 2844 - struct snd_soc_pcm_runtime *be = dpcm->be; 2845 - int i; 2800 + dpcm_be_disconnect(fe, stream); 2846 2801 2847 - if (be->dai_link->ignore_suspend) 2848 - continue; 2802 + fe->dpcm[stream].runtime = NULL; 2803 + } 2849 2804 2850 - for_each_rtd_codec_dai(be, i, dai) { 2851 - struct snd_soc_dai_driver *drv = dai->driver; 2805 + static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) 2806 + { 2807 + struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 2808 + int ret; 2852 2809 2853 - dev_dbg(be->dev, "ASoC: BE digital mute %s\n", 2854 - be->dai_link->name); 2810 + mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2811 + ret = dpcm_fe_dai_shutdown(fe_substream); 2855 2812 2856 - if (drv->ops && drv->ops->digital_mute && 2857 - dai->playback_active) 2858 - drv->ops->digital_mute(dai, mute); 2859 - } 2860 - } 2813 + dpcm_fe_dai_cleanup(fe_substream); 2861 2814 2862 - return 0; 2815 + mutex_unlock(&fe->card->mutex); 2816 + return ret; 2863 2817 } 2864 2818 2865 2819 static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) 2866 2820 { 2867 2821 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 2868 - struct snd_soc_dpcm *dpcm; 2869 2822 struct snd_soc_dapm_widget_list *list; 2870 2823 int ret; 2871 2824 int stream = fe_substream->stream; ··· 2877 2826 2878 2827 ret = dpcm_path_get(fe, stream, &list); 2879 2828 if (ret < 0) { 2880 - mutex_unlock(&fe->card->mutex); 2881 - return ret; 2829 + goto open_end; 2882 2830 } else if (ret == 0) { 2883 2831 dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", 2884 2832 fe->dai_link->name, stream ? "capture" : "playback"); ··· 2887 2837 dpcm_process_paths(fe, stream, &list, 1); 2888 2838 2889 2839 ret = dpcm_fe_dai_startup(fe_substream); 2890 - if (ret < 0) { 2891 - /* clean up all links */ 2892 - for_each_dpcm_be(fe, stream, dpcm) 2893 - dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 2894 - 2895 - dpcm_be_disconnect(fe, stream); 2896 - fe->dpcm[stream].runtime = NULL; 2897 - } 2840 + if (ret < 0) 2841 + dpcm_fe_dai_cleanup(fe_substream); 2898 2842 2899 2843 dpcm_clear_pending_state(fe, stream); 2900 2844 dpcm_path_put(&list); 2901 - mutex_unlock(&fe->card->mutex); 2902 - return ret; 2903 - } 2904 - 2905 - static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) 2906 - { 2907 - struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 2908 - struct snd_soc_dpcm *dpcm; 2909 - int stream = fe_substream->stream, ret; 2910 - 2911 - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2912 - ret = dpcm_fe_dai_shutdown(fe_substream); 2913 - 2914 - /* mark FE's links ready to prune */ 2915 - for_each_dpcm_be(fe, stream, dpcm) 2916 - dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 2917 - 2918 - dpcm_be_disconnect(fe, stream); 2919 - 2920 - fe->dpcm[stream].runtime = NULL; 2845 + open_end: 2921 2846 mutex_unlock(&fe->card->mutex); 2922 2847 return ret; 2923 2848 } ··· 2901 2876 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2902 2877 { 2903 2878 struct snd_soc_dai *codec_dai; 2904 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2879 + struct snd_soc_dai *cpu_dai; 2905 2880 struct snd_soc_component *component; 2906 2881 struct snd_pcm *pcm; 2907 2882 char new_name[64]; ··· 2913 2888 capture = rtd->dai_link->dpcm_capture; 2914 2889 } else { 2915 2890 /* Adapt stream for codec2codec links */ 2916 - struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ? 2917 - &cpu_dai->driver->playback : &cpu_dai->driver->capture; 2918 - struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ? 2919 - &cpu_dai->driver->capture : &cpu_dai->driver->playback; 2891 + int cpu_capture = rtd->dai_link->params ? 2892 + SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; 2893 + int cpu_playback = rtd->dai_link->params ? 2894 + SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; 2920 2895 2921 - for_each_rtd_codec_dai(rtd, i, codec_dai) { 2896 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 2897 + if (rtd->num_cpus == 1) { 2898 + cpu_dai = rtd->cpu_dais[0]; 2899 + } else if (rtd->num_cpus == rtd->num_codecs) { 2900 + cpu_dai = rtd->cpu_dais[i]; 2901 + } else { 2902 + dev_err(rtd->card->dev, 2903 + "N cpus to M codecs link is not supported yet\n"); 2904 + return -EINVAL; 2905 + } 2906 + 2922 2907 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && 2923 - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) 2908 + snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) 2924 2909 playback = 1; 2925 2910 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && 2926 - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) 2911 + snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) 2927 2912 capture = 1; 2928 2913 } 2929 - 2930 - capture = capture && cpu_capture->channels_min; 2931 - playback = playback && cpu_playback->channels_min; 2932 2914 } 2933 2915 2934 2916 if (rtd->dai_link->playback_only) { ··· 3049 3017 out: 3050 3018 dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", 3051 3019 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, 3052 - cpu_dai->name); 3020 + (rtd->num_cpus > 1) ? "multicpu" : rtd->cpu_dai->name); 3053 3021 return ret; 3054 3022 } 3055 3023 ··· 3082 3050 } 3083 3051 EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream); 3084 3052 3085 - /* get the BE runtime state */ 3086 - enum snd_soc_dpcm_state 3087 - snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream) 3088 - { 3089 - return be->dpcm[stream].state; 3090 - } 3091 - EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state); 3092 - 3093 - /* set the BE runtime state */ 3094 - void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, 3095 - int stream, enum snd_soc_dpcm_state state) 3096 - { 3097 - be->dpcm[stream].state = state; 3098 - } 3099 - EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state); 3100 - 3101 - /* 3102 - * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE 3103 - * are not running, paused or suspended for the specified stream direction. 3104 - */ 3105 - int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, 3106 - struct snd_soc_pcm_runtime *be, int stream) 3053 + static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe, 3054 + struct snd_soc_pcm_runtime *be, 3055 + int stream, 3056 + const enum snd_soc_dpcm_state *states, 3057 + int num_states) 3107 3058 { 3108 3059 struct snd_soc_dpcm *dpcm; 3109 3060 int state; 3110 3061 int ret = 1; 3111 3062 unsigned long flags; 3063 + int i; 3112 3064 3113 3065 spin_lock_irqsave(&fe->card->dpcm_lock, flags); 3114 3066 for_each_dpcm_fe(be, stream, dpcm) { ··· 3101 3085 continue; 3102 3086 3103 3087 state = dpcm->fe->dpcm[stream].state; 3104 - if (state == SND_SOC_DPCM_STATE_START || 3105 - state == SND_SOC_DPCM_STATE_PAUSED || 3106 - state == SND_SOC_DPCM_STATE_SUSPEND) { 3107 - ret = 0; 3108 - break; 3088 + for (i = 0; i < num_states; i++) { 3089 + if (state == states[i]) { 3090 + ret = 0; 3091 + break; 3092 + } 3109 3093 } 3110 3094 } 3111 3095 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); 3112 3096 3113 - /* it's safe to free/stop this BE DAI */ 3097 + /* it's safe to do this BE DAI */ 3114 3098 return ret; 3099 + } 3100 + 3101 + /* 3102 + * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE 3103 + * are not running, paused or suspended for the specified stream direction. 3104 + */ 3105 + int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, 3106 + struct snd_soc_pcm_runtime *be, int stream) 3107 + { 3108 + const enum snd_soc_dpcm_state state[] = { 3109 + SND_SOC_DPCM_STATE_START, 3110 + SND_SOC_DPCM_STATE_PAUSED, 3111 + SND_SOC_DPCM_STATE_SUSPEND, 3112 + }; 3113 + 3114 + return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); 3115 3115 } 3116 3116 EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); 3117 3117 ··· 3138 3106 int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, 3139 3107 struct snd_soc_pcm_runtime *be, int stream) 3140 3108 { 3141 - struct snd_soc_dpcm *dpcm; 3142 - int state; 3143 - int ret = 1; 3144 - unsigned long flags; 3109 + const enum snd_soc_dpcm_state state[] = { 3110 + SND_SOC_DPCM_STATE_START, 3111 + SND_SOC_DPCM_STATE_PAUSED, 3112 + SND_SOC_DPCM_STATE_SUSPEND, 3113 + SND_SOC_DPCM_STATE_PREPARE, 3114 + }; 3145 3115 3146 - spin_lock_irqsave(&fe->card->dpcm_lock, flags); 3147 - for_each_dpcm_fe(be, stream, dpcm) { 3148 - 3149 - if (dpcm->fe == fe) 3150 - continue; 3151 - 3152 - state = dpcm->fe->dpcm[stream].state; 3153 - if (state == SND_SOC_DPCM_STATE_START || 3154 - state == SND_SOC_DPCM_STATE_PAUSED || 3155 - state == SND_SOC_DPCM_STATE_SUSPEND || 3156 - state == SND_SOC_DPCM_STATE_PREPARE) { 3157 - ret = 0; 3158 - break; 3159 - } 3160 - } 3161 - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); 3162 - 3163 - /* it's safe to change hw_params */ 3164 - return ret; 3116 + return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); 3165 3117 } 3166 3118 EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); 3167 - 3168 - #ifdef CONFIG_DEBUG_FS 3169 - static const char *dpcm_state_string(enum snd_soc_dpcm_state state) 3170 - { 3171 - switch (state) { 3172 - case SND_SOC_DPCM_STATE_NEW: 3173 - return "new"; 3174 - case SND_SOC_DPCM_STATE_OPEN: 3175 - return "open"; 3176 - case SND_SOC_DPCM_STATE_HW_PARAMS: 3177 - return "hw_params"; 3178 - case SND_SOC_DPCM_STATE_PREPARE: 3179 - return "prepare"; 3180 - case SND_SOC_DPCM_STATE_START: 3181 - return "start"; 3182 - case SND_SOC_DPCM_STATE_STOP: 3183 - return "stop"; 3184 - case SND_SOC_DPCM_STATE_SUSPEND: 3185 - return "suspend"; 3186 - case SND_SOC_DPCM_STATE_PAUSED: 3187 - return "paused"; 3188 - case SND_SOC_DPCM_STATE_HW_FREE: 3189 - return "hw_free"; 3190 - case SND_SOC_DPCM_STATE_CLOSE: 3191 - return "close"; 3192 - } 3193 - 3194 - return "unknown"; 3195 - } 3196 - 3197 - static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, 3198 - int stream, char *buf, size_t size) 3199 - { 3200 - struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; 3201 - struct snd_soc_dpcm *dpcm; 3202 - ssize_t offset = 0; 3203 - unsigned long flags; 3204 - 3205 - /* FE state */ 3206 - offset += scnprintf(buf + offset, size - offset, 3207 - "[%s - %s]\n", fe->dai_link->name, 3208 - stream ? "Capture" : "Playback"); 3209 - 3210 - offset += scnprintf(buf + offset, size - offset, "State: %s\n", 3211 - dpcm_state_string(fe->dpcm[stream].state)); 3212 - 3213 - if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && 3214 - (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) 3215 - offset += scnprintf(buf + offset, size - offset, 3216 - "Hardware Params: " 3217 - "Format = %s, Channels = %d, Rate = %d\n", 3218 - snd_pcm_format_name(params_format(params)), 3219 - params_channels(params), 3220 - params_rate(params)); 3221 - 3222 - /* BEs state */ 3223 - offset += scnprintf(buf + offset, size - offset, "Backends:\n"); 3224 - 3225 - if (list_empty(&fe->dpcm[stream].be_clients)) { 3226 - offset += scnprintf(buf + offset, size - offset, 3227 - " No active DSP links\n"); 3228 - goto out; 3229 - } 3230 - 3231 - spin_lock_irqsave(&fe->card->dpcm_lock, flags); 3232 - for_each_dpcm_be(fe, stream, dpcm) { 3233 - struct snd_soc_pcm_runtime *be = dpcm->be; 3234 - params = &dpcm->hw_params; 3235 - 3236 - offset += scnprintf(buf + offset, size - offset, 3237 - "- %s\n", be->dai_link->name); 3238 - 3239 - offset += scnprintf(buf + offset, size - offset, 3240 - " State: %s\n", 3241 - dpcm_state_string(be->dpcm[stream].state)); 3242 - 3243 - if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && 3244 - (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) 3245 - offset += scnprintf(buf + offset, size - offset, 3246 - " Hardware Params: " 3247 - "Format = %s, Channels = %d, Rate = %d\n", 3248 - snd_pcm_format_name(params_format(params)), 3249 - params_channels(params), 3250 - params_rate(params)); 3251 - } 3252 - spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); 3253 - out: 3254 - return offset; 3255 - } 3256 - 3257 - static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf, 3258 - size_t count, loff_t *ppos) 3259 - { 3260 - struct snd_soc_pcm_runtime *fe = file->private_data; 3261 - ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0; 3262 - char *buf; 3263 - 3264 - buf = kmalloc(out_count, GFP_KERNEL); 3265 - if (!buf) 3266 - return -ENOMEM; 3267 - 3268 - if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK)) 3269 - offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK, 3270 - buf + offset, out_count - offset); 3271 - 3272 - if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE)) 3273 - offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE, 3274 - buf + offset, out_count - offset); 3275 - 3276 - ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset); 3277 - 3278 - kfree(buf); 3279 - return ret; 3280 - } 3281 - 3282 - static const struct file_operations dpcm_state_fops = { 3283 - .open = simple_open, 3284 - .read = dpcm_state_read_file, 3285 - .llseek = default_llseek, 3286 - }; 3287 - 3288 - void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) 3289 - { 3290 - if (!rtd->dai_link) 3291 - return; 3292 - 3293 - if (!rtd->dai_link->dynamic) 3294 - return; 3295 - 3296 - if (!rtd->card->debugfs_card_root) 3297 - return; 3298 - 3299 - rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 3300 - rtd->card->debugfs_card_root); 3301 - 3302 - debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, 3303 - rtd, &dpcm_state_fops); 3304 - } 3305 - #endif
+14 -10
sound/soc/soc-topology.c
··· 251 251 { 252 252 int ret = 0; 253 253 254 - if (tplg->comp && tplg->ops && tplg->ops->vendor_load) 254 + if (tplg->ops && tplg->ops->vendor_load) 255 255 ret = tplg->ops->vendor_load(tplg->comp, tplg->index, hdr); 256 256 else { 257 257 dev_err(tplg->dev, "ASoC: no vendor load callback for ID %d\n", ··· 283 283 static int soc_tplg_widget_load(struct soc_tplg *tplg, 284 284 struct snd_soc_dapm_widget *w, struct snd_soc_tplg_dapm_widget *tplg_w) 285 285 { 286 - if (tplg->comp && tplg->ops && tplg->ops->widget_load) 286 + if (tplg->ops && tplg->ops->widget_load) 287 287 return tplg->ops->widget_load(tplg->comp, tplg->index, w, 288 288 tplg_w); 289 289 ··· 295 295 static int soc_tplg_widget_ready(struct soc_tplg *tplg, 296 296 struct snd_soc_dapm_widget *w, struct snd_soc_tplg_dapm_widget *tplg_w) 297 297 { 298 - if (tplg->comp && tplg->ops && tplg->ops->widget_ready) 298 + if (tplg->ops && tplg->ops->widget_ready) 299 299 return tplg->ops->widget_ready(tplg->comp, tplg->index, w, 300 300 tplg_w); 301 301 ··· 307 307 struct snd_soc_dai_driver *dai_drv, 308 308 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai) 309 309 { 310 - if (tplg->comp && tplg->ops && tplg->ops->dai_load) 310 + if (tplg->ops && tplg->ops->dai_load) 311 311 return tplg->ops->dai_load(tplg->comp, tplg->index, dai_drv, 312 312 pcm, dai); 313 313 ··· 318 318 static int soc_tplg_dai_link_load(struct soc_tplg *tplg, 319 319 struct snd_soc_dai_link *link, struct snd_soc_tplg_link_config *cfg) 320 320 { 321 - if (tplg->comp && tplg->ops && tplg->ops->link_load) 321 + if (tplg->ops && tplg->ops->link_load) 322 322 return tplg->ops->link_load(tplg->comp, tplg->index, link, cfg); 323 323 324 324 return 0; ··· 327 327 /* tell the component driver that all firmware has been loaded in this request */ 328 328 static void soc_tplg_complete(struct soc_tplg *tplg) 329 329 { 330 - if (tplg->comp && tplg->ops && tplg->ops->complete) 330 + if (tplg->ops && tplg->ops->complete) 331 331 tplg->ops->complete(tplg->comp); 332 332 } 333 333 ··· 684 684 static int soc_tplg_init_kcontrol(struct soc_tplg *tplg, 685 685 struct snd_kcontrol_new *k, struct snd_soc_tplg_ctl_hdr *hdr) 686 686 { 687 - if (tplg->comp && tplg->ops && tplg->ops->control_load) 687 + if (tplg->ops && tplg->ops->control_load) 688 688 return tplg->ops->control_load(tplg->comp, tplg->index, k, 689 689 hdr); 690 690 ··· 1174 1174 static int soc_tplg_add_route(struct soc_tplg *tplg, 1175 1175 struct snd_soc_dapm_route *route) 1176 1176 { 1177 - if (tplg->comp && tplg->ops && tplg->ops->dapm_route_load) 1177 + if (tplg->ops && tplg->ops->dapm_route_load) 1178 1178 return tplg->ops->dapm_route_load(tplg->comp, tplg->index, 1179 1179 route); 1180 1180 ··· 2564 2564 } 2565 2565 2566 2566 /* pass control to component driver for optional further init */ 2567 - if (tplg->comp && tplg->ops && tplg->ops->manifest) 2567 + if (tplg->ops && tplg->ops->manifest) 2568 2568 ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest); 2569 2569 2570 2570 if (!abi_match) /* free the duplicated one */ ··· 2736 2736 struct soc_tplg tplg; 2737 2737 int ret; 2738 2738 2739 + /* component needs to exist to keep and reference data while parsing */ 2740 + if (!comp) 2741 + return -EINVAL; 2742 + 2739 2743 /* setup parsing context */ 2740 2744 memset(&tplg, 0, sizeof(tplg)); 2741 2745 tplg.fw = fw; ··· 2778 2774 { 2779 2775 struct snd_soc_dapm_widget *w, *next_w; 2780 2776 2781 - list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) { 2777 + for_each_card_widgets_safe(dapm->card, w, next_w) { 2782 2778 2783 2779 /* make sure we are a widget with correct context */ 2784 2780 if (w->dobj.type != SND_SOC_DOBJ_WIDGET || w->dapm != dapm)
+9
sound/soc/sof/Kconfig
··· 41 41 required to enable i.MX8 devices. 42 42 Say Y if you need this option. If unsure select "N". 43 43 44 + config SND_SOC_SOF_DEBUG_PROBES 45 + bool "SOF enable data probing" 46 + select SND_SOC_COMPRESS 47 + help 48 + This option enables the data probing feature that can be used to 49 + gather data directly from specific points of the audio pipeline. 50 + Say Y if you want to enable probes. 51 + If unsure, select "N". 52 + 44 53 config SND_SOC_SOF_DEVELOPER_SUPPORT 45 54 bool "SOF developer options support" 46 55 depends on EXPERT
+1
sound/soc/sof/Makefile
··· 2 2 3 3 snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ 4 4 control.o trace.o utils.o sof-audio.o 5 + snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += probe.o compress.o 5 6 6 7 snd-sof-pci-objs := sof-pci-dev.o 7 8 snd-sof-acpi-objs := sof-acpi-dev.o
+146
sound/soc/sof/compress.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7 + // 8 + // Author: Cezary Rojewski <cezary.rojewski@intel.com> 9 + // 10 + 11 + #include <sound/soc.h> 12 + #include "compress.h" 13 + #include "ops.h" 14 + #include "probe.h" 15 + 16 + struct snd_compr_ops sof_probe_compressed_ops = { 17 + .copy = sof_probe_compr_copy, 18 + }; 19 + EXPORT_SYMBOL(sof_probe_compressed_ops); 20 + 21 + int sof_probe_compr_open(struct snd_compr_stream *cstream, 22 + struct snd_soc_dai *dai) 23 + { 24 + struct snd_sof_dev *sdev = 25 + snd_soc_component_get_drvdata(dai->component); 26 + int ret; 27 + 28 + ret = snd_sof_probe_compr_assign(sdev, cstream, dai); 29 + if (ret < 0) { 30 + dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret); 31 + return ret; 32 + } 33 + 34 + sdev->extractor_stream_tag = ret; 35 + return 0; 36 + } 37 + EXPORT_SYMBOL(sof_probe_compr_open); 38 + 39 + int sof_probe_compr_free(struct snd_compr_stream *cstream, 40 + struct snd_soc_dai *dai) 41 + { 42 + struct snd_sof_dev *sdev = 43 + snd_soc_component_get_drvdata(dai->component); 44 + struct sof_probe_point_desc *desc; 45 + size_t num_desc; 46 + int i, ret; 47 + 48 + /* disconnect all probe points */ 49 + ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc); 50 + if (ret < 0) { 51 + dev_err(dai->dev, "Failed to get probe points: %d\n", ret); 52 + goto exit; 53 + } 54 + 55 + for (i = 0; i < num_desc; i++) 56 + sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1); 57 + kfree(desc); 58 + 59 + exit: 60 + ret = sof_ipc_probe_deinit(sdev); 61 + if (ret < 0) 62 + dev_err(dai->dev, "Failed to deinit probe: %d\n", ret); 63 + 64 + sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; 65 + snd_compr_free_pages(cstream); 66 + 67 + return snd_sof_probe_compr_free(sdev, cstream, dai); 68 + } 69 + EXPORT_SYMBOL(sof_probe_compr_free); 70 + 71 + int sof_probe_compr_set_params(struct snd_compr_stream *cstream, 72 + struct snd_compr_params *params, struct snd_soc_dai *dai) 73 + { 74 + struct snd_compr_runtime *rtd = cstream->runtime; 75 + struct snd_sof_dev *sdev = 76 + snd_soc_component_get_drvdata(dai->component); 77 + int ret; 78 + 79 + cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG; 80 + cstream->dma_buffer.dev.dev = sdev->dev; 81 + ret = snd_compr_malloc_pages(cstream, rtd->buffer_size); 82 + if (ret < 0) 83 + return ret; 84 + 85 + ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai); 86 + if (ret < 0) 87 + return ret; 88 + 89 + ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag, 90 + rtd->dma_bytes); 91 + if (ret < 0) { 92 + dev_err(dai->dev, "Failed to init probe: %d\n", ret); 93 + return ret; 94 + } 95 + 96 + return 0; 97 + } 98 + EXPORT_SYMBOL(sof_probe_compr_set_params); 99 + 100 + int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, 101 + struct snd_soc_dai *dai) 102 + { 103 + struct snd_sof_dev *sdev = 104 + snd_soc_component_get_drvdata(dai->component); 105 + 106 + return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai); 107 + } 108 + EXPORT_SYMBOL(sof_probe_compr_trigger); 109 + 110 + int sof_probe_compr_pointer(struct snd_compr_stream *cstream, 111 + struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) 112 + { 113 + struct snd_sof_dev *sdev = 114 + snd_soc_component_get_drvdata(dai->component); 115 + 116 + return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai); 117 + } 118 + EXPORT_SYMBOL(sof_probe_compr_pointer); 119 + 120 + int sof_probe_compr_copy(struct snd_compr_stream *cstream, 121 + char __user *buf, size_t count) 122 + { 123 + struct snd_compr_runtime *rtd = cstream->runtime; 124 + unsigned int offset, n; 125 + void *ptr; 126 + int ret; 127 + 128 + if (count > rtd->buffer_size) 129 + count = rtd->buffer_size; 130 + 131 + div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset); 132 + ptr = rtd->dma_area + offset; 133 + n = rtd->buffer_size - offset; 134 + 135 + if (count < n) { 136 + ret = copy_to_user(buf, ptr, count); 137 + } else { 138 + ret = copy_to_user(buf, ptr, n); 139 + ret += copy_to_user(buf + n, rtd->dma_area, count - n); 140 + } 141 + 142 + if (ret) 143 + return count - ret; 144 + return count; 145 + } 146 + EXPORT_SYMBOL(sof_probe_compr_copy);
+31
sound/soc/sof/compress.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 + /* 3 + * This file is provided under a dual BSD/GPLv2 license. When using or 4 + * redistributing this file, you may do so under either license. 5 + * 6 + * Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7 + * 8 + * Author: Cezary Rojewski <cezary.rojewski@intel.com> 9 + */ 10 + 11 + #ifndef __SOF_COMPRESS_H 12 + #define __SOF_COMPRESS_H 13 + 14 + #include <sound/compress_driver.h> 15 + 16 + extern struct snd_compr_ops sof_probe_compressed_ops; 17 + 18 + int sof_probe_compr_open(struct snd_compr_stream *cstream, 19 + struct snd_soc_dai *dai); 20 + int sof_probe_compr_free(struct snd_compr_stream *cstream, 21 + struct snd_soc_dai *dai); 22 + int sof_probe_compr_set_params(struct snd_compr_stream *cstream, 23 + struct snd_compr_params *params, struct snd_soc_dai *dai); 24 + int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, 25 + struct snd_soc_dai *dai); 26 + int sof_probe_compr_pointer(struct snd_compr_stream *cstream, 27 + struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai); 28 + int sof_probe_compr_copy(struct snd_compr_stream *cstream, 29 + char __user *buf, size_t count); 30 + 31 + #endif
+8 -2
sound/soc/sof/core.c
··· 14 14 #include <sound/sof.h> 15 15 #include "sof-priv.h" 16 16 #include "ops.h" 17 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 18 + #include "probe.h" 19 + #endif 17 20 18 21 /* see SOF_DBG_ flags */ 19 22 int sof_core_debug; ··· 289 286 /* initialize sof device */ 290 287 sdev->dev = dev; 291 288 292 - /* initialize default D0 sub-state */ 293 - sdev->d0_substate = SOF_DSP_D0I0; 289 + /* initialize default DSP power state */ 290 + sdev->dsp_power_state.state = SOF_DSP_PM_D0; 294 291 295 292 sdev->pdata = plat_data; 296 293 sdev->first_boot = true; 297 294 sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; 295 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 296 + sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; 297 + #endif 298 298 dev_set_drvdata(dev, sdev); 299 299 300 300 /* check all mandatory ops */
+226
sound/soc/sof/debug.c
··· 17 17 #include "sof-priv.h" 18 18 #include "ops.h" 19 19 20 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 21 + #include "probe.h" 22 + 23 + /** 24 + * strsplit_u32 - Split string into sequence of u32 tokens 25 + * @buf: String to split into tokens. 26 + * @delim: String containing delimiter characters. 27 + * @tkns: Returned u32 sequence pointer. 28 + * @num_tkns: Returned number of tokens obtained. 29 + */ 30 + static int 31 + strsplit_u32(char **buf, const char *delim, u32 **tkns, size_t *num_tkns) 32 + { 33 + char *s; 34 + u32 *data, *tmp; 35 + size_t count = 0; 36 + size_t cap = 32; 37 + int ret = 0; 38 + 39 + *tkns = NULL; 40 + *num_tkns = 0; 41 + data = kcalloc(cap, sizeof(*data), GFP_KERNEL); 42 + if (!data) 43 + return -ENOMEM; 44 + 45 + while ((s = strsep(buf, delim)) != NULL) { 46 + ret = kstrtouint(s, 0, data + count); 47 + if (ret) 48 + goto exit; 49 + if (++count >= cap) { 50 + cap *= 2; 51 + tmp = krealloc(data, cap * sizeof(*data), GFP_KERNEL); 52 + if (!tmp) { 53 + ret = -ENOMEM; 54 + goto exit; 55 + } 56 + data = tmp; 57 + } 58 + } 59 + 60 + if (!count) 61 + goto exit; 62 + *tkns = kmemdup(data, count * sizeof(*data), GFP_KERNEL); 63 + if (*tkns == NULL) { 64 + ret = -ENOMEM; 65 + goto exit; 66 + } 67 + *num_tkns = count; 68 + 69 + exit: 70 + kfree(data); 71 + return ret; 72 + } 73 + 74 + static int tokenize_input(const char __user *from, size_t count, 75 + loff_t *ppos, u32 **tkns, size_t *num_tkns) 76 + { 77 + char *buf; 78 + int ret; 79 + 80 + buf = kmalloc(count + 1, GFP_KERNEL); 81 + if (!buf) 82 + return -ENOMEM; 83 + 84 + ret = simple_write_to_buffer(buf, count, ppos, from, count); 85 + if (ret != count) { 86 + ret = ret >= 0 ? -EIO : ret; 87 + goto exit; 88 + } 89 + 90 + buf[count] = '\0'; 91 + ret = strsplit_u32((char **)&buf, ",", tkns, num_tkns); 92 + exit: 93 + kfree(buf); 94 + return ret; 95 + } 96 + 97 + static ssize_t probe_points_read(struct file *file, 98 + char __user *to, size_t count, loff_t *ppos) 99 + { 100 + struct snd_sof_dfsentry *dfse = file->private_data; 101 + struct snd_sof_dev *sdev = dfse->sdev; 102 + struct sof_probe_point_desc *desc; 103 + size_t num_desc, len = 0; 104 + char *buf; 105 + int i, ret; 106 + 107 + if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 108 + dev_warn(sdev->dev, "no extractor stream running\n"); 109 + return -ENOENT; 110 + } 111 + 112 + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); 113 + if (!buf) 114 + return -ENOMEM; 115 + 116 + ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc); 117 + if (ret < 0) 118 + goto exit; 119 + 120 + for (i = 0; i < num_desc; i++) { 121 + ret = snprintf(buf + len, PAGE_SIZE - len, 122 + "Id: %#010x Purpose: %d Node id: %#x\n", 123 + desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); 124 + if (ret < 0) 125 + goto free_desc; 126 + len += ret; 127 + } 128 + 129 + ret = simple_read_from_buffer(to, count, ppos, buf, len); 130 + free_desc: 131 + kfree(desc); 132 + exit: 133 + kfree(buf); 134 + return ret; 135 + } 136 + 137 + static ssize_t probe_points_write(struct file *file, 138 + const char __user *from, size_t count, loff_t *ppos) 139 + { 140 + struct snd_sof_dfsentry *dfse = file->private_data; 141 + struct snd_sof_dev *sdev = dfse->sdev; 142 + struct sof_probe_point_desc *desc; 143 + size_t num_tkns, bytes; 144 + u32 *tkns; 145 + int ret; 146 + 147 + if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 148 + dev_warn(sdev->dev, "no extractor stream running\n"); 149 + return -ENOENT; 150 + } 151 + 152 + ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); 153 + if (ret < 0) 154 + return ret; 155 + bytes = sizeof(*tkns) * num_tkns; 156 + if (!num_tkns || (bytes % sizeof(*desc))) { 157 + ret = -EINVAL; 158 + goto exit; 159 + } 160 + 161 + desc = (struct sof_probe_point_desc *)tkns; 162 + ret = sof_ipc_probe_points_add(sdev, 163 + desc, bytes / sizeof(*desc)); 164 + if (!ret) 165 + ret = count; 166 + exit: 167 + kfree(tkns); 168 + return ret; 169 + } 170 + 171 + static const struct file_operations probe_points_fops = { 172 + .open = simple_open, 173 + .read = probe_points_read, 174 + .write = probe_points_write, 175 + .llseek = default_llseek, 176 + }; 177 + 178 + static ssize_t probe_points_remove_write(struct file *file, 179 + const char __user *from, size_t count, loff_t *ppos) 180 + { 181 + struct snd_sof_dfsentry *dfse = file->private_data; 182 + struct snd_sof_dev *sdev = dfse->sdev; 183 + size_t num_tkns; 184 + u32 *tkns; 185 + int ret; 186 + 187 + if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) { 188 + dev_warn(sdev->dev, "no extractor stream running\n"); 189 + return -ENOENT; 190 + } 191 + 192 + ret = tokenize_input(from, count, ppos, &tkns, &num_tkns); 193 + if (ret < 0) 194 + return ret; 195 + if (!num_tkns) { 196 + ret = -EINVAL; 197 + goto exit; 198 + } 199 + 200 + ret = sof_ipc_probe_points_remove(sdev, tkns, num_tkns); 201 + if (!ret) 202 + ret = count; 203 + exit: 204 + kfree(tkns); 205 + return ret; 206 + } 207 + 208 + static const struct file_operations probe_points_remove_fops = { 209 + .open = simple_open, 210 + .write = probe_points_remove_write, 211 + .llseek = default_llseek, 212 + }; 213 + 214 + static int snd_sof_debugfs_probe_item(struct snd_sof_dev *sdev, 215 + const char *name, mode_t mode, 216 + const struct file_operations *fops) 217 + { 218 + struct snd_sof_dfsentry *dfse; 219 + 220 + dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); 221 + if (!dfse) 222 + return -ENOMEM; 223 + 224 + dfse->type = SOF_DFSENTRY_TYPE_BUF; 225 + dfse->sdev = sdev; 226 + 227 + debugfs_create_file(name, mode, sdev->debugfs_root, dfse, fops); 228 + /* add to dfsentry list */ 229 + list_add(&dfse->list, &sdev->dfsentry_list); 230 + 231 + return 0; 232 + } 233 + #endif 234 + 20 235 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) 21 236 #define MAX_IPC_FLOOD_DURATION_MS 1000 22 237 #define MAX_IPC_FLOOD_COUNT 10000 ··· 650 435 if (err < 0) 651 436 return err; 652 437 } 438 + 439 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 440 + err = snd_sof_debugfs_probe_item(sdev, "probe_points", 441 + 0644, &probe_points_fops); 442 + if (err < 0) 443 + return err; 444 + err = snd_sof_debugfs_probe_item(sdev, "probe_points_remove", 445 + 0200, &probe_points_remove_fops); 446 + if (err < 0) 447 + return err; 448 + #endif 653 449 654 450 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) 655 451 /* create read-write ipc_flood_count debugfs entry */
+54 -3
sound/soc/sof/imx/imx8.c
··· 138 138 /* 139 139 * DSP control. 140 140 */ 141 - static int imx8_run(struct snd_sof_dev *sdev) 141 + static int imx8x_run(struct snd_sof_dev *sdev) 142 142 { 143 143 struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private; 144 144 int ret; ··· 169 169 IMX_SC_C_OFS_IRQ, 0x51); 170 170 if (ret < 0) { 171 171 dev_err(sdev->dev, "Error system address offset of IRQ\n"); 172 + return ret; 173 + } 174 + 175 + imx_sc_pm_cpu_start(dsp_priv->sc_ipc, IMX_SC_R_DSP, true, 176 + RESET_VECTOR_VADDR); 177 + 178 + return 0; 179 + } 180 + 181 + static int imx8_run(struct snd_sof_dev *sdev) 182 + { 183 + struct imx8_priv *dsp_priv = (struct imx8_priv *)sdev->private; 184 + int ret; 185 + 186 + ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, 187 + IMX_SC_C_OFS_SEL, 0); 188 + if (ret < 0) { 189 + dev_err(sdev->dev, "Error system address offset source select\n"); 172 190 return ret; 173 191 } 174 192 ··· 378 360 }, 379 361 }; 380 362 381 - /* i.MX8 ops */ 363 + /* i.MX8 ops */ 382 364 struct snd_sof_dsp_ops sof_imx8_ops = { 383 365 /* probe and remove */ 384 366 .probe = imx8_probe, 385 367 .remove = imx8_remove, 386 368 /* DSP core boot */ 387 369 .run = imx8_run, 370 + 371 + /* Block IO */ 372 + .block_read = sof_block_read, 373 + .block_write = sof_block_write, 374 + 375 + /* ipc */ 376 + .send_msg = imx8_send_msg, 377 + .fw_ready = sof_fw_ready, 378 + .get_mailbox_offset = imx8_get_mailbox_offset, 379 + .get_window_offset = imx8_get_window_offset, 380 + 381 + .ipc_msg_data = imx8_ipc_msg_data, 382 + .ipc_pcm_params = imx8_ipc_pcm_params, 383 + 384 + /* module loading */ 385 + .load_module = snd_sof_parse_module_memcpy, 386 + .get_bar_index = imx8_get_bar_index, 387 + /* firmware loading */ 388 + .load_firmware = snd_sof_load_firmware_memcpy, 389 + 390 + /* DAI drivers */ 391 + .drv = imx8_dai, 392 + .num_drv = 1, /* we have only 1 ESAI interface on i.MX8 */ 393 + }; 394 + EXPORT_SYMBOL(sof_imx8_ops); 395 + 396 + /* i.MX8X ops */ 397 + struct snd_sof_dsp_ops sof_imx8x_ops = { 398 + /* probe and remove */ 399 + .probe = imx8_probe, 400 + .remove = imx8_remove, 401 + /* DSP core boot */ 402 + .run = imx8x_run, 388 403 389 404 /* Block IO */ 390 405 .block_read = sof_block_read, ··· 449 398 SNDRV_PCM_INFO_PAUSE | 450 399 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 451 400 }; 452 - EXPORT_SYMBOL(sof_imx8_ops); 401 + EXPORT_SYMBOL(sof_imx8x_ops); 453 402 454 403 MODULE_LICENSE("Dual BSD/GPL");
+9 -11
sound/soc/sof/intel/Kconfig
··· 305 305 Say Y if you want to enable HDAudio codecs with SOF. 306 306 If unsure select "N". 307 307 308 + config SND_SOC_SOF_HDA_PROBES 309 + bool "SOF enable probes over HDA" 310 + depends on SND_SOC_SOF_DEBUG_PROBES 311 + help 312 + This option enables the data probing for Intel(R). 313 + Intel(R) Skylake and newer platforms. 314 + Say Y if you want to enable probes. 315 + If unsure, select "N". 316 + 308 317 config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 309 318 bool "SOF enable DMI Link L1" 310 319 help ··· 323 314 affected by DMI L1 issues. This option is not recommended. 324 315 Say Y if you want to enable DMI Link L1 325 316 If unsure, select "N". 326 - 327 - config SND_SOC_SOF_HDA_COMMON_HDMI_CODEC 328 - bool "SOF common HDA HDMI codec driver" 329 - depends on SND_SOC_SOF_HDA_LINK 330 - depends on SND_HDA_CODEC_HDMI 331 - default SND_HDA_CODEC_HDMI 332 - help 333 - This adds support for HDMI audio by using the common HDA 334 - HDMI/DisplayPort codec driver. 335 - Say Y if you want to use the common codec driver with SOF. 336 - If unsure select "Y". 337 317 338 318 endif ## SND_SOC_SOF_HDA_COMMON 339 319
+1
sound/soc/sof/intel/Makefile
··· 9 9 hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ 10 10 hda-dai.o hda-bus.o \ 11 11 apl.o cnl.o 12 + snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o 12 13 13 14 snd-sof-intel-hda-objs := hda-codec.o 14 15
+9
sound/soc/sof/intel/apl.c
··· 73 73 .pcm_trigger = hda_dsp_pcm_trigger, 74 74 .pcm_pointer = hda_dsp_pcm_pointer, 75 75 76 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 77 + /* probe callbacks */ 78 + .probe_assign = hda_probe_compr_assign, 79 + .probe_free = hda_probe_compr_free, 80 + .probe_set_params = hda_probe_compr_set_params, 81 + .probe_trigger = hda_probe_compr_trigger, 82 + .probe_pointer = hda_probe_compr_pointer, 83 + #endif 84 + 76 85 /* firmware loading */ 77 86 .load_firmware = snd_sof_load_firmware_raw, 78 87
+40 -11
sound/soc/sof/intel/cnl.c
··· 65 65 hda_dsp_ipc_get_reply(sdev); 66 66 snd_sof_ipc_reply(sdev, msg); 67 67 68 - if (sdev->code_loading) { 69 - sdev->code_loading = 0; 70 - wake_up(&sdev->waitq); 71 - } 72 - 73 68 cnl_ipc_dsp_done(sdev); 74 69 75 70 spin_unlock_irq(&sdev->ipc_lock); ··· 166 171 static int cnl_ipc_send_msg(struct snd_sof_dev *sdev, 167 172 struct snd_sof_ipc_msg *msg) 168 173 { 174 + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 175 + struct sof_ipc_cmd_hdr *hdr; 169 176 u32 dr = 0; 170 177 u32 dd = 0; 171 178 179 + /* 180 + * Currently the only compact IPC supported is the PM_GATE 181 + * IPC which is used for transitioning the DSP between the 182 + * D0I0 and D0I3 states. And these are sent only during the 183 + * set_power_state() op. Therefore, there will never be a case 184 + * that a compact IPC results in the DSP exiting D0I3 without 185 + * the host and FW being in sync. 186 + */ 172 187 if (cnl_compact_ipc_compress(msg, &dr, &dd)) { 173 188 /* send the message via IPC registers */ 174 189 snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDD, 175 190 dd); 176 191 snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, 177 192 CNL_DSP_REG_HIPCIDR_BUSY | dr); 178 - } else { 179 - /* send the message via mailbox */ 180 - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 181 - msg->msg_size); 182 - snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, 183 - CNL_DSP_REG_HIPCIDR_BUSY); 193 + return 0; 184 194 } 195 + 196 + /* send the message via mailbox */ 197 + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 198 + msg->msg_size); 199 + snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, 200 + CNL_DSP_REG_HIPCIDR_BUSY); 201 + 202 + hdr = msg->msg_data; 203 + 204 + /* 205 + * Use mod_delayed_work() to schedule the delayed work 206 + * to avoid scheduling multiple workqueue items when 207 + * IPCs are sent at a high-rate. mod_delayed_work() 208 + * modifies the timer if the work is pending. 209 + * Also, a new delayed work should not be queued after the 210 + * the CTX_SAVE IPC, which is sent before the DSP enters D3. 211 + */ 212 + if (hdr->cmd != (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CTX_SAVE)) 213 + mod_delayed_work(system_wq, &hdev->d0i3_work, 214 + msecs_to_jiffies(SOF_HDA_D0I3_WORK_DELAY_MS)); 185 215 186 216 return 0; 187 217 } ··· 278 258 .pcm_hw_free = hda_dsp_stream_hw_free, 279 259 .pcm_trigger = hda_dsp_pcm_trigger, 280 260 .pcm_pointer = hda_dsp_pcm_pointer, 261 + 262 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 263 + /* probe callbacks */ 264 + .probe_assign = hda_probe_compr_assign, 265 + .probe_free = hda_probe_compr_free, 266 + .probe_set_params = hda_probe_compr_set_params, 267 + .probe_trigger = hda_probe_compr_trigger, 268 + .probe_pointer = hda_probe_compr_pointer, 269 + #endif 281 270 282 271 /* firmware loading */ 283 272 .load_firmware = snd_sof_load_firmware_raw,
+10 -1
sound/soc/sof/intel/hda-codec.c
··· 113 113 if (ret < 0) 114 114 return ret; 115 115 116 - if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) 116 + if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) { 117 + if (!hdev->bus->audio_component) { 118 + dev_dbg(sdev->dev, 119 + "iDisp hw present but no driver\n"); 120 + return -ENOENT; 121 + } 117 122 hda_priv->need_display_power = true; 123 + } 118 124 119 125 /* 120 126 * if common HDMI codec driver is not used, codec load ··· 208 202 { 209 203 struct hdac_bus *bus = sof_to_bus(sdev); 210 204 int ret; 205 + 206 + if (!bus->audio_component) 207 + return 0; 211 208 212 209 /* power down unconditionally */ 213 210 snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
+114
sound/soc/sof/intel/hda-compress.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7 + // 8 + // Author: Cezary Rojewski <cezary.rojewski@intel.com> 9 + // 10 + 11 + #include <sound/hdaudio_ext.h> 12 + #include <sound/soc.h> 13 + #include "../sof-priv.h" 14 + #include "hda.h" 15 + 16 + static inline struct hdac_ext_stream * 17 + hda_compr_get_stream(struct snd_compr_stream *cstream) 18 + { 19 + return cstream->runtime->private_data; 20 + } 21 + 22 + int hda_probe_compr_assign(struct snd_sof_dev *sdev, 23 + struct snd_compr_stream *cstream, 24 + struct snd_soc_dai *dai) 25 + { 26 + struct hdac_ext_stream *stream; 27 + 28 + stream = hda_dsp_stream_get(sdev, cstream->direction); 29 + if (!stream) 30 + return -EBUSY; 31 + 32 + hdac_stream(stream)->curr_pos = 0; 33 + hdac_stream(stream)->cstream = cstream; 34 + cstream->runtime->private_data = stream; 35 + 36 + return hdac_stream(stream)->stream_tag; 37 + } 38 + 39 + int hda_probe_compr_free(struct snd_sof_dev *sdev, 40 + struct snd_compr_stream *cstream, 41 + struct snd_soc_dai *dai) 42 + { 43 + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); 44 + int ret; 45 + 46 + ret = hda_dsp_stream_put(sdev, cstream->direction, 47 + hdac_stream(stream)->stream_tag); 48 + if (ret < 0) { 49 + dev_dbg(sdev->dev, "stream put failed: %d\n", ret); 50 + return ret; 51 + } 52 + 53 + hdac_stream(stream)->cstream = NULL; 54 + cstream->runtime->private_data = NULL; 55 + 56 + return 0; 57 + } 58 + 59 + int hda_probe_compr_set_params(struct snd_sof_dev *sdev, 60 + struct snd_compr_stream *cstream, 61 + struct snd_compr_params *params, 62 + struct snd_soc_dai *dai) 63 + { 64 + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); 65 + struct hdac_stream *hstream = hdac_stream(stream); 66 + struct snd_dma_buffer *dmab; 67 + u32 bits, rate; 68 + int bps, ret; 69 + 70 + dmab = cstream->runtime->dma_buffer_p; 71 + /* compr params do not store bit depth, default to S32_LE */ 72 + bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE); 73 + if (bps < 0) 74 + return bps; 75 + bits = hda_dsp_get_bits(sdev, bps); 76 + rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate); 77 + 78 + hstream->format_val = rate | bits | (params->codec.ch_out - 1); 79 + hstream->bufsize = cstream->runtime->buffer_size; 80 + hstream->period_bytes = cstream->runtime->fragment_size; 81 + hstream->no_period_wakeup = 0; 82 + 83 + ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); 84 + if (ret < 0) { 85 + dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); 86 + return ret; 87 + } 88 + 89 + return 0; 90 + } 91 + 92 + int hda_probe_compr_trigger(struct snd_sof_dev *sdev, 93 + struct snd_compr_stream *cstream, int cmd, 94 + struct snd_soc_dai *dai) 95 + { 96 + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); 97 + 98 + return hda_dsp_stream_trigger(sdev, stream, cmd); 99 + } 100 + 101 + int hda_probe_compr_pointer(struct snd_sof_dev *sdev, 102 + struct snd_compr_stream *cstream, 103 + struct snd_compr_tstamp *tstamp, 104 + struct snd_soc_dai *dai) 105 + { 106 + struct hdac_ext_stream *stream = hda_compr_get_stream(cstream); 107 + struct snd_soc_pcm_stream *pstream; 108 + 109 + pstream = &dai->driver->capture; 110 + tstamp->copied_total = hdac_stream(stream)->curr_pos; 111 + tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates); 112 + 113 + return 0; 114 + }
+33 -7
sound/soc/sof/intel/hda-ctrl.c
··· 18 18 #include <linux/module.h> 19 19 #include <sound/hdaudio_ext.h> 20 20 #include <sound/hda_register.h> 21 + #include <sound/hda_component.h> 21 22 #include "../ops.h" 22 23 #include "hda.h" 23 24 ··· 65 64 struct hdac_bus *bus = sof_to_bus(sdev); 66 65 u32 cap, offset, feature; 67 66 int count = 0; 67 + int ret; 68 + 69 + /* 70 + * On some devices, one reset cycle is necessary before reading 71 + * capabilities 72 + */ 73 + ret = hda_dsp_ctrl_link_reset(sdev, true); 74 + if (ret < 0) 75 + return ret; 76 + ret = hda_dsp_ctrl_link_reset(sdev, false); 77 + if (ret < 0) 78 + return ret; 68 79 69 80 offset = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_LLCH); 70 81 71 82 do { 72 - cap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, offset); 73 - 74 83 dev_dbg(sdev->dev, "checking for capabilities at offset 0x%x\n", 75 84 offset & SOF_HDA_CAP_NEXT_MASK); 85 + 86 + cap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, offset); 87 + 88 + if (cap == -1) { 89 + dev_dbg(bus->dev, "Invalid capability reg read\n"); 90 + break; 91 + } 76 92 77 93 feature = (cap & SOF_HDA_CAP_ID_MASK) >> SOF_HDA_CAP_ID_OFF; 78 94 ··· 123 105 bus->mlcap = bus->remap_addr + offset; 124 106 break; 125 107 default: 126 - dev_vdbg(sdev->dev, "found capability %d at 0x%x\n", 127 - feature, offset); 108 + dev_dbg(sdev->dev, "found capability %d at 0x%x\n", 109 + feature, offset); 128 110 break; 129 111 } 130 112 ··· 194 176 if (bus->chip_init) 195 177 return 0; 196 178 179 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 180 + snd_hdac_set_codec_wakeup(bus, true); 181 + #endif 197 182 hda_dsp_ctrl_misc_clock_gating(sdev, false); 198 183 199 184 if (full_reset) { ··· 204 183 ret = hda_dsp_ctrl_link_reset(sdev, true); 205 184 if (ret < 0) { 206 185 dev_err(sdev->dev, "error: failed to reset HDA controller\n"); 207 - return ret; 186 + goto err; 208 187 } 209 188 210 189 usleep_range(500, 1000); ··· 213 192 ret = hda_dsp_ctrl_link_reset(sdev, false); 214 193 if (ret < 0) { 215 194 dev_err(sdev->dev, "error: failed to exit HDA controller reset\n"); 216 - return ret; 195 + goto err; 217 196 } 218 197 219 198 usleep_range(1000, 1200); ··· 223 202 /* check to see if controller is ready */ 224 203 if (!snd_hdac_chip_readb(bus, GCTL)) { 225 204 dev_dbg(bus->dev, "controller not ready!\n"); 226 - return -EBUSY; 205 + ret = -EBUSY; 206 + goto err; 227 207 } 228 208 229 209 /* Accept unsolicited responses */ ··· 290 268 291 269 bus->chip_init = true; 292 270 271 + err: 293 272 hda_dsp_ctrl_misc_clock_gating(sdev, true); 273 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 274 + snd_hdac_set_codec_wakeup(bus, false); 275 + #endif 294 276 295 277 return ret; 296 278 }
+127 -3
sound/soc/sof/intel/hda-dai.c
··· 204 204 struct hdac_bus *bus = hstream->bus; 205 205 struct hdac_ext_stream *link_dev; 206 206 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 207 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 207 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 208 208 struct sof_intel_hda_stream *hda_stream; 209 209 struct hda_pipe_params p_params = {0}; 210 210 struct hdac_ext_link *link; ··· 293 293 bus = hstream->bus; 294 294 rtd = snd_pcm_substream_chip(substream); 295 295 296 - link = snd_hdac_ext_bus_get_link(bus, rtd->codec_dai->component->name); 296 + link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name); 297 297 if (!link) 298 298 return -EINVAL; 299 299 ··· 374 374 if (ret < 0) 375 375 return ret; 376 376 377 - link = snd_hdac_ext_bus_get_link(bus, rtd->codec_dai->component->name); 377 + link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name); 378 378 if (!link) 379 379 return -EINVAL; 380 380 ··· 399 399 .trigger = hda_link_pcm_trigger, 400 400 .prepare = hda_link_pcm_prepare, 401 401 }; 402 + 403 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 404 + #include "../compress.h" 405 + 406 + static struct snd_soc_cdai_ops sof_probe_compr_ops = { 407 + .startup = sof_probe_compr_open, 408 + .shutdown = sof_probe_compr_free, 409 + .set_params = sof_probe_compr_set_params, 410 + .trigger = sof_probe_compr_trigger, 411 + .pointer = sof_probe_compr_pointer, 412 + }; 413 + 414 + #endif 402 415 #endif 403 416 404 417 /* ··· 422 409 struct snd_soc_dai_driver skl_dai[] = { 423 410 { 424 411 .name = "SSP0 Pin", 412 + .playback = { 413 + .channels_min = 1, 414 + .channels_max = 8, 415 + }, 416 + .capture = { 417 + .channels_min = 1, 418 + .channels_max = 8, 419 + }, 425 420 }, 426 421 { 427 422 .name = "SSP1 Pin", 423 + .playback = { 424 + .channels_min = 1, 425 + .channels_max = 8, 426 + }, 427 + .capture = { 428 + .channels_min = 1, 429 + .channels_max = 8, 430 + }, 428 431 }, 429 432 { 430 433 .name = "SSP2 Pin", 434 + .playback = { 435 + .channels_min = 1, 436 + .channels_max = 8, 437 + }, 438 + .capture = { 439 + .channels_min = 1, 440 + .channels_max = 8, 441 + }, 431 442 }, 432 443 { 433 444 .name = "SSP3 Pin", 445 + .playback = { 446 + .channels_min = 1, 447 + .channels_max = 8, 448 + }, 449 + .capture = { 450 + .channels_min = 1, 451 + .channels_max = 8, 452 + }, 434 453 }, 435 454 { 436 455 .name = "SSP4 Pin", 456 + .playback = { 457 + .channels_min = 1, 458 + .channels_max = 8, 459 + }, 460 + .capture = { 461 + .channels_min = 1, 462 + .channels_max = 8, 463 + }, 437 464 }, 438 465 { 439 466 .name = "SSP5 Pin", 467 + .playback = { 468 + .channels_min = 1, 469 + .channels_max = 8, 470 + }, 471 + .capture = { 472 + .channels_min = 1, 473 + .channels_max = 8, 474 + }, 440 475 }, 441 476 { 442 477 .name = "DMIC01 Pin", 478 + .capture = { 479 + .channels_min = 1, 480 + .channels_max = 4, 481 + }, 443 482 }, 444 483 { 445 484 .name = "DMIC16k Pin", 485 + .capture = { 486 + .channels_min = 1, 487 + .channels_max = 4, 488 + }, 446 489 }, 447 490 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 448 491 { 449 492 .name = "iDisp1 Pin", 450 493 .ops = &hda_link_dai_ops, 494 + .playback = { 495 + .channels_min = 1, 496 + .channels_max = 8, 497 + }, 451 498 }, 452 499 { 453 500 .name = "iDisp2 Pin", 454 501 .ops = &hda_link_dai_ops, 502 + .playback = { 503 + .channels_min = 1, 504 + .channels_max = 8, 505 + }, 455 506 }, 456 507 { 457 508 .name = "iDisp3 Pin", 458 509 .ops = &hda_link_dai_ops, 510 + .playback = { 511 + .channels_min = 1, 512 + .channels_max = 8, 513 + }, 459 514 }, 460 515 { 461 516 .name = "iDisp4 Pin", 462 517 .ops = &hda_link_dai_ops, 518 + .playback = { 519 + .channels_min = 1, 520 + .channels_max = 8, 521 + }, 463 522 }, 464 523 { 465 524 .name = "Analog CPU DAI", 466 525 .ops = &hda_link_dai_ops, 526 + .playback = { 527 + .channels_min = 1, 528 + .channels_max = 16, 529 + }, 530 + .capture = { 531 + .channels_min = 1, 532 + .channels_max = 16, 533 + }, 467 534 }, 468 535 { 469 536 .name = "Digital CPU DAI", 470 537 .ops = &hda_link_dai_ops, 538 + .playback = { 539 + .channels_min = 1, 540 + .channels_max = 16, 541 + }, 542 + .capture = { 543 + .channels_min = 1, 544 + .channels_max = 16, 545 + }, 471 546 }, 472 547 { 473 548 .name = "Alt Analog CPU DAI", 474 549 .ops = &hda_link_dai_ops, 550 + .playback = { 551 + .channels_min = 1, 552 + .channels_max = 16, 553 + }, 554 + .capture = { 555 + .channels_min = 1, 556 + .channels_max = 16, 557 + }, 475 558 }, 559 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 560 + { 561 + .name = "Probe Extraction CPU DAI", 562 + .compress_new = snd_soc_new_compress, 563 + .cops = &sof_probe_compr_ops, 564 + .capture = { 565 + .stream_name = "Probe Extraction", 566 + .channels_min = 1, 567 + .channels_max = 8, 568 + .rates = SNDRV_PCM_RATE_48000, 569 + .rate_min = 48000, 570 + .rate_max = 48000, 571 + }, 572 + }, 573 + #endif 476 574 #endif 477 575 };
+310 -21
sound/soc/sof/intel/hda-dsp.c
··· 15 15 * Hardware interface for generic Intel audio DSP HDA IP 16 16 */ 17 17 18 + #include <linux/module.h> 18 19 #include <sound/hdaudio_ext.h> 19 20 #include <sound/hda_register.h> 21 + #include "../sof-audio.h" 20 22 #include "../ops.h" 21 23 #include "hda.h" 22 24 #include "hda-ipc.h" 25 + 26 + static bool hda_enable_trace_D0I3_S0; 27 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG) 28 + module_param_named(enable_trace_D0I3_S0, hda_enable_trace_D0I3_S0, bool, 0444); 29 + MODULE_PARM_DESC(enable_trace_D0I3_S0, 30 + "SOF HDA enable trace when the DSP is in D0I3 in S0"); 31 + #endif 23 32 24 33 /* 25 34 * DSP Core control. ··· 343 334 pm_gate.flags = flags; 344 335 345 336 /* send pm_gate ipc to dsp */ 346 - return sof_ipc_tx_message(sdev->ipc, pm_gate.hdr.cmd, &pm_gate, 347 - sizeof(pm_gate), &reply, sizeof(reply)); 337 + return sof_ipc_tx_message_no_pm(sdev->ipc, pm_gate.hdr.cmd, 338 + &pm_gate, sizeof(pm_gate), &reply, 339 + sizeof(reply)); 348 340 } 349 341 350 - int hda_dsp_set_power_state(struct snd_sof_dev *sdev, 351 - enum sof_d0_substate d0_substate) 342 + static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value) 352 343 { 353 344 struct hdac_bus *bus = sof_to_bus(sdev); 354 - u32 flags; 355 345 int ret; 356 - u8 value; 357 346 358 347 /* Write to D0I3C after Command-In-Progress bit is cleared */ 359 348 ret = hda_dsp_wait_d0i3c_done(sdev); ··· 361 354 } 362 355 363 356 /* Update D0I3C register */ 364 - value = d0_substate == SOF_DSP_D0I3 ? SOF_HDA_VS_D0I3C_I3 : 0; 365 357 snd_hdac_chip_updateb(bus, VS_D0I3C, SOF_HDA_VS_D0I3C_I3, value); 366 358 367 359 /* Wait for cmd in progress to be cleared before exiting the function */ ··· 373 367 dev_vdbg(bus->dev, "D0I3C updated, register = 0x%x\n", 374 368 snd_hdac_chip_readb(bus, VS_D0I3C)); 375 369 376 - if (d0_substate == SOF_DSP_D0I0) 377 - flags = HDA_PM_PPG;/* prevent power gating in D0 */ 378 - else 379 - flags = HDA_PM_NO_DMA_TRACE;/* disable DMA trace in D0I3*/ 370 + return 0; 371 + } 380 372 381 - /* sending pm_gate IPC */ 382 - ret = hda_dsp_send_pm_gate_ipc(sdev, flags); 373 + static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev, 374 + const struct sof_dsp_power_state *target_state) 375 + { 376 + u32 flags = 0; 377 + int ret; 378 + u8 value = 0; 379 + 380 + /* 381 + * Sanity check for illegal state transitions 382 + * The only allowed transitions are: 383 + * 1. D3 -> D0I0 384 + * 2. D0I0 -> D0I3 385 + * 3. D0I3 -> D0I0 386 + */ 387 + switch (sdev->dsp_power_state.state) { 388 + case SOF_DSP_PM_D0: 389 + /* Follow the sequence below for D0 substate transitions */ 390 + break; 391 + case SOF_DSP_PM_D3: 392 + /* Follow regular flow for D3 -> D0 transition */ 393 + return 0; 394 + default: 395 + dev_err(sdev->dev, "error: transition from %d to %d not allowed\n", 396 + sdev->dsp_power_state.state, target_state->state); 397 + return -EINVAL; 398 + } 399 + 400 + /* Set flags and register value for D0 target substate */ 401 + if (target_state->substate == SOF_HDA_DSP_PM_D0I3) { 402 + value = SOF_HDA_VS_D0I3C_I3; 403 + 404 + /* 405 + * Trace DMA is disabled by default when the DSP enters D0I3. 406 + * But it can be kept enabled when the DSP enters D0I3 while the 407 + * system is in S0 for debug. 408 + */ 409 + if (hda_enable_trace_D0I3_S0 && 410 + sdev->system_suspend_target != SOF_SUSPEND_NONE) 411 + flags = HDA_PM_NO_DMA_TRACE; 412 + } else { 413 + /* prevent power gating in D0I0 */ 414 + flags = HDA_PM_PPG; 415 + } 416 + 417 + /* update D0I3C register */ 418 + ret = hda_dsp_update_d0i3c_register(sdev, value); 383 419 if (ret < 0) 420 + return ret; 421 + 422 + /* 423 + * Notify the DSP of the state change. 424 + * If this IPC fails, revert the D0I3C register update in order 425 + * to prevent partial state change. 426 + */ 427 + ret = hda_dsp_send_pm_gate_ipc(sdev, flags); 428 + if (ret < 0) { 384 429 dev_err(sdev->dev, 385 430 "error: PM_GATE ipc error %d\n", ret); 431 + goto revert; 432 + } 433 + 434 + return ret; 435 + 436 + revert: 437 + /* fallback to the previous register value */ 438 + value = value ? 0 : SOF_HDA_VS_D0I3C_I3; 439 + 440 + /* 441 + * This can fail but return the IPC error to signal that 442 + * the state change failed. 443 + */ 444 + hda_dsp_update_d0i3c_register(sdev, value); 386 445 387 446 return ret; 388 447 } 448 + 449 + /* helper to log DSP state */ 450 + static void hda_dsp_state_log(struct snd_sof_dev *sdev) 451 + { 452 + switch (sdev->dsp_power_state.state) { 453 + case SOF_DSP_PM_D0: 454 + switch (sdev->dsp_power_state.substate) { 455 + case SOF_HDA_DSP_PM_D0I0: 456 + dev_dbg(sdev->dev, "Current DSP power state: D0I0\n"); 457 + break; 458 + case SOF_HDA_DSP_PM_D0I3: 459 + dev_dbg(sdev->dev, "Current DSP power state: D0I3\n"); 460 + break; 461 + default: 462 + dev_dbg(sdev->dev, "Unknown DSP D0 substate: %d\n", 463 + sdev->dsp_power_state.substate); 464 + break; 465 + } 466 + break; 467 + case SOF_DSP_PM_D1: 468 + dev_dbg(sdev->dev, "Current DSP power state: D1\n"); 469 + break; 470 + case SOF_DSP_PM_D2: 471 + dev_dbg(sdev->dev, "Current DSP power state: D2\n"); 472 + break; 473 + case SOF_DSP_PM_D3_HOT: 474 + dev_dbg(sdev->dev, "Current DSP power state: D3_HOT\n"); 475 + break; 476 + case SOF_DSP_PM_D3: 477 + dev_dbg(sdev->dev, "Current DSP power state: D3\n"); 478 + break; 479 + case SOF_DSP_PM_D3_COLD: 480 + dev_dbg(sdev->dev, "Current DSP power state: D3_COLD\n"); 481 + break; 482 + default: 483 + dev_dbg(sdev->dev, "Unknown DSP power state: %d\n", 484 + sdev->dsp_power_state.state); 485 + break; 486 + } 487 + } 488 + 489 + /* 490 + * All DSP power state transitions are initiated by the driver. 491 + * If the requested state change fails, the error is simply returned. 492 + * Further state transitions are attempted only when the set_power_save() op 493 + * is called again either because of a new IPC sent to the DSP or 494 + * during system suspend/resume. 495 + */ 496 + int hda_dsp_set_power_state(struct snd_sof_dev *sdev, 497 + const struct sof_dsp_power_state *target_state) 498 + { 499 + int ret = 0; 500 + 501 + /* 502 + * When the DSP is already in D0I3 and the target state is D0I3, 503 + * it could be the case that the DSP is in D0I3 during S0 504 + * and the system is suspending to S0Ix. Therefore, 505 + * hda_dsp_set_D0_state() must be called to disable trace DMA 506 + * by sending the PM_GATE IPC to the FW. 507 + */ 508 + if (target_state->substate == SOF_HDA_DSP_PM_D0I3 && 509 + sdev->system_suspend_target == SOF_SUSPEND_S0IX) 510 + goto set_state; 511 + 512 + /* 513 + * For all other cases, return without doing anything if 514 + * the DSP is already in the target state. 515 + */ 516 + if (target_state->state == sdev->dsp_power_state.state && 517 + target_state->substate == sdev->dsp_power_state.substate) 518 + return 0; 519 + 520 + set_state: 521 + switch (target_state->state) { 522 + case SOF_DSP_PM_D0: 523 + ret = hda_dsp_set_D0_state(sdev, target_state); 524 + break; 525 + case SOF_DSP_PM_D3: 526 + /* The only allowed transition is: D0I0 -> D3 */ 527 + if (sdev->dsp_power_state.state == SOF_DSP_PM_D0 && 528 + sdev->dsp_power_state.substate == SOF_HDA_DSP_PM_D0I0) 529 + break; 530 + 531 + dev_err(sdev->dev, 532 + "error: transition from %d to %d not allowed\n", 533 + sdev->dsp_power_state.state, target_state->state); 534 + return -EINVAL; 535 + default: 536 + dev_err(sdev->dev, "error: target state unsupported %d\n", 537 + target_state->state); 538 + return -EINVAL; 539 + } 540 + if (ret < 0) { 541 + dev_err(sdev->dev, 542 + "failed to set requested target DSP state %d substate %d\n", 543 + target_state->state, target_state->substate); 544 + return ret; 545 + } 546 + 547 + sdev->dsp_power_state = *target_state; 548 + hda_dsp_state_log(sdev); 549 + return ret; 550 + } 551 + 552 + /* 553 + * Audio DSP states may transform as below:- 554 + * 555 + * Opportunistic D0I3 in S0 556 + * Runtime +---------------------+ Delayed D0i3 work timeout 557 + * suspend | +--------------------+ 558 + * +------------+ D0I0(active) | | 559 + * | | <---------------+ | 560 + * | +--------> | New IPC | | 561 + * | |Runtime +--^--+---------^--+--+ (via mailbox) | | 562 + * | |resume | | | | | | 563 + * | | | | | | | | 564 + * | | System| | | | | | 565 + * | | resume| | S3/S0IX | | | | 566 + * | | | | suspend | | S0IX | | 567 + * | | | | | |suspend | | 568 + * | | | | | | | | 569 + * | | | | | | | | 570 + * +-v---+-----------+--v-------+ | | +------+----v----+ 571 + * | | | +-----------> | 572 + * | D3 (suspended) | | | D0I3 | 573 + * | | +--------------+ | 574 + * | | System resume | | 575 + * +----------------------------+ +----------------+ 576 + * 577 + * S0IX suspend: The DSP is in D0I3 if any D0I3-compatible streams 578 + * ignored the suspend trigger. Otherwise the DSP 579 + * is in D3. 580 + */ 389 581 390 582 static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) 391 583 { ··· 593 389 struct hdac_bus *bus = sof_to_bus(sdev); 594 390 #endif 595 391 int ret; 392 + 393 + hda_sdw_int_enable(sdev, false); 596 394 597 395 /* disable IPC interrupts */ 598 396 hda_dsp_ipc_int_disable(sdev); ··· 692 486 { 693 487 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 694 488 struct pci_dev *pci = to_pci_dev(sdev->dev); 489 + const struct sof_dsp_power_state target_state = { 490 + .state = SOF_DSP_PM_D0, 491 + .substate = SOF_HDA_DSP_PM_D0I0, 492 + }; 493 + int ret; 695 494 696 - if (sdev->s0_suspend) { 495 + /* resume from D0I3 */ 496 + if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) { 697 497 hda_codec_i915_display_power(sdev, true); 498 + 499 + /* Set DSP power state */ 500 + ret = snd_sof_dsp_set_power_state(sdev, &target_state); 501 + if (ret < 0) { 502 + dev_err(sdev->dev, "error: setting dsp state %d substate %d\n", 503 + target_state.state, target_state.substate); 504 + return ret; 505 + } 698 506 699 507 /* restore L1SEN bit */ 700 508 if (hda->l1_support_changed) ··· 723 503 } 724 504 725 505 /* init hda controller. DSP cores will be powered up during fw boot */ 726 - return hda_resume(sdev, false); 506 + ret = hda_resume(sdev, false); 507 + if (ret < 0) 508 + return ret; 509 + 510 + return snd_sof_dsp_set_power_state(sdev, &target_state); 727 511 } 728 512 729 513 int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) 730 514 { 515 + const struct sof_dsp_power_state target_state = { 516 + .state = SOF_DSP_PM_D0, 517 + }; 518 + int ret; 519 + 731 520 /* init hda controller. DSP cores will be powered up during fw boot */ 732 - return hda_resume(sdev, true); 521 + ret = hda_resume(sdev, true); 522 + if (ret < 0) 523 + return ret; 524 + 525 + return snd_sof_dsp_set_power_state(sdev, &target_state); 733 526 } 734 527 735 528 int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) ··· 760 527 761 528 int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev) 762 529 { 530 + const struct sof_dsp_power_state target_state = { 531 + .state = SOF_DSP_PM_D3, 532 + }; 533 + int ret; 534 + 763 535 /* stop hda controller and power dsp off */ 764 - return hda_suspend(sdev, true); 536 + ret = hda_suspend(sdev, true); 537 + if (ret < 0) 538 + return ret; 539 + 540 + return snd_sof_dsp_set_power_state(sdev, &target_state); 765 541 } 766 542 767 - int hda_dsp_suspend(struct snd_sof_dev *sdev) 543 + int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) 768 544 { 769 545 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 770 546 struct hdac_bus *bus = sof_to_bus(sdev); 771 547 struct pci_dev *pci = to_pci_dev(sdev->dev); 548 + const struct sof_dsp_power_state target_dsp_state = { 549 + .state = target_state, 550 + .substate = target_state == SOF_DSP_PM_D0 ? 551 + SOF_HDA_DSP_PM_D0I3 : 0, 552 + }; 772 553 int ret; 773 554 774 - if (sdev->s0_suspend) { 555 + /* cancel any attempt for DSP D0I3 */ 556 + cancel_delayed_work_sync(&hda->d0i3_work); 557 + 558 + if (target_state == SOF_DSP_PM_D0) { 775 559 /* we can't keep a wakeref to display driver at suspend */ 776 560 hda_codec_i915_display_power(sdev, false); 561 + 562 + /* Set DSP power state */ 563 + ret = snd_sof_dsp_set_power_state(sdev, &target_dsp_state); 564 + if (ret < 0) { 565 + dev_err(sdev->dev, "error: setting dsp state %d substate %d\n", 566 + target_dsp_state.state, 567 + target_dsp_state.substate); 568 + return ret; 569 + } 777 570 778 571 /* enable L1SEN to make sure the system can enter S0Ix */ 779 572 hda->l1_support_changed = ··· 821 562 return ret; 822 563 } 823 564 824 - return 0; 565 + return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); 825 566 } 826 567 827 568 int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) ··· 847 588 */ 848 589 if (stream->link_substream) { 849 590 rtd = snd_pcm_substream_chip(stream->link_substream); 850 - name = rtd->codec_dai->component->name; 591 + name = asoc_rtd_to_codec(rtd, 0)->component->name; 851 592 link = snd_hdac_ext_bus_get_link(bus, name); 852 593 if (!link) 853 594 return -EINVAL; ··· 864 605 } 865 606 #endif 866 607 return 0; 608 + } 609 + 610 + void hda_dsp_d0i3_work(struct work_struct *work) 611 + { 612 + struct sof_intel_hda_dev *hdev = container_of(work, 613 + struct sof_intel_hda_dev, 614 + d0i3_work.work); 615 + struct hdac_bus *bus = &hdev->hbus.core; 616 + struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev); 617 + struct sof_dsp_power_state target_state; 618 + int ret; 619 + 620 + target_state.state = SOF_DSP_PM_D0; 621 + 622 + /* DSP can enter D0I3 iff only D0I3-compatible streams are active */ 623 + if (snd_sof_dsp_only_d0i3_compatible_stream_active(sdev)) 624 + target_state.substate = SOF_HDA_DSP_PM_D0I3; 625 + else 626 + target_state.substate = SOF_HDA_DSP_PM_D0I0; 627 + 628 + /* remain in D0I0 */ 629 + if (target_state.substate == SOF_HDA_DSP_PM_D0I0) 630 + return; 631 + 632 + /* This can fail but error cannot be propagated */ 633 + ret = snd_sof_dsp_set_power_state(sdev, &target_state); 634 + if (ret < 0) 635 + dev_err_ratelimited(sdev->dev, 636 + "error: failed to set DSP state %d substate %d\n", 637 + target_state.state, target_state.substate); 867 638 }
+6 -18
sound/soc/sof/intel/hda-ipc.c
··· 106 106 ret = reply.error; 107 107 } else { 108 108 /* reply correct size ? */ 109 - if (reply.hdr.size != msg->reply_size) { 109 + if (reply.hdr.size != msg->reply_size && 110 + /* getter payload is never known upfront */ 111 + !(reply.hdr.cmd & SOF_IPC_GLB_PROBE)) { 110 112 dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", 111 113 msg->reply_size, reply.hdr.size); 112 114 ret = -EINVAL; ··· 123 121 out: 124 122 msg->reply_error = ret; 125 123 126 - } 127 - 128 - static bool hda_dsp_ipc_is_sof(uint32_t msg) 129 - { 130 - return (msg & (HDA_DSP_IPC_PURGE_FW | 0xf << 9)) != msg || 131 - (msg & HDA_DSP_IPC_PURGE_FW) != HDA_DSP_IPC_PURGE_FW; 132 124 } 133 125 134 126 /* IPC handler thread */ ··· 170 174 */ 171 175 spin_lock_irq(&sdev->ipc_lock); 172 176 173 - /* handle immediate reply from DSP core - ignore ROM messages */ 174 - if (hda_dsp_ipc_is_sof(msg)) { 175 - hda_dsp_ipc_get_reply(sdev); 176 - snd_sof_ipc_reply(sdev, msg); 177 - } 178 - 179 - /* wake up sleeper if we are loading code */ 180 - if (sdev->code_loading) { 181 - sdev->code_loading = 0; 182 - wake_up(&sdev->waitq); 183 - } 177 + /* handle immediate reply from DSP core */ 178 + hda_dsp_ipc_get_reply(sdev); 179 + snd_sof_ipc_reply(sdev, msg); 184 180 185 181 /* set the done bit */ 186 182 hda_dsp_ipc_dsp_done(sdev);
+37 -3
sound/soc/sof/intel/hda-loader.c
··· 131 131 goto err; 132 132 } 133 133 134 + /* set DONE bit to clear the reply IPC message */ 135 + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, 136 + chip->ipc_ack, 137 + chip->ipc_ack_mask, 138 + chip->ipc_ack_mask); 139 + 134 140 /* step 5: power down corex */ 135 141 ret = hda_dsp_core_power_down(sdev, 136 142 chip->cores_mask & ~(HDA_DSP_CORE_MASK(0))); ··· 179 173 /* code loader is special case that reuses stream ops */ 180 174 switch (cmd) { 181 175 case SNDRV_PCM_TRIGGER_START: 182 - wait_event_timeout(sdev->waitq, !sdev->code_loading, 183 - HDA_DSP_CL_TRIGGER_TIMEOUT); 184 - 185 176 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, 186 177 1 << hstream->index, 187 178 1 << hstream->index); ··· 347 344 } 348 345 349 346 /* 347 + * When a SoundWire link is in clock stop state, a Slave 348 + * device may trigger in-band wakes for events such as jack 349 + * insertion or acoustic event detection. This event will lead 350 + * to a WAKEEN interrupt, handled by the PCI device and routed 351 + * to PME if the PCI device is in D3. The resume function in 352 + * audio PCI driver will be invoked by ACPI for PME event and 353 + * initialize the device and process WAKEEN interrupt. 354 + * 355 + * The WAKEEN interrupt should be processed ASAP to prevent an 356 + * interrupt flood, otherwise other interrupts, such IPC, 357 + * cannot work normally. The WAKEEN is handled after the ROM 358 + * is initialized successfully, which ensures power rails are 359 + * enabled before accessing the SoundWire SHIM registers 360 + */ 361 + if (!sdev->first_boot) 362 + hda_sdw_process_wakeen(sdev); 363 + 364 + /* 350 365 * at this point DSP ROM has been initialized and 351 366 * should be ready for code loading and firmware boot 352 367 */ ··· 417 396 /* post fw run operations */ 418 397 int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) 419 398 { 399 + int ret; 400 + 401 + if (sdev->first_boot) { 402 + ret = hda_sdw_startup(sdev); 403 + if (ret < 0) { 404 + dev_err(sdev->dev, 405 + "error: could not startup SoundWire links\n"); 406 + return ret; 407 + } 408 + } 409 + 410 + hda_sdw_int_enable(sdev, true); 411 + 420 412 /* re-enable clock gating and power gating */ 421 413 return hda_dsp_ctrl_clock_power_gating(sdev, true); 422 414 }
+4 -4
sound/soc/sof/intel/hda-pcm.c
··· 27 27 #define SDnFMT_BITS(x) ((x) << 4) 28 28 #define SDnFMT_CHAN(x) ((x) << 0) 29 29 30 - static inline u32 get_mult_div(struct snd_sof_dev *sdev, int rate) 30 + u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate) 31 31 { 32 32 switch (rate) { 33 33 case 8000: ··· 61 61 } 62 62 }; 63 63 64 - static inline u32 get_bits(struct snd_sof_dev *sdev, int sample_bits) 64 + u32 hda_dsp_get_bits(struct snd_sof_dev *sdev, int sample_bits) 65 65 { 66 66 switch (sample_bits) { 67 67 case 8: ··· 95 95 u32 size, rate, bits; 96 96 97 97 size = params_buffer_bytes(params); 98 - rate = get_mult_div(sdev, params_rate(params)); 99 - bits = get_bits(sdev, params_width(params)); 98 + rate = hda_dsp_get_mult_div(sdev, params_rate(params)); 99 + bits = hda_dsp_get_bits(sdev, params_width(params)); 100 100 101 101 hstream->substream = substream; 102 102
+25 -2
sound/soc/sof/intel/hda-stream.c
··· 547 547 SOF_HDA_REG_PP_PPCTL, mask, 0); 548 548 spin_unlock_irq(&bus->reg_lock); 549 549 550 + stream->substream = NULL; 551 + 550 552 return 0; 551 553 } 552 554 ··· 573 571 return ret; 574 572 } 575 573 574 + static void 575 + hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size) 576 + { 577 + u64 prev_pos, pos, num_bytes; 578 + 579 + div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); 580 + pos = snd_hdac_stream_get_pos_posbuf(hstream); 581 + 582 + if (pos < prev_pos) 583 + num_bytes = (buffer_size - prev_pos) + pos; 584 + else 585 + num_bytes = pos - prev_pos; 586 + 587 + hstream->curr_pos += num_bytes; 588 + } 589 + 576 590 static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) 577 591 { 578 592 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); ··· 606 588 snd_hdac_stream_writeb(s, SD_STS, sd_status); 607 589 608 590 active = true; 609 - if (!s->substream || 591 + if ((!s->substream && !s->cstream) || 610 592 !s->running || 611 593 (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0) 612 594 continue; 613 595 614 596 /* Inform ALSA only in case not do that with IPC */ 615 - if (sof_hda->no_ipc_position) 597 + if (s->substream && sof_hda->no_ipc_position) { 616 598 snd_sof_pcm_period_elapsed(s->substream); 599 + } else if (s->cstream) { 600 + hda_dsp_set_bytes_transferred(s, 601 + s->cstream->runtime->buffer_size); 602 + snd_compr_fragment_elapsed(s->cstream); 603 + } 617 604 } 618 605 } 619 606
+414 -19
sound/soc/sof/intel/hda.c
··· 18 18 #include <sound/hdaudio_ext.h> 19 19 #include <sound/hda_register.h> 20 20 21 + #include <linux/acpi.h> 21 22 #include <linux/module.h> 23 + #include <linux/soundwire/sdw.h> 24 + #include <linux/soundwire/sdw_intel.h> 22 25 #include <sound/intel-nhlt.h> 23 26 #include <sound/sof.h> 24 27 #include <sound/sof/xtensa.h> 28 + #include "../sof-audio.h" 25 29 #include "../ops.h" 26 30 #include "hda.h" 27 31 ··· 37 33 #include "shim.h" 38 34 39 35 #define EXCEPT_MAX_HDR_SIZE 0x400 36 + 37 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 38 + 39 + /* 40 + * The default for SoundWire clock stop quirks is to power gate the IP 41 + * and do a Bus Reset, this will need to be modified when the DSP 42 + * needs to remain in D0i3 so that the Master does not lose context 43 + * and enumeration is not required on clock restart 44 + */ 45 + static int sdw_clock_stop_quirks = SDW_INTEL_CLK_STOP_BUS_RESET; 46 + module_param(sdw_clock_stop_quirks, int, 0444); 47 + MODULE_PARM_DESC(sdw_clock_stop_quirks, "SOF SoundWire clock stop quirks"); 48 + 49 + static int sdw_params_stream(struct device *dev, 50 + struct sdw_intel_stream_params_data *params_data) 51 + { 52 + struct snd_sof_dev *sdev = dev_get_drvdata(dev); 53 + struct snd_soc_dai *d = params_data->dai; 54 + struct sof_ipc_dai_config config; 55 + struct sof_ipc_reply reply; 56 + int link_id = params_data->link_id; 57 + int alh_stream_id = params_data->alh_stream_id; 58 + int ret; 59 + u32 size = sizeof(config); 60 + 61 + memset(&config, 0, size); 62 + config.hdr.size = size; 63 + config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; 64 + config.type = SOF_DAI_INTEL_ALH; 65 + config.dai_index = (link_id << 8) | (d->id); 66 + config.alh.stream_id = alh_stream_id; 67 + 68 + /* send message to DSP */ 69 + ret = sof_ipc_tx_message(sdev->ipc, 70 + config.hdr.cmd, &config, size, &reply, 71 + sizeof(reply)); 72 + if (ret < 0) { 73 + dev_err(sdev->dev, 74 + "error: failed to set DAI hw_params for link %d dai->id %d ALH %d\n", 75 + link_id, d->id, alh_stream_id); 76 + } 77 + 78 + return ret; 79 + } 80 + 81 + static int sdw_free_stream(struct device *dev, 82 + struct sdw_intel_stream_free_data *free_data) 83 + { 84 + struct snd_sof_dev *sdev = dev_get_drvdata(dev); 85 + struct snd_soc_dai *d = free_data->dai; 86 + struct sof_ipc_dai_config config; 87 + struct sof_ipc_reply reply; 88 + int link_id = free_data->link_id; 89 + int ret; 90 + u32 size = sizeof(config); 91 + 92 + memset(&config, 0, size); 93 + config.hdr.size = size; 94 + config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; 95 + config.type = SOF_DAI_INTEL_ALH; 96 + config.dai_index = (link_id << 8) | d->id; 97 + config.alh.stream_id = 0xFFFF; /* invalid value on purpose */ 98 + 99 + /* send message to DSP */ 100 + ret = sof_ipc_tx_message(sdev->ipc, 101 + config.hdr.cmd, &config, size, &reply, 102 + sizeof(reply)); 103 + if (ret < 0) { 104 + dev_err(sdev->dev, 105 + "error: failed to free stream for link %d dai->id %d\n", 106 + link_id, d->id); 107 + } 108 + 109 + return ret; 110 + } 111 + 112 + static const struct sdw_intel_ops sdw_callback = { 113 + .params_stream = sdw_params_stream, 114 + .free_stream = sdw_free_stream, 115 + }; 116 + 117 + void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) 118 + { 119 + sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable); 120 + } 121 + 122 + static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) 123 + { 124 + struct sof_intel_hda_dev *hdev; 125 + acpi_handle handle; 126 + int ret; 127 + 128 + handle = ACPI_HANDLE(sdev->dev); 129 + 130 + /* save ACPI info for the probe step */ 131 + hdev = sdev->pdata->hw_pdata; 132 + 133 + ret = sdw_intel_acpi_scan(handle, &hdev->info); 134 + if (ret < 0) { 135 + dev_err(sdev->dev, "%s failed\n", __func__); 136 + return -EINVAL; 137 + } 138 + 139 + return 0; 140 + } 141 + 142 + static int hda_sdw_probe(struct snd_sof_dev *sdev) 143 + { 144 + struct sof_intel_hda_dev *hdev; 145 + struct sdw_intel_res res; 146 + void *sdw; 147 + 148 + hdev = sdev->pdata->hw_pdata; 149 + 150 + memset(&res, 0, sizeof(res)); 151 + 152 + res.mmio_base = sdev->bar[HDA_DSP_BAR]; 153 + res.irq = sdev->ipc_irq; 154 + res.handle = hdev->info.handle; 155 + res.parent = sdev->dev; 156 + res.ops = &sdw_callback; 157 + res.dev = sdev->dev; 158 + res.clock_stop_quirks = sdw_clock_stop_quirks; 159 + 160 + /* 161 + * ops and arg fields are not populated for now, 162 + * they will be needed when the DAI callbacks are 163 + * provided 164 + */ 165 + 166 + /* we could filter links here if needed, e.g for quirks */ 167 + res.count = hdev->info.count; 168 + res.link_mask = hdev->info.link_mask; 169 + 170 + sdw = sdw_intel_probe(&res); 171 + if (!sdw) { 172 + dev_err(sdev->dev, "error: SoundWire probe failed\n"); 173 + return -EINVAL; 174 + } 175 + 176 + /* save context */ 177 + hdev->sdw = sdw; 178 + 179 + return 0; 180 + } 181 + 182 + int hda_sdw_startup(struct snd_sof_dev *sdev) 183 + { 184 + struct sof_intel_hda_dev *hdev; 185 + 186 + hdev = sdev->pdata->hw_pdata; 187 + 188 + if (!hdev->sdw) 189 + return 0; 190 + 191 + return sdw_intel_startup(hdev->sdw); 192 + } 193 + 194 + static int hda_sdw_exit(struct snd_sof_dev *sdev) 195 + { 196 + struct sof_intel_hda_dev *hdev; 197 + 198 + hdev = sdev->pdata->hw_pdata; 199 + 200 + hda_sdw_int_enable(sdev, false); 201 + 202 + if (hdev->sdw) 203 + sdw_intel_exit(hdev->sdw); 204 + hdev->sdw = NULL; 205 + 206 + return 0; 207 + } 208 + 209 + static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev) 210 + { 211 + struct sof_intel_hda_dev *hdev; 212 + bool ret = false; 213 + u32 irq_status; 214 + 215 + hdev = sdev->pdata->hw_pdata; 216 + 217 + if (!hdev->sdw) 218 + return ret; 219 + 220 + /* store status */ 221 + irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIS2); 222 + 223 + /* invalid message ? */ 224 + if (irq_status == 0xffffffff) 225 + goto out; 226 + 227 + /* SDW message ? */ 228 + if (irq_status & HDA_DSP_REG_ADSPIS2_SNDW) 229 + ret = true; 230 + 231 + out: 232 + return ret; 233 + } 234 + 235 + static irqreturn_t hda_dsp_sdw_thread(int irq, void *context) 236 + { 237 + return sdw_intel_thread(irq, context); 238 + } 239 + 240 + static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) 241 + { 242 + struct sof_intel_hda_dev *hdev; 243 + 244 + hdev = sdev->pdata->hw_pdata; 245 + if (hdev->sdw && 246 + snd_sof_dsp_read(sdev, HDA_DSP_BAR, 247 + HDA_DSP_REG_SNDW_WAKE_STS)) 248 + return true; 249 + 250 + return false; 251 + } 252 + 253 + void hda_sdw_process_wakeen(struct snd_sof_dev *sdev) 254 + { 255 + struct sof_intel_hda_dev *hdev; 256 + 257 + hdev = sdev->pdata->hw_pdata; 258 + if (!hdev->sdw) 259 + return; 260 + 261 + sdw_intel_process_wakeen_event(hdev->sdw); 262 + } 263 + 264 + #endif 40 265 41 266 /* 42 267 * Debug ··· 287 54 module_param_named(dmic_num, hda_dmic_num, int, 0444); 288 55 MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number"); 289 56 290 - static bool hda_codec_use_common_hdmi = 291 - IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC); 57 + static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI); 292 58 module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); 293 59 MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); 294 60 #endif ··· 520 288 521 289 /* init i915 and HDMI codecs */ 522 290 ret = hda_codec_i915_init(sdev); 523 - if (ret < 0) { 524 - dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n"); 525 - return ret; 526 - } 291 + if (ret < 0) 292 + dev_warn(sdev->dev, "init of i915 and HDMI codec failed\n"); 527 293 528 294 /* get controller capabilities */ 529 295 ret = hda_dsp_ctrl_get_caps(sdev); ··· 579 349 static int hda_init_caps(struct snd_sof_dev *sdev) 580 350 { 581 351 struct hdac_bus *bus = sof_to_bus(sdev); 352 + struct snd_sof_pdata *pdata = sdev->pdata; 582 353 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 583 354 struct hdac_ext_link *hlink; 584 355 #endif 356 + struct sof_intel_hda_dev *hdev = pdata->hw_pdata; 357 + u32 link_mask; 585 358 int ret = 0; 586 359 587 360 device_disable_async_suspend(bus->dev); ··· 598 365 if (ret < 0) { 599 366 dev_err(bus->dev, "error: init chip failed with ret: %d\n", 600 367 ret); 601 - #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 602 - hda_codec_i915_exit(sdev); 603 - #endif 604 368 return ret; 605 369 } 370 + 371 + /* scan SoundWire capabilities exposed by DSDT */ 372 + ret = hda_sdw_acpi_scan(sdev); 373 + if (ret < 0) { 374 + dev_dbg(sdev->dev, "skipping SoundWire, ACPI scan error\n"); 375 + goto skip_soundwire; 376 + } 377 + 378 + link_mask = hdev->info.link_mask; 379 + if (!link_mask) { 380 + dev_dbg(sdev->dev, "skipping SoundWire, no links enabled\n"); 381 + goto skip_soundwire; 382 + } 383 + 384 + /* 385 + * probe/allocate SoundWire resources. 386 + * The hardware configuration takes place in hda_sdw_startup 387 + * after power rails are enabled. 388 + * It's entirely possible to have a mix of I2S/DMIC/SoundWire 389 + * devices, so we allocate the resources in all cases. 390 + */ 391 + ret = hda_sdw_probe(sdev); 392 + if (ret < 0) { 393 + dev_err(sdev->dev, "error: SoundWire probe error\n"); 394 + return ret; 395 + } 396 + 397 + skip_soundwire: 606 398 607 399 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 608 400 if (bus->mlcap) ··· 637 379 hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi); 638 380 639 381 if (!HDA_IDISP_CODEC(bus->codec_mask)) 640 - hda_codec_i915_exit(sdev); 382 + hda_codec_i915_display_power(sdev, false); 641 383 642 384 /* 643 385 * we are done probing so decrement link counts ··· 685 427 static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) 686 428 { 687 429 struct snd_sof_dev *sdev = context; 430 + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 688 431 689 432 /* deal with streams and controller first */ 690 433 if (hda_dsp_check_stream_irq(sdev)) ··· 693 434 694 435 if (hda_dsp_check_ipc_irq(sdev)) 695 436 sof_ops(sdev)->irq_thread(irq, sdev); 437 + 438 + if (hda_dsp_check_sdw_irq(sdev)) 439 + hda_dsp_sdw_thread(irq, hdev->sdw); 440 + 441 + if (hda_sdw_check_wakeen_irq(sdev)) 442 + hda_sdw_process_wakeen(sdev); 696 443 697 444 /* enable GIE interrupt */ 698 445 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, ··· 855 590 hda_dsp_ctrl_ppcap_enable(sdev, true); 856 591 hda_dsp_ctrl_ppcap_int_enable(sdev, true); 857 592 858 - /* initialize waitq for code loading */ 859 - init_waitqueue_head(&sdev->waitq); 860 - 861 593 /* set default mailbox offset for FW ready message */ 862 594 sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET; 595 + 596 + INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work); 863 597 864 598 return 0; 865 599 ··· 885 621 struct pci_dev *pci = to_pci_dev(sdev->dev); 886 622 const struct sof_intel_dsp_desc *chip = hda->desc; 887 623 624 + /* cancel any attempt for DSP D0I3 */ 625 + cancel_delayed_work_sync(&hda->d0i3_work); 626 + 888 627 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 889 628 /* codec removal, invoke bus_device_remove */ 890 629 snd_hdac_ext_bus_device_remove(bus); 891 630 #endif 631 + 632 + hda_sdw_exit(sdev); 892 633 893 634 if (!IS_ERR_OR_NULL(hda->dmic_dev)) 894 635 platform_device_unregister(hda->dmic_dev); ··· 963 694 /* 964 695 * If no machine driver is found, then: 965 696 * 966 - * hda machine driver is used if : 967 - * 1. there is one HDMI codec and one external HDAudio codec 968 - * 2. only HDMI codec 697 + * generic hda machine driver can handle: 698 + * - one HDMI codec, and/or 699 + * - one external HDAudio codec 969 700 */ 970 - if (!pdata->machine && codec_num <= 2 && 971 - HDA_IDISP_CODEC(bus->codec_mask)) { 701 + if (!pdata->machine && codec_num <= 2) { 972 702 hda_mach = snd_soc_acpi_intel_hda_machines; 973 703 974 704 /* topology: use the info from hda_machines */ ··· 977 709 dev_info(bus->dev, "using HDA machine driver %s now\n", 978 710 hda_mach->drv_name); 979 711 980 - if (codec_num == 1) 712 + if (codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask)) 981 713 idisp_str = "-idisp"; 982 714 else 983 715 idisp_str = ""; ··· 1031 763 } 1032 764 #endif 1033 765 766 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 767 + /* Check if all Slaves defined on the link can be found */ 768 + static bool link_slaves_found(struct snd_sof_dev *sdev, 769 + const struct snd_soc_acpi_link_adr *link, 770 + struct sdw_intel_ctx *sdw) 771 + { 772 + struct hdac_bus *bus = sof_to_bus(sdev); 773 + struct sdw_intel_slave_id *ids = sdw->ids; 774 + int num_slaves = sdw->num_slaves; 775 + unsigned int part_id, link_id, unique_id, mfg_id; 776 + int i, j; 777 + 778 + for (i = 0; i < link->num_adr; i++) { 779 + u64 adr = link->adr_d[i].adr; 780 + 781 + mfg_id = SDW_MFG_ID(adr); 782 + part_id = SDW_PART_ID(adr); 783 + link_id = SDW_DISCO_LINK_ID(adr); 784 + for (j = 0; j < num_slaves; j++) { 785 + if (ids[j].link_id != link_id || 786 + ids[j].id.part_id != part_id || 787 + ids[j].id.mfg_id != mfg_id) 788 + continue; 789 + /* 790 + * we have to check unique id 791 + * if there is more than one 792 + * Slave on the link 793 + */ 794 + unique_id = SDW_UNIQUE_ID(adr); 795 + if (link->num_adr == 1 || 796 + ids[j].id.unique_id == SDW_IGNORED_UNIQUE_ID || 797 + ids[j].id.unique_id == unique_id) { 798 + dev_dbg(bus->dev, 799 + "found %x at link %d\n", 800 + part_id, link_id); 801 + break; 802 + } 803 + } 804 + if (j == num_slaves) { 805 + dev_dbg(bus->dev, 806 + "Slave %x not found\n", 807 + part_id); 808 + return false; 809 + } 810 + } 811 + return true; 812 + } 813 + 814 + static int hda_sdw_machine_select(struct snd_sof_dev *sdev) 815 + { 816 + struct snd_sof_pdata *pdata = sdev->pdata; 817 + const struct snd_soc_acpi_link_adr *link; 818 + struct hdac_bus *bus = sof_to_bus(sdev); 819 + struct snd_soc_acpi_mach *mach; 820 + struct sof_intel_hda_dev *hdev; 821 + u32 link_mask; 822 + int i; 823 + 824 + hdev = pdata->hw_pdata; 825 + link_mask = hdev->info.link_mask; 826 + 827 + /* 828 + * Select SoundWire machine driver if needed using the 829 + * alternate tables. This case deals with SoundWire-only 830 + * machines, for mixed cases with I2C/I2S the detection relies 831 + * on the HID list. 832 + */ 833 + if (link_mask && !pdata->machine) { 834 + for (mach = pdata->desc->alt_machines; 835 + mach && mach->link_mask; mach++) { 836 + if (mach->link_mask != link_mask) 837 + continue; 838 + 839 + /* No need to match adr if there is no links defined */ 840 + if (!mach->links) 841 + break; 842 + 843 + link = mach->links; 844 + for (i = 0; i < hdev->info.count && link->num_adr; 845 + i++, link++) { 846 + /* 847 + * Try next machine if any expected Slaves 848 + * are not found on this link. 849 + */ 850 + if (!link_slaves_found(sdev, link, hdev->sdw)) 851 + break; 852 + } 853 + /* Found if all Slaves are checked */ 854 + if (i == hdev->info.count || !link->num_adr) 855 + break; 856 + } 857 + if (mach && mach->link_mask) { 858 + dev_dbg(bus->dev, 859 + "SoundWire machine driver %s topology %s\n", 860 + mach->drv_name, 861 + mach->sof_tplg_filename); 862 + pdata->machine = mach; 863 + mach->mach_params.links = mach->links; 864 + mach->mach_params.link_mask = mach->link_mask; 865 + mach->mach_params.platform = dev_name(sdev->dev); 866 + pdata->fw_filename = mach->sof_fw_filename; 867 + pdata->tplg_filename = mach->sof_tplg_filename; 868 + } else { 869 + dev_info(sdev->dev, 870 + "No SoundWire machine driver found\n"); 871 + } 872 + } 873 + 874 + return 0; 875 + } 876 + #else 877 + static int hda_sdw_machine_select(struct snd_sof_dev *sdev) 878 + { 879 + return 0; 880 + } 881 + #endif 882 + 1034 883 void hda_set_mach_params(const struct snd_soc_acpi_mach *mach, 1035 884 struct device *dev) 1036 885 { ··· 1167 782 if (mach) { 1168 783 sof_pdata->tplg_filename = mach->sof_tplg_filename; 1169 784 sof_pdata->machine = mach; 785 + 786 + if (mach->link_mask) { 787 + mach->mach_params.links = mach->links; 788 + mach->mach_params.link_mask = mach->link_mask; 789 + } 1170 790 } 791 + 792 + /* 793 + * If I2S fails, try SoundWire 794 + */ 795 + hda_sdw_machine_select(sdev); 1171 796 1172 797 /* 1173 798 * Choose HDA generic machine driver if mach is NULL.
+117 -3
sound/soc/sof/intel/hda.h
··· 11 11 #ifndef __SOF_INTEL_HDA_H 12 12 #define __SOF_INTEL_HDA_H 13 13 14 + #include <linux/soundwire/sdw.h> 15 + #include <linux/soundwire/sdw_intel.h> 16 + #include <sound/compress_driver.h> 14 17 #include <sound/hda_codec.h> 15 18 #include <sound/hdaudio_ext.h> 16 19 #include "shim.h" ··· 177 174 * value cannot be read back within the specified time. 178 175 */ 179 176 #define HDA_DSP_STREAM_RUN_TIMEOUT 300 180 - #define HDA_DSP_CL_TRIGGER_TIMEOUT 300 181 177 182 178 #define HDA_DSP_SPIB_ENABLE 1 183 179 #define HDA_DSP_SPIB_DISABLE 0 ··· 231 229 #define HDA_DSP_REG_ADSPIS (HDA_DSP_GEN_BASE + 0x0C) 232 230 #define HDA_DSP_REG_ADSPIC2 (HDA_DSP_GEN_BASE + 0x10) 233 231 #define HDA_DSP_REG_ADSPIS2 (HDA_DSP_GEN_BASE + 0x14) 232 + 233 + #define HDA_DSP_REG_ADSPIS2_SNDW BIT(5) 234 + #define HDA_DSP_REG_SNDW_WAKE_STS 0x2C192 234 235 235 236 /* Intel HD Audio Inter-Processor Communication Registers */ 236 237 #define HDA_DSP_IPC_BASE 0x40 ··· 353 348 354 349 /* Number of DAIs */ 355 350 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 351 + 352 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 353 + #define SOF_SKL_NUM_DAIS 16 354 + #else 356 355 #define SOF_SKL_NUM_DAIS 15 356 + #endif 357 + 357 358 #else 358 359 #define SOF_SKL_NUM_DAIS 8 359 360 #endif ··· 403 392 #define SOF_HDA_PLAYBACK 0 404 393 #define SOF_HDA_CAPTURE 1 405 394 395 + /* 396 + * Time in ms for opportunistic D0I3 entry delay. 397 + * This has been deliberately chosen to be long to avoid race conditions. 398 + * Could be optimized in future. 399 + */ 400 + #define SOF_HDA_D0I3_WORK_DELAY_MS 5000 401 + 402 + /* HDA DSP D0 substate */ 403 + enum sof_hda_D0_substate { 404 + SOF_HDA_DSP_PM_D0I0, /* default D0 substate */ 405 + SOF_HDA_DSP_PM_D0I3, /* low power D0 substate */ 406 + }; 407 + 406 408 /* represents DSP HDA controller frontend - i.e. host facing control */ 407 409 struct sof_intel_hda_dev { 408 410 ··· 438 414 439 415 /* DMIC device */ 440 416 struct platform_device *dmic_dev; 417 + 418 + /* delayed work to enter D0I3 opportunistically */ 419 + struct delayed_work d0i3_work; 420 + 421 + /* ACPI information stored between scan and probe steps */ 422 + struct sdw_intel_acpi_info info; 423 + 424 + /* sdw context allocated by SoundWire driver */ 425 + struct sdw_intel_ctx *sdw; 441 426 }; 442 427 443 428 static inline struct hdac_bus *sof_to_bus(struct snd_sof_dev *s) ··· 502 469 void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev); 503 470 504 471 int hda_dsp_set_power_state(struct snd_sof_dev *sdev, 505 - enum sof_d0_substate d0_substate); 472 + const struct sof_dsp_power_state *target_state); 506 473 507 - int hda_dsp_suspend(struct snd_sof_dev *sdev); 474 + int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state); 508 475 int hda_dsp_resume(struct snd_sof_dev *sdev); 509 476 int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev); 510 477 int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); ··· 514 481 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); 515 482 void hda_ipc_dump(struct snd_sof_dev *sdev); 516 483 void hda_ipc_irq_dump(struct snd_sof_dev *sdev); 484 + void hda_dsp_d0i3_work(struct work_struct *work); 517 485 518 486 /* 519 487 * DSP PCM Operations. 520 488 */ 489 + u32 hda_dsp_get_mult_div(struct snd_sof_dev *sdev, int rate); 490 + u32 hda_dsp_get_bits(struct snd_sof_dev *sdev, int sample_bits); 521 491 int hda_dsp_pcm_open(struct snd_sof_dev *sdev, 522 492 struct snd_pcm_substream *substream); 523 493 int hda_dsp_pcm_close(struct snd_sof_dev *sdev, ··· 568 532 int hda_ipc_pcm_params(struct snd_sof_dev *sdev, 569 533 struct snd_pcm_substream *substream, 570 534 const struct sof_ipc_pcm_params_reply *reply); 535 + 536 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 537 + /* 538 + * Probe Compress Operations. 539 + */ 540 + int hda_probe_compr_assign(struct snd_sof_dev *sdev, 541 + struct snd_compr_stream *cstream, 542 + struct snd_soc_dai *dai); 543 + int hda_probe_compr_free(struct snd_sof_dev *sdev, 544 + struct snd_compr_stream *cstream, 545 + struct snd_soc_dai *dai); 546 + int hda_probe_compr_set_params(struct snd_sof_dev *sdev, 547 + struct snd_compr_stream *cstream, 548 + struct snd_compr_params *params, 549 + struct snd_soc_dai *dai); 550 + int hda_probe_compr_trigger(struct snd_sof_dev *sdev, 551 + struct snd_compr_stream *cstream, int cmd, 552 + struct snd_soc_dai *dai); 553 + int hda_probe_compr_pointer(struct snd_sof_dev *sdev, 554 + struct snd_compr_stream *cstream, 555 + struct snd_compr_tstamp *tstamp, 556 + struct snd_soc_dai *dai); 557 + #endif 571 558 572 559 /* 573 560 * DSP IPC Operations. ··· 664 605 int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag); 665 606 int hda_dsp_trace_release(struct snd_sof_dev *sdev); 666 607 int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd); 608 + 609 + /* 610 + * SoundWire support 611 + */ 612 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) 613 + 614 + int hda_sdw_startup(struct snd_sof_dev *sdev); 615 + void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable); 616 + void hda_sdw_process_wakeen(struct snd_sof_dev *sdev); 617 + 618 + #else 619 + 620 + static inline int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) 621 + { 622 + return 0; 623 + } 624 + 625 + static inline int hda_sdw_probe(struct snd_sof_dev *sdev) 626 + { 627 + return 0; 628 + } 629 + 630 + static inline int hda_sdw_startup(struct snd_sof_dev *sdev) 631 + { 632 + return 0; 633 + } 634 + 635 + static inline int hda_sdw_exit(struct snd_sof_dev *sdev) 636 + { 637 + return 0; 638 + } 639 + 640 + static inline void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) 641 + { 642 + } 643 + 644 + static inline bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev) 645 + { 646 + return false; 647 + } 648 + 649 + static inline irqreturn_t hda_dsp_sdw_thread(int irq, void *context) 650 + { 651 + return IRQ_HANDLED; 652 + } 653 + 654 + static inline bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) 655 + { 656 + return false; 657 + } 658 + 659 + static inline void hda_sdw_process_wakeen(struct snd_sof_dev *sdev) 660 + { 661 + } 662 + #endif 667 663 668 664 /* common dai driver */ 669 665 extern struct snd_soc_dai_driver skl_dai[];
+34 -7
sound/soc/sof/ipc.c
··· 214 214 snd_sof_handle_fw_exception(ipc->sdev); 215 215 ret = -ETIMEDOUT; 216 216 } else { 217 - /* copy the data returned from DSP */ 218 217 ret = msg->reply_error; 219 - if (msg->reply_size) 220 - memcpy(reply_data, msg->reply_data, msg->reply_size); 221 - if (ret < 0) 218 + if (ret < 0) { 222 219 dev_err(sdev->dev, "error: ipc error for 0x%x size %zu\n", 223 220 hdr->cmd, msg->reply_size); 224 - else 221 + } else { 225 222 ipc_log_header(sdev->dev, "ipc tx succeeded", hdr->cmd); 223 + if (msg->reply_size) 224 + /* copy the data returned from DSP */ 225 + memcpy(reply_data, msg->reply_data, 226 + msg->reply_size); 227 + } 226 228 } 227 229 228 230 return ret; ··· 270 268 spin_unlock_irq(&sdev->ipc_lock); 271 269 272 270 if (ret < 0) { 273 - /* So far IPC TX never fails, consider making the above void */ 274 271 dev_err_ratelimited(sdev->dev, 275 272 "error: ipc tx failed with error %d\n", 276 273 ret); ··· 290 289 void *msg_data, size_t msg_bytes, void *reply_data, 291 290 size_t reply_bytes) 292 291 { 292 + const struct sof_dsp_power_state target_state = { 293 + .state = SOF_DSP_PM_D0, 294 + }; 295 + int ret; 296 + 297 + /* ensure the DSP is in D0 before sending a new IPC */ 298 + ret = snd_sof_dsp_set_power_state(ipc->sdev, &target_state); 299 + if (ret < 0) { 300 + dev_err(ipc->sdev->dev, "error: resuming DSP %d\n", ret); 301 + return ret; 302 + } 303 + 304 + return sof_ipc_tx_message_no_pm(ipc, header, msg_data, msg_bytes, 305 + reply_data, reply_bytes); 306 + } 307 + EXPORT_SYMBOL(sof_ipc_tx_message); 308 + 309 + /* 310 + * send IPC message from host to DSP without modifying the DSP state. 311 + * This will be used for IPC's that can be handled by the DSP 312 + * even in a low-power D0 substate. 313 + */ 314 + int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, u32 header, 315 + void *msg_data, size_t msg_bytes, 316 + void *reply_data, size_t reply_bytes) 317 + { 293 318 int ret; 294 319 295 320 if (msg_bytes > SOF_IPC_MSG_MAX_SIZE || ··· 332 305 333 306 return ret; 334 307 } 335 - EXPORT_SYMBOL(sof_ipc_tx_message); 308 + EXPORT_SYMBOL(sof_ipc_tx_message_no_pm); 336 309 337 310 /* handle reply message from DSP */ 338 311 int snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id)
-6
sound/soc/sof/loader.c
··· 95 95 96 96 /* process structure data */ 97 97 switch (ext_hdr->type) { 98 - case SOF_IPC_EXT_DMA_BUFFER: 99 - ret = 0; 100 - break; 101 98 case SOF_IPC_EXT_WINDOW: 102 99 ret = get_ext_windows(sdev, ext_hdr); 103 100 break; ··· 465 468 struct snd_sof_pdata *plat_data = sdev->pdata; 466 469 const char *fw_filename; 467 470 int ret; 468 - 469 - /* set code loading condition to true */ 470 - sdev->code_loading = 1; 471 471 472 472 /* Don't request firmware again if firmware is already requested */ 473 473 if (plat_data->fw)
+52 -7
sound/soc/sof/ops.h
··· 146 146 return 0; 147 147 } 148 148 149 - static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev) 149 + static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev, 150 + u32 target_state) 150 151 { 151 152 if (sof_ops(sdev)->suspend) 152 - return sof_ops(sdev)->suspend(sdev); 153 + return sof_ops(sdev)->suspend(sdev, target_state); 153 154 154 155 return 0; 155 156 } ··· 194 193 return 0; 195 194 } 196 195 197 - static inline int snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, 198 - enum sof_d0_substate substate) 196 + static inline int 197 + snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, 198 + const struct sof_dsp_power_state *target_state) 199 199 { 200 200 if (sof_ops(sdev)->set_power_state) 201 - return sof_ops(sdev)->set_power_state(sdev, substate); 201 + return sof_ops(sdev)->set_power_state(sdev, target_state); 202 202 203 - /* D0 substate is not supported */ 204 - return -ENOTSUPP; 203 + /* D0 substate is not supported, do nothing here. */ 204 + return 0; 205 205 } 206 206 207 207 /* debug */ ··· 392 390 393 391 return 0; 394 392 } 393 + 394 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 395 + static inline int 396 + snd_sof_probe_compr_assign(struct snd_sof_dev *sdev, 397 + struct snd_compr_stream *cstream, struct snd_soc_dai *dai) 398 + { 399 + return sof_ops(sdev)->probe_assign(sdev, cstream, dai); 400 + } 401 + 402 + static inline int 403 + snd_sof_probe_compr_free(struct snd_sof_dev *sdev, 404 + struct snd_compr_stream *cstream, struct snd_soc_dai *dai) 405 + { 406 + return sof_ops(sdev)->probe_free(sdev, cstream, dai); 407 + } 408 + 409 + static inline int 410 + snd_sof_probe_compr_set_params(struct snd_sof_dev *sdev, 411 + struct snd_compr_stream *cstream, 412 + struct snd_compr_params *params, struct snd_soc_dai *dai) 413 + { 414 + return sof_ops(sdev)->probe_set_params(sdev, cstream, params, dai); 415 + } 416 + 417 + static inline int 418 + snd_sof_probe_compr_trigger(struct snd_sof_dev *sdev, 419 + struct snd_compr_stream *cstream, int cmd, 420 + struct snd_soc_dai *dai) 421 + { 422 + return sof_ops(sdev)->probe_trigger(sdev, cstream, cmd, dai); 423 + } 424 + 425 + static inline int 426 + snd_sof_probe_compr_pointer(struct snd_sof_dev *sdev, 427 + struct snd_compr_stream *cstream, 428 + struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) 429 + { 430 + if (sof_ops(sdev) && sof_ops(sdev)->probe_pointer) 431 + return sof_ops(sdev)->probe_pointer(sdev, cstream, tstamp, dai); 432 + 433 + return 0; 434 + } 435 + #endif 395 436 396 437 /* machine driver */ 397 438 static inline int
+11 -8
sound/soc/sof/pcm.c
··· 16 16 #include "sof-priv.h" 17 17 #include "sof-audio.h" 18 18 #include "ops.h" 19 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 20 + #include "compress.h" 21 + #endif 19 22 20 23 /* Create DMA buffer page table for DSP */ 21 24 static int create_page_table(struct snd_soc_component *component, ··· 57 54 /* 58 55 * sof pcm period elapse work 59 56 */ 60 - static void sof_pcm_period_elapsed_work(struct work_struct *work) 57 + void snd_sof_pcm_period_elapsed_work(struct work_struct *work) 61 58 { 62 59 struct snd_sof_pcm_stream *sps = 63 60 container_of(work, struct snd_sof_pcm_stream, ··· 375 372 stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_START; 376 373 break; 377 374 case SNDRV_PCM_TRIGGER_SUSPEND: 378 - if (sdev->s0_suspend && 375 + if (sdev->system_suspend_target == SOF_SUSPEND_S0IX && 379 376 spcm->stream[substream->stream].d0i3_compatible) { 380 377 /* 381 378 * trap the event, not sending trigger stop to ··· 475 472 dev_dbg(component->dev, "pcm: open stream %d dir %d\n", 476 473 spcm->pcm.pcm_id, substream->stream); 477 474 478 - INIT_WORK(&spcm->stream[substream->stream].period_elapsed_work, 479 - sof_pcm_period_elapsed_work); 480 475 481 476 caps = &spcm->pcm.caps[substream->stream]; 482 477 ··· 599 598 600 599 snd_pcm_set_managed_buffer(pcm->streams[stream].substream, 601 600 SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 602 - le32_to_cpu(caps->buffer_size_min), 603 - le32_to_cpu(caps->buffer_size_max)); 601 + 0, le32_to_cpu(caps->buffer_size_max)); 604 602 capture: 605 603 stream = SNDRV_PCM_STREAM_CAPTURE; 606 604 ··· 621 621 622 622 snd_pcm_set_managed_buffer(pcm->streams[stream].substream, 623 623 SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 624 - le32_to_cpu(caps->buffer_size_min), 625 - le32_to_cpu(caps->buffer_size_max)); 624 + 0, le32_to_cpu(caps->buffer_size_max)); 626 625 627 626 return 0; 628 627 } ··· 786 787 787 788 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) 788 789 pd->compr_ops = &sof_compressed_ops; 790 + #endif 791 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 792 + /* override cops when probe support is enabled */ 793 + pd->compr_ops = &sof_probe_compressed_ops; 789 794 #endif 790 795 pd->pcm_construct = sof_pcm_new; 791 796 pd->ignore_machine = drv_name;
+65 -111
sound/soc/sof/pm.c
··· 12 12 #include "sof-priv.h" 13 13 #include "sof-audio.h" 14 14 15 + /* 16 + * Helper function to determine the target DSP state during 17 + * system suspend. This function only cares about the device 18 + * D-states. Platform-specific substates, if any, should be 19 + * handled by the platform-specific parts. 20 + */ 21 + static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev) 22 + { 23 + u32 target_dsp_state; 24 + 25 + switch (sdev->system_suspend_target) { 26 + case SOF_SUSPEND_S3: 27 + /* DSP should be in D3 if the system is suspending to S3 */ 28 + target_dsp_state = SOF_DSP_PM_D3; 29 + break; 30 + case SOF_SUSPEND_S0IX: 31 + /* 32 + * Currently, the only criterion for retaining the DSP in D0 33 + * is that there are streams that ignored the suspend trigger. 34 + * Additional criteria such Soundwire clock-stop mode and 35 + * device suspend latency considerations will be added later. 36 + */ 37 + if (snd_sof_stream_suspend_ignored(sdev)) 38 + target_dsp_state = SOF_DSP_PM_D0; 39 + else 40 + target_dsp_state = SOF_DSP_PM_D3; 41 + break; 42 + default: 43 + /* This case would be during runtime suspend */ 44 + target_dsp_state = SOF_DSP_PM_D3; 45 + break; 46 + } 47 + 48 + return target_dsp_state; 49 + } 50 + 15 51 static int sof_send_pm_ctx_ipc(struct snd_sof_dev *sdev, int cmd) 16 52 { 17 53 struct sof_ipc_pm_ctx pm_ctx; ··· 86 50 static int sof_resume(struct device *dev, bool runtime_resume) 87 51 { 88 52 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 53 + u32 old_state = sdev->dsp_power_state.state; 89 54 int ret; 90 55 91 56 /* do nothing if dsp resume callbacks are not set */ ··· 110 73 "error: failed to power up DSP after resume\n"); 111 74 return ret; 112 75 } 76 + 77 + /* Nothing further to do if resuming from a low-power D0 substate */ 78 + if (!runtime_resume && old_state == SOF_DSP_PM_D0) 79 + return 0; 113 80 114 81 sdev->fw_state = SOF_FW_BOOT_PREPARE; 115 82 ··· 165 124 "error: ctx_restore ipc error during resume %d\n", 166 125 ret); 167 126 168 - /* initialize default D0 sub-state */ 169 - sdev->d0_substate = SOF_DSP_D0I0; 170 - 171 127 return ret; 172 128 } 173 129 174 130 static int sof_suspend(struct device *dev, bool runtime_suspend) 175 131 { 176 132 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 133 + u32 target_state = 0; 177 134 int ret; 178 135 179 136 /* do nothing if dsp suspend callback is not set */ ··· 179 140 return 0; 180 141 181 142 if (sdev->fw_state != SOF_FW_BOOT_COMPLETE) 182 - goto power_down; 183 - 184 - /* release trace */ 185 - snd_sof_release_trace(sdev); 143 + goto suspend; 186 144 187 145 /* set restore_stream for all streams during system suspend */ 188 146 if (!runtime_suspend) { ··· 191 155 return ret; 192 156 } 193 157 } 158 + 159 + target_state = snd_sof_dsp_power_target(sdev); 160 + 161 + /* Skip to platform-specific suspend if DSP is entering D0 */ 162 + if (target_state == SOF_DSP_PM_D0) 163 + goto suspend; 164 + 165 + /* release trace */ 166 + snd_sof_release_trace(sdev); 194 167 195 168 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) 196 169 /* cache debugfs contents during runtime suspend */ ··· 224 179 ret); 225 180 } 226 181 227 - power_down: 182 + suspend: 228 183 229 184 /* return if the DSP was not probed successfully */ 230 185 if (sdev->fw_state == SOF_FW_BOOT_NOT_STARTED) 231 186 return 0; 232 187 233 - /* power down all DSP cores */ 188 + /* platform-specific suspend */ 234 189 if (runtime_suspend) 235 190 ret = snd_sof_dsp_runtime_suspend(sdev); 236 191 else 237 - ret = snd_sof_dsp_suspend(sdev); 192 + ret = snd_sof_dsp_suspend(sdev, target_state); 238 193 if (ret < 0) 239 194 dev_err(sdev->dev, 240 195 "error: failed to power down DSP during suspend %d\n", 241 196 ret); 197 + 198 + /* Do not reset FW state if DSP is in D0 */ 199 + if (target_state == SOF_DSP_PM_D0) 200 + return ret; 242 201 243 202 /* reset FW state */ 244 203 sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; ··· 270 221 } 271 222 EXPORT_SYMBOL(snd_sof_runtime_resume); 272 223 273 - int snd_sof_set_d0_substate(struct snd_sof_dev *sdev, 274 - enum sof_d0_substate d0_substate) 275 - { 276 - int ret; 277 - 278 - if (sdev->d0_substate == d0_substate) 279 - return 0; 280 - 281 - /* do platform specific set_state */ 282 - ret = snd_sof_dsp_set_power_state(sdev, d0_substate); 283 - if (ret < 0) 284 - return ret; 285 - 286 - /* update dsp D0 sub-state */ 287 - sdev->d0_substate = d0_substate; 288 - 289 - return 0; 290 - } 291 - EXPORT_SYMBOL(snd_sof_set_d0_substate); 292 - 293 - /* 294 - * Audio DSP states may transform as below:- 295 - * 296 - * D0I3 compatible stream 297 - * Runtime +---------------------+ opened only, timeout 298 - * suspend | +--------------------+ 299 - * +------------+ D0(active) | | 300 - * | | <---------------+ | 301 - * | +--------> | | | 302 - * | |Runtime +--^--+---------^--+--+ The last | | 303 - * | |resume | | | | opened D0I3 | | 304 - * | | | | | | compatible | | 305 - * | | resume| | | | stream closed | | 306 - * | | from | | D3 | | | | 307 - * | | D3 | |suspend | | d0i3 | | 308 - * | | | | | |suspend | | 309 - * | | | | | | | | 310 - * | | | | | | | | 311 - * +-v---+-----------+--v-------+ | | +------+----v----+ 312 - * | | | +-----------> | 313 - * | D3 (suspended) | | | D0I3 +-----+ 314 - * | | +--------------+ | | 315 - * | | resume from | | | 316 - * +-------------------^--------+ d0i3 suspend +----------------+ | 317 - * | | 318 - * | D3 suspend | 319 - * +------------------------------------------------+ 320 - * 321 - * d0i3_suspend = s0_suspend && D0I3 stream opened, 322 - * D3 suspend = !d0i3_suspend, 323 - */ 324 - 325 224 int snd_sof_resume(struct device *dev) 326 225 { 327 - struct snd_sof_dev *sdev = dev_get_drvdata(dev); 328 - int ret; 329 - 330 - if (snd_sof_dsp_d0i3_on_suspend(sdev)) { 331 - /* resume from D0I3 */ 332 - dev_dbg(sdev->dev, "DSP will exit from D0i3...\n"); 333 - ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I0); 334 - if (ret == -ENOTSUPP) { 335 - /* fallback to resume from D3 */ 336 - dev_dbg(sdev->dev, "D0i3 not supported, fall back to resume from D3...\n"); 337 - goto d3_resume; 338 - } else if (ret < 0) { 339 - dev_err(sdev->dev, "error: failed to exit from D0I3 %d\n", 340 - ret); 341 - return ret; 342 - } 343 - 344 - /* platform-specific resume from D0i3 */ 345 - return snd_sof_dsp_resume(sdev); 346 - } 347 - 348 - d3_resume: 349 - /* resume from D3 */ 350 226 return sof_resume(dev, false); 351 227 } 352 228 EXPORT_SYMBOL(snd_sof_resume); 353 229 354 230 int snd_sof_suspend(struct device *dev) 355 231 { 356 - struct snd_sof_dev *sdev = dev_get_drvdata(dev); 357 - int ret; 358 - 359 - if (snd_sof_dsp_d0i3_on_suspend(sdev)) { 360 - /* suspend to D0i3 */ 361 - dev_dbg(sdev->dev, "DSP is trying to enter D0i3...\n"); 362 - ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3); 363 - if (ret == -ENOTSUPP) { 364 - /* fallback to D3 suspend */ 365 - dev_dbg(sdev->dev, "D0i3 not supported, fall back to D3...\n"); 366 - goto d3_suspend; 367 - } else if (ret < 0) { 368 - dev_err(sdev->dev, "error: failed to enter D0I3, %d\n", 369 - ret); 370 - return ret; 371 - } 372 - 373 - /* platform-specific suspend to D0i3 */ 374 - return snd_sof_dsp_suspend(sdev); 375 - } 376 - 377 - d3_suspend: 378 - /* suspend to D3 */ 379 232 return sof_suspend(dev, false); 380 233 } 381 234 EXPORT_SYMBOL(snd_sof_suspend); ··· 287 336 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 288 337 289 338 #if defined(CONFIG_ACPI) 290 - sdev->s0_suspend = acpi_target_system_state() == ACPI_STATE_S0; 339 + if (acpi_target_system_state() == ACPI_STATE_S0) 340 + sdev->system_suspend_target = SOF_SUSPEND_S0IX; 341 + else 342 + sdev->system_suspend_target = SOF_SUSPEND_S3; 291 343 #else 292 344 /* will suspend to S3 by default */ 293 - sdev->s0_suspend = false; 345 + sdev->system_suspend_target = SOF_SUSPEND_S3; 294 346 #endif 295 347 296 348 return 0; ··· 304 350 { 305 351 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 306 352 307 - sdev->s0_suspend = false; 353 + sdev->system_suspend_target = SOF_SUSPEND_NONE; 308 354 } 309 355 EXPORT_SYMBOL(snd_sof_complete);
+290
sound/soc/sof/probe.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7 + // 8 + // Author: Cezary Rojewski <cezary.rojewski@intel.com> 9 + // 10 + 11 + #include "sof-priv.h" 12 + #include "probe.h" 13 + 14 + /** 15 + * sof_ipc_probe_init - initialize data probing 16 + * @sdev: SOF sound device 17 + * @stream_tag: Extractor stream tag 18 + * @buffer_size: DMA buffer size to set for extractor 19 + * 20 + * Host chooses whether extraction is supported or not by providing 21 + * valid stream tag to DSP. Once specified, stream described by that 22 + * tag will be tied to DSP for extraction for the entire lifetime of 23 + * probe. 24 + * 25 + * Probing is initialized only once and each INIT request must be 26 + * matched by DEINIT call. 27 + */ 28 + int sof_ipc_probe_init(struct snd_sof_dev *sdev, 29 + u32 stream_tag, size_t buffer_size) 30 + { 31 + struct sof_ipc_probe_dma_add_params *msg; 32 + struct sof_ipc_reply reply; 33 + size_t size = struct_size(msg, dma, 1); 34 + int ret; 35 + 36 + msg = kmalloc(size, GFP_KERNEL); 37 + if (!msg) 38 + return -ENOMEM; 39 + msg->hdr.size = size; 40 + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_INIT; 41 + msg->num_elems = 1; 42 + msg->dma[0].stream_tag = stream_tag; 43 + msg->dma[0].dma_buffer_size = buffer_size; 44 + 45 + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, 46 + &reply, sizeof(reply)); 47 + kfree(msg); 48 + return ret; 49 + } 50 + EXPORT_SYMBOL(sof_ipc_probe_init); 51 + 52 + /** 53 + * sof_ipc_probe_deinit - cleanup after data probing 54 + * @sdev: SOF sound device 55 + * 56 + * Host sends DEINIT request to free previously initialized probe 57 + * on DSP side once it is no longer needed. DEINIT only when there 58 + * are no probes connected and with all injectors detached. 59 + */ 60 + int sof_ipc_probe_deinit(struct snd_sof_dev *sdev) 61 + { 62 + struct sof_ipc_cmd_hdr msg; 63 + struct sof_ipc_reply reply; 64 + 65 + msg.size = sizeof(msg); 66 + msg.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DEINIT; 67 + 68 + return sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size, 69 + &reply, sizeof(reply)); 70 + } 71 + EXPORT_SYMBOL(sof_ipc_probe_deinit); 72 + 73 + static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd, 74 + void **params, size_t *num_params) 75 + { 76 + struct sof_ipc_probe_info_params msg = {{{0}}}; 77 + struct sof_ipc_probe_info_params *reply; 78 + size_t bytes; 79 + int ret; 80 + 81 + *params = NULL; 82 + *num_params = 0; 83 + 84 + reply = kzalloc(SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL); 85 + if (!reply) 86 + return -ENOMEM; 87 + msg.rhdr.hdr.size = sizeof(msg); 88 + msg.rhdr.hdr.cmd = SOF_IPC_GLB_PROBE | cmd; 89 + 90 + ret = sof_ipc_tx_message(sdev->ipc, msg.rhdr.hdr.cmd, &msg, 91 + msg.rhdr.hdr.size, reply, SOF_IPC_MSG_MAX_SIZE); 92 + if (ret < 0 || reply->rhdr.error < 0) 93 + goto exit; 94 + 95 + if (!reply->num_elems) 96 + goto exit; 97 + 98 + if (cmd == SOF_IPC_PROBE_DMA_INFO) 99 + bytes = sizeof(reply->dma[0]); 100 + else 101 + bytes = sizeof(reply->desc[0]); 102 + bytes *= reply->num_elems; 103 + *params = kmemdup(&reply->dma[0], bytes, GFP_KERNEL); 104 + if (!*params) { 105 + ret = -ENOMEM; 106 + goto exit; 107 + } 108 + *num_params = reply->num_elems; 109 + 110 + exit: 111 + kfree(reply); 112 + return ret; 113 + } 114 + 115 + /** 116 + * sof_ipc_probe_dma_info - retrieve list of active injection dmas 117 + * @sdev: SOF sound device 118 + * @dma: Returned list of active dmas 119 + * @num_dma: Returned count of active dmas 120 + * 121 + * Host sends DMA_INFO request to obtain list of injection dmas it 122 + * can use to transfer data over with. 123 + * 124 + * Note that list contains only injection dmas as there is only one 125 + * extractor (dma) and it is always assigned on probing init. 126 + * DSP knows exactly where data from extraction probes is going to, 127 + * which is not the case for injection where multiple streams 128 + * could be engaged. 129 + */ 130 + int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, 131 + struct sof_probe_dma **dma, size_t *num_dma) 132 + { 133 + return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_DMA_INFO, 134 + (void **)dma, num_dma); 135 + } 136 + EXPORT_SYMBOL(sof_ipc_probe_dma_info); 137 + 138 + /** 139 + * sof_ipc_probe_dma_add - attach to specified dmas 140 + * @sdev: SOF sound device 141 + * @dma: List of streams (dmas) to attach to 142 + * @num_dma: Number of elements in @dma 143 + * 144 + * Contrary to extraction, injection streams are never assigned 145 + * on init. Before attempting any data injection, host is responsible 146 + * for specifying streams which will be later used to transfer data 147 + * to connected probe points. 148 + */ 149 + int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, 150 + struct sof_probe_dma *dma, size_t num_dma) 151 + { 152 + struct sof_ipc_probe_dma_add_params *msg; 153 + struct sof_ipc_reply reply; 154 + size_t size = struct_size(msg, dma, num_dma); 155 + int ret; 156 + 157 + msg = kmalloc(size, GFP_KERNEL); 158 + if (!msg) 159 + return -ENOMEM; 160 + msg->hdr.size = size; 161 + msg->num_elems = num_dma; 162 + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_ADD; 163 + memcpy(&msg->dma[0], dma, size - sizeof(*msg)); 164 + 165 + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, 166 + &reply, sizeof(reply)); 167 + kfree(msg); 168 + return ret; 169 + } 170 + EXPORT_SYMBOL(sof_ipc_probe_dma_add); 171 + 172 + /** 173 + * sof_ipc_probe_dma_remove - detach from specified dmas 174 + * @sdev: SOF sound device 175 + * @stream_tag: List of stream tags to detach from 176 + * @num_stream_tag: Number of elements in @stream_tag 177 + * 178 + * Host sends DMA_REMOVE request to free previously attached stream 179 + * from being occupied for injection. Each detach operation should 180 + * match equivalent DMA_ADD. Detach only when all probes tied to 181 + * given stream have been disconnected. 182 + */ 183 + int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, 184 + unsigned int *stream_tag, size_t num_stream_tag) 185 + { 186 + struct sof_ipc_probe_dma_remove_params *msg; 187 + struct sof_ipc_reply reply; 188 + size_t size = struct_size(msg, stream_tag, num_stream_tag); 189 + int ret; 190 + 191 + msg = kmalloc(size, GFP_KERNEL); 192 + if (!msg) 193 + return -ENOMEM; 194 + msg->hdr.size = size; 195 + msg->num_elems = num_stream_tag; 196 + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_REMOVE; 197 + memcpy(&msg->stream_tag[0], stream_tag, size - sizeof(*msg)); 198 + 199 + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, 200 + &reply, sizeof(reply)); 201 + kfree(msg); 202 + return ret; 203 + } 204 + EXPORT_SYMBOL(sof_ipc_probe_dma_remove); 205 + 206 + /** 207 + * sof_ipc_probe_points_info - retrieve list of active probe points 208 + * @sdev: SOF sound device 209 + * @desc: Returned list of active probes 210 + * @num_desc: Returned count of active probes 211 + * 212 + * Host sends PROBE_POINT_INFO request to obtain list of active probe 213 + * points, valid for disconnection when given probe is no longer 214 + * required. 215 + */ 216 + int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, 217 + struct sof_probe_point_desc **desc, size_t *num_desc) 218 + { 219 + return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_POINT_INFO, 220 + (void **)desc, num_desc); 221 + } 222 + EXPORT_SYMBOL(sof_ipc_probe_points_info); 223 + 224 + /** 225 + * sof_ipc_probe_points_add - connect specified probes 226 + * @sdev: SOF sound device 227 + * @desc: List of probe points to connect 228 + * @num_desc: Number of elements in @desc 229 + * 230 + * Dynamically connects to provided set of endpoints. Immediately 231 + * after connection is established, host must be prepared to 232 + * transfer data from or to target stream given the probing purpose. 233 + * 234 + * Each probe point should be removed using PROBE_POINT_REMOVE 235 + * request when no longer needed. 236 + */ 237 + int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, 238 + struct sof_probe_point_desc *desc, size_t num_desc) 239 + { 240 + struct sof_ipc_probe_point_add_params *msg; 241 + struct sof_ipc_reply reply; 242 + size_t size = struct_size(msg, desc, num_desc); 243 + int ret; 244 + 245 + msg = kmalloc(size, GFP_KERNEL); 246 + if (!msg) 247 + return -ENOMEM; 248 + msg->hdr.size = size; 249 + msg->num_elems = num_desc; 250 + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_ADD; 251 + memcpy(&msg->desc[0], desc, size - sizeof(*msg)); 252 + 253 + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, 254 + &reply, sizeof(reply)); 255 + kfree(msg); 256 + return ret; 257 + } 258 + EXPORT_SYMBOL(sof_ipc_probe_points_add); 259 + 260 + /** 261 + * sof_ipc_probe_points_remove - disconnect specified probes 262 + * @sdev: SOF sound device 263 + * @buffer_id: List of probe points to disconnect 264 + * @num_buffer_id: Number of elements in @desc 265 + * 266 + * Removes previously connected probes from list of active probe 267 + * points and frees all resources on DSP side. 268 + */ 269 + int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, 270 + unsigned int *buffer_id, size_t num_buffer_id) 271 + { 272 + struct sof_ipc_probe_point_remove_params *msg; 273 + struct sof_ipc_reply reply; 274 + size_t size = struct_size(msg, buffer_id, num_buffer_id); 275 + int ret; 276 + 277 + msg = kmalloc(size, GFP_KERNEL); 278 + if (!msg) 279 + return -ENOMEM; 280 + msg->hdr.size = size; 281 + msg->num_elems = num_buffer_id; 282 + msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_POINT_REMOVE; 283 + memcpy(&msg->buffer_id[0], buffer_id, size - sizeof(*msg)); 284 + 285 + ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, 286 + &reply, sizeof(reply)); 287 + kfree(msg); 288 + return ret; 289 + } 290 + EXPORT_SYMBOL(sof_ipc_probe_points_remove);
+85
sound/soc/sof/probe.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 + /* 3 + * This file is provided under a dual BSD/GPLv2 license. When using or 4 + * redistributing this file, you may do so under either license. 5 + * 6 + * Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7 + * 8 + * Author: Cezary Rojewski <cezary.rojewski@intel.com> 9 + */ 10 + 11 + #ifndef __SOF_PROBE_H 12 + #define __SOF_PROBE_H 13 + 14 + #include <sound/sof/header.h> 15 + 16 + struct snd_sof_dev; 17 + 18 + #define SOF_PROBE_INVALID_NODE_ID UINT_MAX 19 + 20 + struct sof_probe_dma { 21 + unsigned int stream_tag; 22 + unsigned int dma_buffer_size; 23 + } __packed; 24 + 25 + enum sof_connection_purpose { 26 + SOF_CONNECTION_PURPOSE_EXTRACT = 1, 27 + SOF_CONNECTION_PURPOSE_INJECT, 28 + }; 29 + 30 + struct sof_probe_point_desc { 31 + unsigned int buffer_id; 32 + unsigned int purpose; 33 + unsigned int stream_tag; 34 + } __packed; 35 + 36 + struct sof_ipc_probe_dma_add_params { 37 + struct sof_ipc_cmd_hdr hdr; 38 + unsigned int num_elems; 39 + struct sof_probe_dma dma[0]; 40 + } __packed; 41 + 42 + struct sof_ipc_probe_info_params { 43 + struct sof_ipc_reply rhdr; 44 + unsigned int num_elems; 45 + union { 46 + struct sof_probe_dma dma[0]; 47 + struct sof_probe_point_desc desc[0]; 48 + }; 49 + } __packed; 50 + 51 + struct sof_ipc_probe_dma_remove_params { 52 + struct sof_ipc_cmd_hdr hdr; 53 + unsigned int num_elems; 54 + unsigned int stream_tag[0]; 55 + } __packed; 56 + 57 + struct sof_ipc_probe_point_add_params { 58 + struct sof_ipc_cmd_hdr hdr; 59 + unsigned int num_elems; 60 + struct sof_probe_point_desc desc[0]; 61 + } __packed; 62 + 63 + struct sof_ipc_probe_point_remove_params { 64 + struct sof_ipc_cmd_hdr hdr; 65 + unsigned int num_elems; 66 + unsigned int buffer_id[0]; 67 + } __packed; 68 + 69 + int sof_ipc_probe_init(struct snd_sof_dev *sdev, 70 + u32 stream_tag, size_t buffer_size); 71 + int sof_ipc_probe_deinit(struct snd_sof_dev *sdev); 72 + int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, 73 + struct sof_probe_dma **dma, size_t *num_dma); 74 + int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, 75 + struct sof_probe_dma *dma, size_t num_dma); 76 + int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, 77 + unsigned int *stream_tag, size_t num_stream_tag); 78 + int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, 79 + struct sof_probe_point_desc **desc, size_t *num_desc); 80 + int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, 81 + struct sof_probe_point_desc *desc, size_t num_desc); 82 + int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, 83 + unsigned int *buffer_id, size_t num_buffer_id); 84 + 85 + #endif
+47 -12
sound/soc/sof/sof-audio.c
··· 11 11 #include "sof-audio.h" 12 12 #include "ops.h" 13 13 14 - bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev) 14 + /* 15 + * helper to determine if there are only D0i3 compatible 16 + * streams active 17 + */ 18 + bool snd_sof_dsp_only_d0i3_compatible_stream_active(struct snd_sof_dev *sdev) 19 + { 20 + struct snd_pcm_substream *substream; 21 + struct snd_sof_pcm *spcm; 22 + bool d0i3_compatible_active = false; 23 + int dir; 24 + 25 + list_for_each_entry(spcm, &sdev->pcm_list, list) { 26 + for_each_pcm_streams(dir) { 27 + substream = spcm->stream[dir].substream; 28 + if (!substream || !substream->runtime) 29 + continue; 30 + 31 + /* 32 + * substream->runtime being not NULL indicates that 33 + * that the stream is open. No need to check the 34 + * stream state. 35 + */ 36 + if (!spcm->stream[dir].d0i3_compatible) 37 + return false; 38 + 39 + d0i3_compatible_active = true; 40 + } 41 + } 42 + 43 + return d0i3_compatible_active; 44 + } 45 + EXPORT_SYMBOL(snd_sof_dsp_only_d0i3_compatible_stream_active); 46 + 47 + bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev) 15 48 { 16 49 struct snd_sof_pcm *spcm; 17 50 ··· 71 38 * have been suspended. 72 39 */ 73 40 list_for_each_entry(spcm, &sdev->pcm_list, list) { 74 - for (dir = 0; dir <= SNDRV_PCM_STREAM_CAPTURE; dir++) { 41 + for_each_pcm_streams(dir) { 42 + /* 43 + * do not reset hw_params upon resume for streams that 44 + * were kept running during suspend 45 + */ 46 + if (spcm->stream[dir].suspend_ignored) 47 + continue; 48 + 75 49 substream = spcm->stream[dir].substream; 76 50 if (!substream || !substream->runtime) 77 51 continue; ··· 319 279 int dir; 320 280 321 281 list_for_each_entry(spcm, &sdev->pcm_list, list) { 322 - dir = SNDRV_PCM_STREAM_PLAYBACK; 323 - if (spcm->stream[dir].comp_id == comp_id) { 324 - *direction = dir; 325 - return spcm; 326 - } 327 - 328 - dir = SNDRV_PCM_STREAM_CAPTURE; 329 - if (spcm->stream[dir].comp_id == comp_id) { 330 - *direction = dir; 331 - return spcm; 282 + for_each_pcm_streams(dir) { 283 + if (spcm->stream[dir].comp_id == comp_id) { 284 + *direction = dir; 285 + return spcm; 286 + } 332 287 } 333 288 } 334 289
+5 -1
sound/soc/sof/sof-audio.h
··· 11 11 #ifndef __SOUND_SOC_SOF_AUDIO_H 12 12 #define __SOUND_SOC_SOF_AUDIO_H 13 13 14 + #include <linux/workqueue.h> 15 + 14 16 #include <sound/soc.h> 15 17 #include <sound/control.h> 16 18 #include <sound/sof/stream.h> /* needs to be included before control.h */ ··· 191 189 struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_soc_component *scomp, 192 190 unsigned int pcm_id); 193 191 void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream); 192 + void snd_sof_pcm_period_elapsed_work(struct work_struct *work); 194 193 195 194 /* 196 195 * Mixer IPC ··· 205 202 /* PM */ 206 203 int sof_restore_pipelines(struct device *dev); 207 204 int sof_set_hw_params_upon_resume(struct device *dev); 208 - bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev); 205 + bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev); 206 + bool snd_sof_dsp_only_d0i3_compatible_stream_active(struct snd_sof_dev *sdev); 209 207 210 208 /* Machine driver enumeration */ 211 209 int sof_machine_register(struct snd_sof_dev *sdev, void *pdata);
+10
sound/soc/sof/sof-of-dev.c
··· 13 13 #include "ops.h" 14 14 15 15 extern struct snd_sof_dsp_ops sof_imx8_ops; 16 + extern struct snd_sof_dsp_ops sof_imx8x_ops; 16 17 17 18 /* platform specific devices */ 18 19 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8) 19 20 static struct sof_dev_desc sof_of_imx8qxp_desc = { 21 + .default_fw_path = "imx/sof", 22 + .default_tplg_path = "imx/sof-tplg", 23 + .default_fw_filename = "sof-imx8x.ri", 24 + .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", 25 + .ops = &sof_imx8x_ops, 26 + }; 27 + 28 + static struct sof_dev_desc sof_of_imx8qm_desc = { 20 29 .default_fw_path = "imx/sof", 21 30 .default_tplg_path = "imx/sof-tplg", 22 31 .default_fw_filename = "sof-imx8.ri", ··· 112 103 static const struct of_device_id sof_of_ids[] = { 113 104 #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8) 114 105 { .compatible = "fsl,imx8qxp-dsp", .data = &sof_of_imx8qxp_desc}, 106 + { .compatible = "fsl,imx8qm-dsp", .data = &sof_of_imx8qm_desc}, 115 107 #endif 116 108 { } 117 109 };
+55 -16
sound/soc/sof/sof-priv.h
··· 54 54 (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) || \ 55 55 IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST)) 56 56 57 - /* DSP D0ix sub-state */ 58 - enum sof_d0_substate { 59 - SOF_DSP_D0I0 = 0, /* DSP default D0 substate */ 60 - SOF_DSP_D0I3, /* DSP D0i3(low power) substate*/ 57 + /* DSP power state */ 58 + enum sof_dsp_power_states { 59 + SOF_DSP_PM_D0, 60 + SOF_DSP_PM_D1, 61 + SOF_DSP_PM_D2, 62 + SOF_DSP_PM_D3_HOT, 63 + SOF_DSP_PM_D3, 64 + SOF_DSP_PM_D3_COLD, 65 + }; 66 + 67 + struct sof_dsp_power_state { 68 + u32 state; 69 + u32 substate; /* platform-specific */ 70 + }; 71 + 72 + /* System suspend target state */ 73 + enum sof_system_suspend_state { 74 + SOF_SUSPEND_NONE = 0, 75 + SOF_SUSPEND_S0IX, 76 + SOF_SUSPEND_S3, 61 77 }; 62 78 63 79 struct snd_sof_dev; ··· 170 154 snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev, 171 155 struct snd_pcm_substream *substream); /* optional */ 172 156 157 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 158 + /* Except for probe_pointer, all probe ops are mandatory */ 159 + int (*probe_assign)(struct snd_sof_dev *sdev, 160 + struct snd_compr_stream *cstream, 161 + struct snd_soc_dai *dai); /* mandatory */ 162 + int (*probe_free)(struct snd_sof_dev *sdev, 163 + struct snd_compr_stream *cstream, 164 + struct snd_soc_dai *dai); /* mandatory */ 165 + int (*probe_set_params)(struct snd_sof_dev *sdev, 166 + struct snd_compr_stream *cstream, 167 + struct snd_compr_params *params, 168 + struct snd_soc_dai *dai); /* mandatory */ 169 + int (*probe_trigger)(struct snd_sof_dev *sdev, 170 + struct snd_compr_stream *cstream, int cmd, 171 + struct snd_soc_dai *dai); /* mandatory */ 172 + int (*probe_pointer)(struct snd_sof_dev *sdev, 173 + struct snd_compr_stream *cstream, 174 + struct snd_compr_tstamp *tstamp, 175 + struct snd_soc_dai *dai); /* optional */ 176 + #endif 177 + 173 178 /* host read DSP stream data */ 174 179 void (*ipc_msg_data)(struct snd_sof_dev *sdev, 175 180 struct snd_pcm_substream *substream, ··· 206 169 int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */ 207 170 208 171 /* DSP PM */ 209 - int (*suspend)(struct snd_sof_dev *sof_dev); /* optional */ 172 + int (*suspend)(struct snd_sof_dev *sof_dev, 173 + u32 target_state); /* optional */ 210 174 int (*resume)(struct snd_sof_dev *sof_dev); /* optional */ 211 175 int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */ 212 176 int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ 213 177 int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */ 214 178 int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */ 215 179 int (*set_power_state)(struct snd_sof_dev *sdev, 216 - enum sof_d0_substate d0_substate); /* optional */ 180 + const struct sof_dsp_power_state *target_state); /* optional */ 217 181 218 182 /* DSP clocking */ 219 183 int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */ ··· 361 323 */ 362 324 struct snd_soc_component_driver plat_drv; 363 325 364 - /* power states related */ 365 - enum sof_d0_substate d0_substate; 366 - /* flag to track if the intended power target of suspend is S0ix */ 367 - bool s0_suspend; 326 + /* current DSP power state */ 327 + struct sof_dsp_power_state dsp_power_state; 328 + 329 + /* Intended power target of system suspend */ 330 + enum sof_system_suspend_state system_suspend_target; 368 331 369 332 /* DSP firmware boot */ 370 333 wait_queue_head_t boot_wait; ··· 415 376 u32 enabled_cores_mask; /* keep track of enabled cores */ 416 377 417 378 /* FW configuration */ 418 - struct sof_ipc_dma_buffer_data *info_buffer; 419 379 struct sof_ipc_window *info_window; 420 380 421 381 /* IPC timeouts in ms */ 422 382 int ipc_timeout; 423 383 int boot_timeout; 424 384 425 - /* Wait queue for code loading */ 426 - wait_queue_head_t waitq; 427 - int code_loading; 385 + #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 386 + unsigned int extractor_stream_tag; 387 + #endif 428 388 429 389 /* DMA for Trace */ 430 390 struct snd_dma_buffer dmatb; ··· 455 417 int snd_sof_suspend(struct device *dev); 456 418 int snd_sof_prepare(struct device *dev); 457 419 void snd_sof_complete(struct device *dev); 458 - int snd_sof_set_d0_substate(struct snd_sof_dev *sdev, 459 - enum sof_d0_substate d0_substate); 460 420 461 421 void snd_sof_new_platform_drv(struct snd_sof_dev *sdev); 462 422 ··· 490 454 int sof_ipc_tx_message(struct snd_sof_ipc *ipc, u32 header, 491 455 void *msg_data, size_t msg_bytes, void *reply_data, 492 456 size_t reply_bytes); 457 + int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, u32 header, 458 + void *msg_data, size_t msg_bytes, 459 + void *reply_data, size_t reply_bytes); 493 460 494 461 /* 495 462 * Trace/debug
+18 -7
sound/soc/sof/topology.c
··· 9 9 // 10 10 11 11 #include <linux/firmware.h> 12 + #include <linux/workqueue.h> 12 13 #include <sound/tlv.h> 13 14 #include <sound/pcm_params.h> 14 15 #include <uapi/sound/sof/tokens.h> ··· 1241 1240 { 1242 1241 struct snd_soc_card *card = scomp->card; 1243 1242 struct snd_soc_pcm_runtime *rtd; 1243 + struct snd_soc_dai *cpu_dai; 1244 + int i; 1244 1245 1245 1246 list_for_each_entry(rtd, &card->rtd_list, list) { 1246 1247 dev_vdbg(scomp->dev, "tplg: check widget: %s stream: %s dai stream: %s\n", ··· 1257 1254 1258 1255 switch (w->id) { 1259 1256 case snd_soc_dapm_dai_out: 1260 - rtd->cpu_dai->capture_widget = w; 1257 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) 1258 + cpu_dai->capture_widget = w; 1261 1259 dai->name = rtd->dai_link->name; 1262 1260 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", 1263 1261 w->name, rtd->dai_link->name); 1264 1262 break; 1265 1263 case snd_soc_dapm_dai_in: 1266 - rtd->cpu_dai->playback_widget = w; 1264 + for_each_rtd_cpu_dais(rtd, i, cpu_dai) 1265 + cpu_dai->playback_widget = w; 1267 1266 dai->name = rtd->dai_link->name; 1268 1267 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", 1269 1268 w->name, rtd->dai_link->name); ··· 2449 2444 struct snd_soc_tplg_stream_caps *caps; 2450 2445 struct snd_soc_tplg_private *private = &pcm->priv; 2451 2446 struct snd_sof_pcm *spcm; 2452 - int stream = SNDRV_PCM_STREAM_PLAYBACK; 2447 + int stream; 2453 2448 int ret = 0; 2454 2449 2455 2450 /* nothing to do for BEs atm */ ··· 2461 2456 return -ENOMEM; 2462 2457 2463 2458 spcm->scomp = scomp; 2464 - spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].comp_id = COMP_ID_UNASSIGNED; 2465 - spcm->stream[SNDRV_PCM_STREAM_CAPTURE].comp_id = COMP_ID_UNASSIGNED; 2459 + 2460 + for_each_pcm_streams(stream) { 2461 + spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED; 2462 + INIT_WORK(&spcm->stream[stream].period_elapsed_work, 2463 + snd_sof_pcm_period_elapsed_work); 2464 + } 2466 2465 2467 2466 spcm->pcm = *pcm; 2468 2467 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name); ··· 2487 2478 if (!spcm->pcm.playback) 2488 2479 goto capture; 2489 2480 2481 + stream = SNDRV_PCM_STREAM_PLAYBACK; 2482 + 2490 2483 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n", 2491 - spcm->pcm.pcm_name, spcm->stream[0].d0i3_compatible); 2484 + spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible); 2492 2485 2493 2486 caps = &spcm->pcm.caps[stream]; 2494 2487 ··· 2520 2509 return ret; 2521 2510 2522 2511 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n", 2523 - spcm->pcm.pcm_name, spcm->stream[1].d0i3_compatible); 2512 + spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible); 2524 2513 2525 2514 caps = &spcm->pcm.caps[stream]; 2526 2515
+1 -1
sound/soc/sprd/Kconfig
··· 8 8 the Spreadtrum SoCs' Audio interfaces. 9 9 10 10 config SND_SOC_SPRD_MCDT 11 - bool "Spreadtrum multi-channel data transfer support" 11 + tristate "Spreadtrum multi-channel data transfer support" 12 12 depends on SND_SOC_SPRD 13 13 help 14 14 Say y here to enable multi-channel data transfer support. It
+1 -1
sound/soc/sprd/sprd-mcdt.h
··· 48 48 struct list_head list; 49 49 }; 50 50 51 - #ifdef CONFIG_SND_SOC_SPRD_MCDT 51 + #if IS_ENABLED(CONFIG_SND_SOC_SPRD_MCDT) 52 52 struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel, 53 53 enum sprd_mcdt_channel_type type); 54 54 void sprd_mcdt_free_chan(struct sprd_mcdt_chan *chan);
+2 -2
sound/soc/sprd/sprd-pcm-compress.c
··· 135 135 struct snd_soc_component *component = 136 136 snd_soc_rtdcom_lookup(rtd, DRV_NAME); 137 137 struct device *dev = component->dev; 138 - struct sprd_compr_data *data = snd_soc_dai_get_drvdata(rtd->cpu_dai); 138 + struct sprd_compr_data *data = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 139 139 struct sprd_pcm_dma_params *dma_params = data->dma_params; 140 140 struct sprd_compr_dma *dma = &stream->dma[channel]; 141 141 struct dma_slave_config config = { }; ··· 321 321 struct snd_soc_component *component = 322 322 snd_soc_rtdcom_lookup(rtd, DRV_NAME); 323 323 struct device *dev = component->dev; 324 - struct sprd_compr_data *data = snd_soc_dai_get_drvdata(rtd->cpu_dai); 324 + struct sprd_compr_data *data = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 325 325 struct sprd_compr_stream *stream; 326 326 struct sprd_compr_callback cb; 327 327 int stream_id = cstream->direction, ret;
+1 -1
sound/soc/sprd/sprd-pcm-dma.c
··· 200 200 unsigned long flags; 201 201 int ret, i, j, sg_num; 202 202 203 - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 203 + dma_params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 204 204 if (!dma_params) { 205 205 dev_warn(component->dev, "no dma parameters setting\n"); 206 206 dma_private->params = NULL;
+6 -6
sound/soc/stm/stm32_adfsdm.c
··· 215 215 { 216 216 struct snd_soc_pcm_runtime *rtd = substream->private_data; 217 217 struct stm32_adfsdm_priv *priv = 218 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 218 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 219 219 220 220 switch (cmd) { 221 221 case SNDRV_PCM_TRIGGER_START: ··· 235 235 struct snd_pcm_substream *substream) 236 236 { 237 237 struct snd_soc_pcm_runtime *rtd = substream->private_data; 238 - struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 238 + struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 239 239 int ret; 240 240 241 241 ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw); ··· 250 250 { 251 251 struct snd_soc_pcm_runtime *rtd = substream->private_data; 252 252 struct stm32_adfsdm_priv *priv = 253 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 253 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 254 254 255 255 priv->substream = NULL; 256 256 ··· 263 263 { 264 264 struct snd_soc_pcm_runtime *rtd = substream->private_data; 265 265 struct stm32_adfsdm_priv *priv = 266 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 266 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 267 267 268 268 return bytes_to_frames(substream->runtime, priv->pos); 269 269 } ··· 274 274 { 275 275 struct snd_soc_pcm_runtime *rtd = substream->private_data; 276 276 struct stm32_adfsdm_priv *priv = 277 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 277 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 278 278 279 279 priv->pcm_buff = substream->runtime->dma_area; 280 280 ··· 287 287 { 288 288 struct snd_pcm *pcm = rtd->pcm; 289 289 struct stm32_adfsdm_priv *priv = 290 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 290 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 291 291 unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE; 292 292 293 293 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
+55 -20
sound/soc/stm/stm32_i2s.c
··· 831 831 /* Get clocks */ 832 832 i2s->pclk = devm_clk_get(&pdev->dev, "pclk"); 833 833 if (IS_ERR(i2s->pclk)) { 834 - dev_err(&pdev->dev, "Could not get pclk\n"); 834 + if (PTR_ERR(i2s->pclk) != -EPROBE_DEFER) 835 + dev_err(&pdev->dev, "Could not get pclk: %ld\n", 836 + PTR_ERR(i2s->pclk)); 835 837 return PTR_ERR(i2s->pclk); 836 838 } 837 839 838 840 i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk"); 839 841 if (IS_ERR(i2s->i2sclk)) { 840 - dev_err(&pdev->dev, "Could not get i2sclk\n"); 842 + if (PTR_ERR(i2s->i2sclk) != -EPROBE_DEFER) 843 + dev_err(&pdev->dev, "Could not get i2sclk: %ld\n", 844 + PTR_ERR(i2s->i2sclk)); 841 845 return PTR_ERR(i2s->i2sclk); 842 846 } 843 847 844 848 i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); 845 849 if (IS_ERR(i2s->x8kclk)) { 846 - dev_err(&pdev->dev, "missing x8k parent clock\n"); 850 + if (PTR_ERR(i2s->x8kclk) != -EPROBE_DEFER) 851 + dev_err(&pdev->dev, "Could not get x8k parent clock: %ld\n", 852 + PTR_ERR(i2s->x8kclk)); 847 853 return PTR_ERR(i2s->x8kclk); 848 854 } 849 855 850 856 i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); 851 857 if (IS_ERR(i2s->x11kclk)) { 852 - dev_err(&pdev->dev, "missing x11k parent clock\n"); 858 + if (PTR_ERR(i2s->x11kclk) != -EPROBE_DEFER) 859 + dev_err(&pdev->dev, "Could not get x11k parent clock: %ld\n", 860 + PTR_ERR(i2s->x11kclk)); 853 861 return PTR_ERR(i2s->x11kclk); 854 862 } 855 863 ··· 874 866 } 875 867 876 868 /* Reset */ 877 - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 878 - if (!IS_ERR(rst)) { 879 - reset_control_assert(rst); 880 - udelay(2); 881 - reset_control_deassert(rst); 869 + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); 870 + if (IS_ERR(rst)) { 871 + if (PTR_ERR(rst) != -EPROBE_DEFER) 872 + dev_err(&pdev->dev, "Reset controller error %ld\n", 873 + PTR_ERR(rst)); 874 + return PTR_ERR(rst); 882 875 } 876 + reset_control_assert(rst); 877 + udelay(2); 878 + reset_control_deassert(rst); 879 + 880 + return 0; 881 + } 882 + 883 + static int stm32_i2s_remove(struct platform_device *pdev) 884 + { 885 + snd_dmaengine_pcm_unregister(&pdev->dev); 886 + snd_soc_unregister_component(&pdev->dev); 883 887 884 888 return 0; 885 889 } ··· 923 903 i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk", 924 904 i2s->base, i2s->regmap_conf); 925 905 if (IS_ERR(i2s->regmap)) { 926 - dev_err(&pdev->dev, "regmap init failed\n"); 906 + if (PTR_ERR(i2s->regmap) != -EPROBE_DEFER) 907 + dev_err(&pdev->dev, "Regmap init error %ld\n", 908 + PTR_ERR(i2s->regmap)); 927 909 return PTR_ERR(i2s->regmap); 928 910 } 929 911 930 - ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component, 931 - i2s->dai_drv, 1); 932 - if (ret) 912 + ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0); 913 + if (ret) { 914 + if (ret != -EPROBE_DEFER) 915 + dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); 933 916 return ret; 917 + } 934 918 935 - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, 936 - &stm32_i2s_pcm_config, 0); 937 - if (ret) 919 + ret = snd_soc_register_component(&pdev->dev, &stm32_i2s_component, 920 + i2s->dai_drv, 1); 921 + if (ret) { 922 + snd_dmaengine_pcm_unregister(&pdev->dev); 938 923 return ret; 924 + } 939 925 940 926 /* Set SPI/I2S in i2s mode */ 941 927 ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, 942 928 I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD); 943 929 if (ret) 944 - return ret; 930 + goto error; 945 931 946 932 ret = regmap_read(i2s->regmap, STM32_I2S_IPIDR_REG, &val); 947 933 if (ret) 948 - return ret; 934 + goto error; 949 935 950 936 if (val == I2S_IPIDR_NUMBER) { 951 937 ret = regmap_read(i2s->regmap, STM32_I2S_HWCFGR_REG, &val); 952 938 if (ret) 953 - return ret; 939 + goto error; 954 940 955 941 if (!FIELD_GET(I2S_HWCFGR_I2S_SUPPORT_MASK, val)) { 956 942 dev_err(&pdev->dev, 957 943 "Device does not support i2s mode\n"); 958 - return -EPERM; 944 + ret = -EPERM; 945 + goto error; 959 946 } 960 947 961 948 ret = regmap_read(i2s->regmap, STM32_I2S_VERR_REG, &val); 949 + if (ret) 950 + goto error; 962 951 963 952 dev_dbg(&pdev->dev, "I2S version: %lu.%lu registered\n", 964 953 FIELD_GET(I2S_VERR_MAJ_MASK, val), 965 954 FIELD_GET(I2S_VERR_MIN_MASK, val)); 966 955 } 956 + 957 + return ret; 958 + 959 + error: 960 + stm32_i2s_remove(pdev); 967 961 968 962 return ret; 969 963 } ··· 1015 981 .pm = &stm32_i2s_pm_ops, 1016 982 }, 1017 983 .probe = stm32_i2s_probe, 984 + .remove = stm32_i2s_remove, 1018 985 }; 1019 986 1020 987 module_platform_driver(stm32_i2s_driver);
+18 -8
sound/soc/stm/stm32_sai.c
··· 174 174 if (!STM_SAI_IS_F4(sai)) { 175 175 sai->pclk = devm_clk_get(&pdev->dev, "pclk"); 176 176 if (IS_ERR(sai->pclk)) { 177 - dev_err(&pdev->dev, "missing bus clock pclk\n"); 177 + if (PTR_ERR(sai->pclk) != -EPROBE_DEFER) 178 + dev_err(&pdev->dev, "missing bus clock pclk: %ld\n", 179 + PTR_ERR(sai->pclk)); 178 180 return PTR_ERR(sai->pclk); 179 181 } 180 182 } 181 183 182 184 sai->clk_x8k = devm_clk_get(&pdev->dev, "x8k"); 183 185 if (IS_ERR(sai->clk_x8k)) { 184 - dev_err(&pdev->dev, "missing x8k parent clock\n"); 186 + if (PTR_ERR(sai->clk_x8k) != -EPROBE_DEFER) 187 + dev_err(&pdev->dev, "missing x8k parent clock: %ld\n", 188 + PTR_ERR(sai->clk_x8k)); 185 189 return PTR_ERR(sai->clk_x8k); 186 190 } 187 191 188 192 sai->clk_x11k = devm_clk_get(&pdev->dev, "x11k"); 189 193 if (IS_ERR(sai->clk_x11k)) { 190 - dev_err(&pdev->dev, "missing x11k parent clock\n"); 194 + if (PTR_ERR(sai->clk_x11k) != -EPROBE_DEFER) 195 + dev_err(&pdev->dev, "missing x11k parent clock: %ld\n", 196 + PTR_ERR(sai->clk_x11k)); 191 197 return PTR_ERR(sai->clk_x11k); 192 198 } 193 199 ··· 203 197 return sai->irq; 204 198 205 199 /* reset */ 206 - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 207 - if (!IS_ERR(rst)) { 208 - reset_control_assert(rst); 209 - udelay(2); 210 - reset_control_deassert(rst); 200 + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); 201 + if (IS_ERR(rst)) { 202 + if (PTR_ERR(rst) != -EPROBE_DEFER) 203 + dev_err(&pdev->dev, "Reset controller error %ld\n", 204 + PTR_ERR(rst)); 205 + return PTR_ERR(rst); 211 206 } 207 + reset_control_assert(rst); 208 + udelay(2); 209 + reset_control_deassert(rst); 212 210 213 211 /* Enable peripheral clock to allow register access */ 214 212 ret = clk_prepare_enable(sai->pclk);
+9 -4
sound/soc/stm/stm32_sai_sub.c
··· 1238 1238 { 1239 1239 struct snd_pcm_runtime *runtime = substream->runtime; 1240 1240 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1241 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1241 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 1242 1242 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev); 1243 1243 int *ptr = (int *)(runtime->dma_area + hwoff + 1244 1244 channel * (runtime->dma_bytes / runtime->channels)); ··· 1380 1380 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base, 1381 1381 sai->regmap_config); 1382 1382 if (IS_ERR(sai->regmap)) { 1383 - dev_err(&pdev->dev, "Failed to initialize MMIO\n"); 1383 + if (PTR_ERR(sai->regmap) != -EPROBE_DEFER) 1384 + dev_err(&pdev->dev, "Regmap init error %ld\n", 1385 + PTR_ERR(sai->regmap)); 1384 1386 return PTR_ERR(sai->regmap); 1385 1387 } 1386 1388 ··· 1473 1471 of_node_put(args.np); 1474 1472 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck"); 1475 1473 if (IS_ERR(sai->sai_ck)) { 1476 - dev_err(&pdev->dev, "Missing kernel clock sai_ck\n"); 1474 + if (PTR_ERR(sai->sai_ck) != -EPROBE_DEFER) 1475 + dev_err(&pdev->dev, "Missing kernel clock sai_ck: %ld\n", 1476 + PTR_ERR(sai->sai_ck)); 1477 1477 return PTR_ERR(sai->sai_ck); 1478 1478 } 1479 1479 ··· 1549 1545 1550 1546 ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0); 1551 1547 if (ret) { 1552 - dev_err(&pdev->dev, "Could not register pcm dma\n"); 1548 + if (ret != -EPROBE_DEFER) 1549 + dev_err(&pdev->dev, "Could not register pcm dma\n"); 1553 1550 return ret; 1554 1551 } 1555 1552
+52 -37
sound/soc/stm/stm32_spdifrx.c
··· 406 406 407 407 spdifrx->ctrl_chan = dma_request_chan(dev, "rx-ctrl"); 408 408 if (IS_ERR(spdifrx->ctrl_chan)) { 409 - dev_err(dev, "dma_request_slave_channel failed\n"); 409 + if (PTR_ERR(spdifrx->ctrl_chan) != -EPROBE_DEFER) 410 + dev_err(dev, "dma_request_slave_channel error %ld\n", 411 + PTR_ERR(spdifrx->ctrl_chan)); 410 412 return PTR_ERR(spdifrx->ctrl_chan); 411 413 } 412 414 ··· 931 929 932 930 spdifrx->kclk = devm_clk_get(&pdev->dev, "kclk"); 933 931 if (IS_ERR(spdifrx->kclk)) { 934 - dev_err(&pdev->dev, "Could not get kclk\n"); 932 + if (PTR_ERR(spdifrx->kclk) != -EPROBE_DEFER) 933 + dev_err(&pdev->dev, "Could not get kclk: %ld\n", 934 + PTR_ERR(spdifrx->kclk)); 935 935 return PTR_ERR(spdifrx->kclk); 936 936 } 937 937 938 938 spdifrx->irq = platform_get_irq(pdev, 0); 939 939 if (spdifrx->irq < 0) 940 940 return spdifrx->irq; 941 + 942 + return 0; 943 + } 944 + 945 + static int stm32_spdifrx_remove(struct platform_device *pdev) 946 + { 947 + struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); 948 + 949 + if (spdifrx->ctrl_chan) 950 + dma_release_channel(spdifrx->ctrl_chan); 951 + 952 + if (spdifrx->dmab) 953 + snd_dma_free_pages(spdifrx->dmab); 954 + 955 + snd_dmaengine_pcm_unregister(&pdev->dev); 956 + snd_soc_unregister_component(&pdev->dev); 941 957 942 958 return 0; 943 959 } ··· 987 967 spdifrx->base, 988 968 spdifrx->regmap_conf); 989 969 if (IS_ERR(spdifrx->regmap)) { 990 - dev_err(&pdev->dev, "Regmap init failed\n"); 970 + if (PTR_ERR(spdifrx->regmap) != -EPROBE_DEFER) 971 + dev_err(&pdev->dev, "Regmap init error %ld\n", 972 + PTR_ERR(spdifrx->regmap)); 991 973 return PTR_ERR(spdifrx->regmap); 992 974 } 993 975 ··· 1000 978 return ret; 1001 979 } 1002 980 1003 - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); 1004 - if (!IS_ERR(rst)) { 1005 - reset_control_assert(rst); 1006 - udelay(2); 1007 - reset_control_deassert(rst); 981 + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); 982 + if (IS_ERR(rst)) { 983 + if (PTR_ERR(rst) != -EPROBE_DEFER) 984 + dev_err(&pdev->dev, "Reset controller error %ld\n", 985 + PTR_ERR(rst)); 986 + return PTR_ERR(rst); 987 + } 988 + reset_control_assert(rst); 989 + udelay(2); 990 + reset_control_deassert(rst); 991 + 992 + pcm_config = &stm32_spdifrx_pcm_config; 993 + ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0); 994 + if (ret) { 995 + if (ret != -EPROBE_DEFER) 996 + dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); 997 + return ret; 1008 998 } 1009 999 1010 - ret = devm_snd_soc_register_component(&pdev->dev, 1011 - &stm32_spdifrx_component, 1012 - stm32_spdifrx_dai, 1013 - ARRAY_SIZE(stm32_spdifrx_dai)); 1014 - if (ret) 1000 + ret = snd_soc_register_component(&pdev->dev, 1001 + &stm32_spdifrx_component, 1002 + stm32_spdifrx_dai, 1003 + ARRAY_SIZE(stm32_spdifrx_dai)); 1004 + if (ret) { 1005 + snd_dmaengine_pcm_unregister(&pdev->dev); 1015 1006 return ret; 1007 + } 1016 1008 1017 1009 ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx); 1018 1010 if (ret) 1019 1011 goto error; 1020 - 1021 - pcm_config = &stm32_spdifrx_pcm_config; 1022 - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0); 1023 - if (ret) { 1024 - dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret); 1025 - goto error; 1026 - } 1027 1012 1028 1013 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr); 1029 1014 if (ret) ··· 1038 1009 1039 1010 if (idr == SPDIFRX_IPIDR_NUMBER) { 1040 1011 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver); 1012 + if (ret) 1013 + goto error; 1041 1014 1042 1015 dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n", 1043 1016 FIELD_GET(SPDIFRX_VERR_MAJ_MASK, ver), ··· 1049 1018 return ret; 1050 1019 1051 1020 error: 1052 - if (!IS_ERR(spdifrx->ctrl_chan)) 1053 - dma_release_channel(spdifrx->ctrl_chan); 1054 - if (spdifrx->dmab) 1055 - snd_dma_free_pages(spdifrx->dmab); 1021 + stm32_spdifrx_remove(pdev); 1056 1022 1057 1023 return ret; 1058 - } 1059 - 1060 - static int stm32_spdifrx_remove(struct platform_device *pdev) 1061 - { 1062 - struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); 1063 - 1064 - if (spdifrx->ctrl_chan) 1065 - dma_release_channel(spdifrx->ctrl_chan); 1066 - 1067 - if (spdifrx->dmab) 1068 - snd_dma_free_pages(spdifrx->dmab); 1069 - 1070 - return 0; 1071 1024 } 1072 1025 1073 1026 MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);
+1 -1
sound/soc/sunxi/sun4i-spdif.c
··· 244 244 struct snd_soc_dai *cpu_dai) 245 245 { 246 246 struct snd_soc_pcm_runtime *rtd = substream->private_data; 247 - struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(rtd->cpu_dai); 247 + struct sun4i_spdif_dev *host = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 248 248 249 249 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 250 250 return -EINVAL;
-3
sound/soc/sunxi/sun8i-codec.c
··· 86 86 #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9) 87 87 88 88 struct sun8i_codec { 89 - struct device *dev; 90 89 struct regmap *regmap; 91 90 struct clk *clk_module; 92 91 struct clk *clk_bus; ··· 540 541 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL); 541 542 if (!scodec) 542 543 return -ENOMEM; 543 - 544 - scodec->dev = &pdev->dev; 545 544 546 545 scodec->clk_module = devm_clk_get(&pdev->dev, "mod"); 547 546 if (IS_ERR(scodec->clk_module)) {
+1 -1
sound/soc/tegra/tegra_alc5632.c
··· 37 37 struct snd_pcm_hw_params *params) 38 38 { 39 39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 40 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 41 41 struct snd_soc_card *card = rtd->card; 42 42 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 43 43 int srate, mclk;
+1 -1
sound/soc/tegra/tegra_max98090.c
··· 38 38 struct snd_pcm_hw_params *params) 39 39 { 40 40 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 41 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 42 42 struct snd_soc_card *card = rtd->card; 43 43 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); 44 44 int srate, mclk;
+1 -1
sound/soc/tegra/tegra_rt5640.c
··· 40 40 struct snd_pcm_hw_params *params) 41 41 { 42 42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 43 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 43 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 44 44 struct snd_soc_card *card = rtd->card; 45 45 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card); 46 46 int srate, mclk;
+1 -1
sound/soc/tegra/tegra_rt5677.c
··· 42 42 struct snd_pcm_hw_params *params) 43 43 { 44 44 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 45 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 46 46 struct snd_soc_card *card = rtd->card; 47 47 struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); 48 48 int srate, mclk, err;
+1 -1
sound/soc/tegra/tegra_sgtl5000.c
··· 36 36 struct snd_pcm_hw_params *params) 37 37 { 38 38 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 39 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 40 40 struct snd_soc_card *card = rtd->card; 41 41 struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card); 42 42 int srate, mclk;
+1 -1
sound/soc/tegra/tegra_wm8753.c
··· 40 40 struct snd_pcm_hw_params *params) 41 41 { 42 42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 43 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 43 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 44 44 struct snd_soc_card *card = rtd->card; 45 45 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); 46 46 int srate, mclk;
+21 -3
sound/soc/tegra/tegra_wm8903.c
··· 45 45 struct snd_pcm_hw_params *params) 46 46 { 47 47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 48 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 49 49 struct snd_soc_card *card = rtd->card; 50 50 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 51 51 int srate, mclk; ··· 143 143 return 0; 144 144 } 145 145 146 + static int tegra_wm8903_event_int_mic(struct snd_soc_dapm_widget *w, 147 + struct snd_kcontrol *k, int event) 148 + { 149 + struct snd_soc_dapm_context *dapm = w->dapm; 150 + struct snd_soc_card *card = dapm->card; 151 + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 152 + 153 + if (!gpio_is_valid(machine->gpio_int_mic_en)) 154 + return 0; 155 + 156 + gpio_set_value_cansleep(machine->gpio_int_mic_en, 157 + SND_SOC_DAPM_EVENT_ON(event)); 158 + 159 + return 0; 160 + } 161 + 146 162 static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { 147 163 SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk), 148 164 SND_SOC_DAPM_HP("Headphone Jack", tegra_wm8903_event_hp), 149 165 SND_SOC_DAPM_MIC("Mic Jack", NULL), 166 + SND_SOC_DAPM_MIC("Int Mic", tegra_wm8903_event_int_mic), 150 167 }; 151 168 152 169 static const struct snd_kcontrol_new tegra_wm8903_controls[] = { 153 170 SOC_DAPM_PIN_SWITCH("Int Spk"), 171 + SOC_DAPM_PIN_SWITCH("Int Mic"), 154 172 }; 155 173 156 174 static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) 157 175 { 158 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 176 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 159 177 struct snd_soc_component *component = codec_dai->component; 160 178 struct snd_soc_card *card = rtd->card; 161 179 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); ··· 205 187 { 206 188 struct snd_soc_pcm_runtime *rtd = 207 189 snd_soc_get_pcm_runtime(card, &card->dai_link[0]); 208 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 190 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 209 191 struct snd_soc_component *component = codec_dai->component; 210 192 211 193 wm8903_mic_detect(component, NULL, 0, 0);
+1 -1
sound/soc/tegra/trimslice.c
··· 35 35 struct snd_pcm_hw_params *params) 36 36 { 37 37 struct snd_soc_pcm_runtime *rtd = substream->private_data; 38 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 38 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 39 39 struct snd_soc_card *card = rtd->card; 40 40 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); 41 41 int srate, mclk;
+7 -1
sound/soc/ti/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 menu "Audio support for Texas Instruments SoCs" 3 - depends on DMA_OMAP || TI_EDMA || COMPILE_TEST 3 + depends on DMA_OMAP || TI_EDMA || TI_K3_UDMA || COMPILE_TEST 4 4 5 5 config SND_SOC_TI_EDMA_PCM 6 6 tristate 7 7 select SND_SOC_GENERIC_DMAENGINE_PCM 8 8 9 9 config SND_SOC_TI_SDMA_PCM 10 + tristate 11 + select SND_SOC_GENERIC_DMAENGINE_PCM 12 + 13 + config SND_SOC_TI_UDMA_PCM 10 14 tristate 11 15 select SND_SOC_GENERIC_DMAENGINE_PCM 12 16 ··· 28 24 tristate "Multichannel Audio Serial Port (McASP) support" 29 25 select SND_SOC_TI_EDMA_PCM 30 26 select SND_SOC_TI_SDMA_PCM 27 + select SND_SOC_TI_UDMA_PCM 31 28 help 32 29 Say Y or M here if you want to have support for McASP IP found in 33 30 various Texas Instruments SoCs like: ··· 36 31 - Sitara line of SoCs (AM335x, AM438x, etc) 37 32 - DRA7x devices 38 33 - Keystone devices 34 + - K3 devices (am654, j721e) 39 35 40 36 config SND_SOC_DAVINCI_VCIF 41 37 tristate "daVinci Voice Interface (VCIF) support"
+2
sound/soc/ti/Makefile
··· 3 3 # Platform drivers 4 4 snd-soc-ti-edma-objs := edma-pcm.o 5 5 snd-soc-ti-sdma-objs := sdma-pcm.o 6 + snd-soc-ti-udma-objs := udma-pcm.o 6 7 7 8 obj-$(CONFIG_SND_SOC_TI_EDMA_PCM) += snd-soc-ti-edma.o 8 9 obj-$(CONFIG_SND_SOC_TI_SDMA_PCM) += snd-soc-ti-sdma.o 10 + obj-$(CONFIG_SND_SOC_TI_UDMA_PCM) += snd-soc-ti-udma.o 9 11 10 12 # CPU DAI drivers 11 13 snd-soc-davinci-asp-objs := davinci-i2s.o
+2 -2
sound/soc/ti/ams-delta.c
··· 460 460 461 461 static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) 462 462 { 463 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 463 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 464 464 struct snd_soc_card *card = rtd->card; 465 465 struct snd_soc_dapm_context *dapm = &card->dapm; 466 466 int ret; 467 467 /* Codec is ready, now add/activate board specific controls */ 468 468 469 469 /* Store a pointer to the codec structure for tty ldisc use */ 470 - cx20442_codec = rtd->codec_dai->component; 470 + cx20442_codec = asoc_rtd_to_codec(rtd, 0)->component; 471 471 472 472 /* Add hook switch - can be used to control the codec from userspace 473 473 * even if line discipline fails */
+2 -2
sound/soc/ti/davinci-evm.c
··· 54 54 struct snd_pcm_hw_params *params) 55 55 { 56 56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 57 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 58 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 57 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 58 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 59 59 struct snd_soc_card *soc_card = rtd->card; 60 60 int ret = 0; 61 61 unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
+9 -4
sound/soc/ti/davinci-mcasp.c
··· 38 38 39 39 #include "edma-pcm.h" 40 40 #include "sdma-pcm.h" 41 + #include "udma-pcm.h" 41 42 #include "davinci-mcasp.h" 42 43 43 44 #define MCASP_MAX_AFIFO_DEPTH 64 ··· 1765 1764 } else if (match) { 1766 1765 pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata), 1767 1766 GFP_KERNEL); 1768 - if (!pdata) { 1769 - ret = -ENOMEM; 1770 - return pdata; 1771 - } 1767 + if (!pdata) 1768 + return NULL; 1772 1769 } else { 1773 1770 /* control shouldn't reach here. something is wrong */ 1774 1771 ret = -EINVAL; ··· 1874 1875 enum { 1875 1876 PCM_EDMA, 1876 1877 PCM_SDMA, 1878 + PCM_UDMA, 1877 1879 }; 1878 1880 static const char *sdma_prefix = "ti,omap"; 1879 1881 ··· 1912 1912 dev_dbg(mcasp->dev, "DMA controller compatible = \"%s\"\n", tmp); 1913 1913 if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix))) 1914 1914 return PCM_SDMA; 1915 + else if (strstr(tmp, "udmap")) 1916 + return PCM_UDMA; 1915 1917 1916 1918 return PCM_EDMA; 1917 1919 } ··· 2372 2370 break; 2373 2371 case PCM_SDMA: 2374 2372 ret = sdma_pcm_platform_register(&pdev->dev, "tx", "rx"); 2373 + break; 2374 + case PCM_UDMA: 2375 + ret = udma_pcm_platform_register(&pdev->dev); 2375 2376 break; 2376 2377 default: 2377 2378 dev_err(&pdev->dev, "No DMA controller found (%d)\n", ret);
+2 -2
sound/soc/ti/davinci-vcif.c
··· 43 43 { 44 44 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 45 struct davinci_vcif_dev *davinci_vcif_dev = 46 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 46 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 47 47 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 48 48 u32 w; 49 49 ··· 62 62 { 63 63 struct snd_soc_pcm_runtime *rtd = substream->private_data; 64 64 struct davinci_vcif_dev *davinci_vcif_dev = 65 - snd_soc_dai_get_drvdata(rtd->cpu_dai); 65 + snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 66 66 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 67 67 u32 w; 68 68
+1 -1
sound/soc/ti/n810.c
··· 101 101 struct snd_pcm_hw_params *params) 102 102 { 103 103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 104 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 104 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 105 105 int err; 106 106 107 107 /* Set the codec system clock for DAC and ADC */
+3 -3
sound/soc/ti/omap-abe-twl6040.c
··· 46 46 struct snd_pcm_hw_params *params) 47 47 { 48 48 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 49 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 50 50 struct snd_soc_card *card = rtd->card; 51 51 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); 52 52 int clk_id, freq; ··· 78 78 struct snd_pcm_hw_params *params) 79 79 { 80 80 struct snd_soc_pcm_runtime *rtd = substream->private_data; 81 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 81 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 82 82 int ret = 0; 83 83 84 84 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, ··· 166 166 167 167 static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) 168 168 { 169 - struct snd_soc_component *component = rtd->codec_dai->component; 169 + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; 170 170 struct snd_soc_card *card = rtd->card; 171 171 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); 172 172 int hs_trim;
+1 -1
sound/soc/ti/omap-mcbsp-st.c
··· 489 489 490 490 int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id) 491 491 { 492 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 492 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 493 493 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 494 494 495 495 if (!mcbsp->st_data) {
+2 -2
sound/soc/ti/omap-mcbsp.c
··· 737 737 unsigned int packet_size) 738 738 { 739 739 struct snd_soc_pcm_runtime *rtd = substream->private_data; 740 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 740 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 741 741 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 742 742 int words; 743 743 ··· 902 902 struct snd_soc_dai *dai) 903 903 { 904 904 struct snd_soc_pcm_runtime *rtd = substream->private_data; 905 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 905 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 906 906 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 907 907 u16 fifo_use; 908 908 snd_pcm_sframes_t delay;
+1 -1
sound/soc/ti/omap-mcpdm.c
··· 532 532 void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, 533 533 u8 rx1, u8 rx2) 534 534 { 535 - struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai); 535 + struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); 536 536 537 537 mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2); 538 538 }
+2 -2
sound/soc/ti/omap3pandora.c
··· 32 32 struct snd_pcm_hw_params *params) 33 33 { 34 34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 35 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 36 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 35 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 36 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 37 37 int ret; 38 38 39 39 /* Set the codec system clock for DAC and ADC */
+1 -1
sound/soc/ti/osk5912.c
··· 39 39 struct snd_pcm_hw_params *params) 40 40 { 41 41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 42 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 43 43 int err; 44 44 45 45 /* Set the codec system clock for DAC and ADC */
+1 -1
sound/soc/ti/rx51.c
··· 103 103 struct snd_pcm_hw_params *params) 104 104 { 105 105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 106 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 106 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 107 107 108 108 /* Set the codec system clock for DAC and ADC */ 109 109 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
+43
sound/soc/ti/udma-pcm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com 4 + * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> 5 + */ 6 + 7 + #include <linux/module.h> 8 + #include <sound/core.h> 9 + #include <sound/pcm.h> 10 + #include <sound/pcm_params.h> 11 + #include <sound/soc.h> 12 + #include <sound/dmaengine_pcm.h> 13 + 14 + #include "udma-pcm.h" 15 + 16 + static const struct snd_pcm_hardware udma_pcm_hardware = { 17 + .info = SNDRV_PCM_INFO_MMAP | 18 + SNDRV_PCM_INFO_MMAP_VALID | 19 + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 20 + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | 21 + SNDRV_PCM_INFO_INTERLEAVED, 22 + .buffer_bytes_max = SIZE_MAX, 23 + .period_bytes_min = 32, 24 + .period_bytes_max = SZ_64K, 25 + .periods_min = 2, 26 + .periods_max = UINT_MAX, 27 + }; 28 + 29 + static const struct snd_dmaengine_pcm_config udma_dmaengine_pcm_config = { 30 + .pcm_hardware = &udma_pcm_hardware, 31 + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 32 + }; 33 + 34 + int udma_pcm_platform_register(struct device *dev) 35 + { 36 + return devm_snd_dmaengine_pcm_register(dev, &udma_dmaengine_pcm_config, 37 + 0); 38 + } 39 + EXPORT_SYMBOL_GPL(udma_pcm_platform_register); 40 + 41 + MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 42 + MODULE_DESCRIPTION("UDMA PCM ASoC platform driver"); 43 + MODULE_LICENSE("GPL v2");
+18
sound/soc/ti/udma-pcm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com 4 + */ 5 + 6 + #ifndef __UDMA_PCM_H__ 7 + #define __UDMA_PCM_H__ 8 + 9 + #if IS_ENABLED(CONFIG_SND_SOC_TI_UDMA_PCM) 10 + int udma_pcm_platform_register(struct device *dev); 11 + #else 12 + static inline int udma_pcm_platform_register(struct device *dev) 13 + { 14 + return 0; 15 + } 16 + #endif /* CONFIG_SND_SOC_TI_UDMA_PCM */ 17 + 18 + #endif /* __UDMA_PCM_H__ */
+1 -1
sound/soc/txx9/txx9aclc.c
··· 269 269 struct snd_soc_pcm_runtime *rtd) 270 270 { 271 271 struct snd_card *card = rtd->card->snd_card; 272 - struct snd_soc_dai *dai = rtd->cpu_dai; 272 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 273 273 struct snd_pcm *pcm = rtd->pcm; 274 274 struct platform_device *pdev = to_platform_device(component->dev); 275 275 struct txx9aclc_soc_device *dev;
+11 -11
sound/soc/uniphier/aio-compress.c
··· 23 23 { 24 24 struct snd_compr *compr = rtd->compr; 25 25 struct device *dev = compr->card->dev; 26 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 26 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 27 27 struct uniphier_aio_sub *sub = &aio->sub[compr->direction]; 28 28 size_t size = AUD_RING_SIZE; 29 29 int dma_dir = DMA_FROM_DEVICE, ret; ··· 56 56 { 57 57 struct snd_compr *compr = rtd->compr; 58 58 struct device *dev = compr->card->dev; 59 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 59 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 60 60 struct uniphier_aio_sub *sub = &aio->sub[compr->direction]; 61 61 int dma_dir = DMA_FROM_DEVICE; 62 62 ··· 73 73 static int uniphier_aio_compr_open(struct snd_compr_stream *cstream) 74 74 { 75 75 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 76 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 76 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 77 77 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 78 78 int ret; 79 79 ··· 98 98 static int uniphier_aio_compr_free(struct snd_compr_stream *cstream) 99 99 { 100 100 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 101 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 101 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 102 102 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 103 103 int ret; 104 104 ··· 118 118 struct snd_codec *params) 119 119 { 120 120 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 121 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 121 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 122 122 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 123 123 124 124 *params = sub->cparams.codec; ··· 130 130 struct snd_compr_params *params) 131 131 { 132 132 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 133 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 133 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 134 134 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 135 135 struct device *dev = &aio->chip->pdev->dev; 136 136 int ret; ··· 165 165 static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream) 166 166 { 167 167 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 168 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 168 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 169 169 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 170 170 171 171 sub->setting = 0; ··· 177 177 { 178 178 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 179 179 struct snd_compr_runtime *runtime = cstream->runtime; 180 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 180 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 181 181 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 182 182 int bytes = runtime->fragment_size; 183 183 unsigned long flags; ··· 215 215 { 216 216 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 217 217 struct snd_compr_runtime *runtime = cstream->runtime; 218 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 218 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 219 219 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 220 220 struct device *dev = &aio->chip->pdev->dev; 221 221 int bytes = runtime->fragment_size, ret = 0; ··· 248 248 { 249 249 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 250 250 struct snd_compr_runtime *runtime = cstream->runtime; 251 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 251 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 252 252 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 253 253 int bytes = runtime->fragment_size; 254 254 unsigned long flags; ··· 322 322 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 323 323 struct snd_compr_runtime *runtime = cstream->runtime; 324 324 struct device *carddev = rtd->compr->card->dev; 325 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 325 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 326 326 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 327 327 size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2); 328 328 int bytes = runtime->fragment_size;
+3 -3
sound/soc/uniphier/aio-dma.c
··· 109 109 { 110 110 struct snd_pcm_runtime *runtime = substream->runtime; 111 111 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 112 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 112 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 113 113 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 114 114 int bytes = runtime->period_size * 115 115 runtime->channels * samples_to_bytes(runtime, 1); ··· 136 136 { 137 137 struct snd_pcm_runtime *runtime = substream->runtime; 138 138 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 139 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 139 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 140 140 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 141 141 struct device *dev = &aio->chip->pdev->dev; 142 142 int bytes = runtime->period_size * ··· 172 172 { 173 173 struct snd_pcm_runtime *runtime = substream->runtime; 174 174 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 175 - struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai); 175 + struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 176 176 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 177 177 int bytes = runtime->period_size * 178 178 runtime->channels * samples_to_bytes(runtime, 1);
+3 -3
sound/soc/ux500/mop500_ab8500.c
··· 215 215 struct snd_pcm_hw_params *params) 216 216 { 217 217 struct snd_soc_pcm_runtime *rtd = substream->private_data; 218 - struct snd_soc_dai *codec_dai = rtd->codec_dai; 219 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 218 + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); 219 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 220 220 struct device *dev = rtd->card->dev; 221 221 unsigned int fmt; 222 222 int channels, ret = 0, driver_mode, slots; ··· 339 339 static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream) 340 340 { 341 341 struct snd_soc_pcm_runtime *rtd = substream->private_data; 342 - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 342 + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); 343 343 344 344 mutex_lock(&mop500_ab8500_params_lock); 345 345 __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
+4 -4
sound/soc/ux500/ux500_pcm.c
··· 46 46 static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, 47 47 struct snd_pcm_substream *substream) 48 48 { 49 - struct snd_soc_dai *dai = rtd->cpu_dai; 49 + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); 50 50 u16 per_data_width, mem_data_width; 51 51 struct stedma40_chan_cfg *dma_cfg; 52 52 struct ux500_msp_dma_params *dma_params; ··· 86 86 struct dma_slave_config *slave_config) 87 87 { 88 88 struct snd_soc_pcm_runtime *rtd = substream->private_data; 89 - struct msp_i2s_platform_data *pdata = rtd->cpu_dai->dev->platform_data; 89 + struct msp_i2s_platform_data *pdata = asoc_rtd_to_cpu(rtd, 0)->dev->platform_data; 90 90 struct snd_dmaengine_dai_dma_data *snd_dma_params; 91 91 struct ux500_msp_dma_params *ste_dma_params; 92 92 dma_addr_t dma_addr; ··· 94 94 95 95 if (pdata) { 96 96 ste_dma_params = 97 - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 97 + snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 98 98 dma_addr = ste_dma_params->tx_rx_addr; 99 99 } else { 100 100 snd_dma_params = 101 - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 101 + snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 102 102 dma_addr = snd_dma_params->addr; 103 103 } 104 104
+1 -1
sound/soc/xtensa/xtfpga-i2s.c
··· 373 373 void *p; 374 374 375 375 snd_soc_set_runtime_hwparams(substream, &xtfpga_pcm_hardware); 376 - p = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 376 + p = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); 377 377 runtime->private_data = p; 378 378 379 379 return 0;
-1
sound/soc/zte/zx-spdif.c
··· 322 322 zx_spdif->mapbase = res->start; 323 323 zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res); 324 324 if (IS_ERR(zx_spdif->reg_base)) { 325 - dev_err(&pdev->dev, "ioremap failed!\n"); 326 325 return PTR_ERR(zx_spdif->reg_base); 327 326 } 328 327
+1 -2
sound/soc/zte/zx-tdm.c
··· 371 371 372 372 static int zx_tdm_probe(struct platform_device *pdev) 373 373 { 374 - struct device *dev = &pdev->dev; 375 374 struct of_phandle_args out_args; 376 375 unsigned int dma_reg_offset; 377 376 struct zx_tdm_info *zx_tdm; ··· 383 384 if (!zx_tdm) 384 385 return -ENOMEM; 385 386 386 - zx_tdm->dev = dev; 387 + zx_tdm->dev = &pdev->dev; 387 388 388 389 zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk"); 389 390 if (IS_ERR(zx_tdm->dai_wclk)) {
+1
sound/usb/Makefile
··· 13 13 mixer_scarlett.o \ 14 14 mixer_scarlett_gen2.o \ 15 15 mixer_us16x08.o \ 16 + mixer_s1810c.o \ 16 17 pcm.o \ 17 18 power.o \ 18 19 proc.o \
+34 -4
sound/usb/card.c
··· 72 72 static bool ignore_ctl_error; 73 73 static bool autoclock = true; 74 74 static char *quirk_alias[SNDRV_CARDS]; 75 + static char *delayed_register[SNDRV_CARDS]; 75 76 76 77 bool snd_usb_use_vmalloc = true; 77 78 bool snd_usb_skip_validation; ··· 96 95 MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); 97 96 module_param_array(quirk_alias, charp, NULL, 0444); 98 97 MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); 98 + module_param_array(delayed_register, charp, NULL, 0444); 99 + MODULE_PARM_DESC(delayed_register, "Quirk for delayed registration, given by id:iface, e.g. 0123abcd:4."); 99 100 module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444); 100 101 MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes)."); 101 102 module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444); ··· 528 525 return false; 529 526 } 530 527 528 + static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface) 529 + { 530 + int i; 531 + unsigned int id, inum; 532 + 533 + for (i = 0; i < ARRAY_SIZE(delayed_register); i++) { 534 + if (delayed_register[i] && 535 + sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 && 536 + id == chip->usb_id) 537 + return inum != iface; 538 + } 539 + 540 + return false; 541 + } 542 + 531 543 static const struct usb_device_id usb_audio_ids[]; /* defined below */ 532 544 533 545 /* look for the corresponding quirk */ ··· 680 662 goto __error; 681 663 } 682 664 683 - /* we are allowed to call snd_card_register() many times */ 684 - err = snd_card_register(chip->card); 685 - if (err < 0) 686 - goto __error; 665 + if (chip->need_delayed_register) { 666 + dev_info(&dev->dev, 667 + "Found post-registration device assignment: %08x:%02x\n", 668 + chip->usb_id, ifnum); 669 + chip->need_delayed_register = false; /* clear again */ 670 + } 671 + 672 + /* we are allowed to call snd_card_register() many times, but first 673 + * check to see if a device needs to skip it or do anything special 674 + */ 675 + if (!snd_usb_registration_quirk(chip, ifnum) && 676 + !check_delayed_register_option(chip, ifnum)) { 677 + err = snd_card_register(chip->card); 678 + if (err < 0) 679 + goto __error; 680 + } 687 681 688 682 if (quirk && quirk->shares_media_device) { 689 683 /* don't want to fail when snd_media_device_create() fails */
+48 -11
sound/usb/clock.c
··· 151 151 return ret; 152 152 } 153 153 154 - /* 155 - * Assume the clock is valid if clock source supports only one single sample 156 - * rate, the terminal is connected directly to it (there is no clock selector) 157 - * and clock type is internal. This is to deal with some Denon DJ controllers 158 - * that always reports that clock is invalid. 159 - */ 160 154 static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip, 161 155 struct audioformat *fmt, 162 156 int source_id) 163 157 { 158 + bool ret = false; 159 + int count; 160 + unsigned char data; 161 + struct usb_device *dev = chip->dev; 162 + 164 163 if (fmt->protocol == UAC_VERSION_2) { 165 164 struct uac_clock_source_descriptor *cs_desc = 166 165 snd_usb_find_clock_source(chip->ctrl_intf, source_id); ··· 167 168 if (!cs_desc) 168 169 return false; 169 170 170 - return (fmt->nr_rates == 1 && 171 - (fmt->clock & 0xff) == cs_desc->bClockID && 172 - (cs_desc->bmAttributes & 0x3) != 173 - UAC_CLOCK_SOURCE_TYPE_EXT); 171 + /* 172 + * Assume the clock is valid if clock source supports only one 173 + * single sample rate, the terminal is connected directly to it 174 + * (there is no clock selector) and clock type is internal. 175 + * This is to deal with some Denon DJ controllers that always 176 + * reports that clock is invalid. 177 + */ 178 + if (fmt->nr_rates == 1 && 179 + (fmt->clock & 0xff) == cs_desc->bClockID && 180 + (cs_desc->bmAttributes & 0x3) != 181 + UAC_CLOCK_SOURCE_TYPE_EXT) 182 + return true; 174 183 } 175 184 176 - return false; 185 + /* 186 + * MOTU MicroBook IIc 187 + * Sample rate changes takes more than 2 seconds for this device. Clock 188 + * validity request returns false during that period. 189 + */ 190 + if (chip->usb_id == USB_ID(0x07fd, 0x0004)) { 191 + count = 0; 192 + 193 + while ((!ret) && (count < 50)) { 194 + int err; 195 + 196 + msleep(100); 197 + 198 + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 199 + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 200 + UAC2_CS_CONTROL_CLOCK_VALID << 8, 201 + snd_usb_ctrl_intf(chip) | (source_id << 8), 202 + &data, sizeof(data)); 203 + if (err < 0) { 204 + dev_warn(&dev->dev, 205 + "%s(): cannot get clock validity for id %d\n", 206 + __func__, source_id); 207 + return false; 208 + } 209 + 210 + ret = !!data; 211 + count++; 212 + } 213 + } 214 + 215 + return ret; 177 216 } 178 217 179 218 static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
+37
sound/usb/format.c
··· 247 247 return 0; 248 248 } 249 249 250 + 251 + /* 252 + * Presonus Studio 1810c supports a limited set of sampling 253 + * rates per altsetting but reports the full set each time. 254 + * If we don't filter out the unsupported rates and attempt 255 + * to configure the card, it will hang refusing to do any 256 + * further audio I/O until a hard reset is performed. 257 + * 258 + * The list of supported rates per altsetting (set of available 259 + * I/O channels) is described in the owner's manual, section 2.2. 260 + */ 261 + static bool s1810c_valid_sample_rate(struct audioformat *fp, 262 + unsigned int rate) 263 + { 264 + switch (fp->altsetting) { 265 + case 1: 266 + /* All ADAT ports available */ 267 + return rate <= 48000; 268 + case 2: 269 + /* Half of ADAT ports available */ 270 + return (rate == 88200 || rate == 96000); 271 + case 3: 272 + /* Analog I/O only (no S/PDIF nor ADAT) */ 273 + return rate >= 176400; 274 + default: 275 + return false; 276 + } 277 + return false; 278 + } 279 + 250 280 /* 251 281 * Helper function to walk the array of sample rate triplets reported by 252 282 * the device. The problem is that we need to parse whole array first to ··· 313 283 } 314 284 315 285 for (rate = min; rate <= max; rate += res) { 286 + 287 + /* Filter out invalid rates on Presonus Studio 1810c */ 288 + if (chip->usb_id == USB_ID(0x0194f, 0x010c) && 289 + !s1810c_valid_sample_rate(fp, rate)) 290 + goto skip_rate; 291 + 316 292 if (fp->rate_table) 317 293 fp->rate_table[nr_rates] = rate; 318 294 if (!fp->rate_min || rate < fp->rate_min) ··· 333 297 break; 334 298 } 335 299 300 + skip_rate: 336 301 /* avoid endless loop */ 337 302 if (res == 0) 338 303 break;
+25 -6
sound/usb/midi.c
··· 91 91 __u8 bDescriptorType; 92 92 __u8 bDescriptorSubtype; 93 93 __u8 bNumEmbMIDIJack; 94 - __u8 baAssocJackID[0]; 94 + __u8 baAssocJackID[]; 95 95 } __attribute__ ((packed)); 96 96 97 97 struct snd_usb_midi_in_endpoint; ··· 1826 1826 return 0; 1827 1827 } 1828 1828 1829 + static struct usb_ms_endpoint_descriptor *find_usb_ms_endpoint_descriptor( 1830 + struct usb_host_endpoint *hostep) 1831 + { 1832 + unsigned char *extra = hostep->extra; 1833 + int extralen = hostep->extralen; 1834 + 1835 + while (extralen > 3) { 1836 + struct usb_ms_endpoint_descriptor *ms_ep = 1837 + (struct usb_ms_endpoint_descriptor *)extra; 1838 + 1839 + if (ms_ep->bLength > 3 && 1840 + ms_ep->bDescriptorType == USB_DT_CS_ENDPOINT && 1841 + ms_ep->bDescriptorSubtype == UAC_MS_GENERAL) 1842 + return ms_ep; 1843 + if (!extra[0]) 1844 + break; 1845 + extralen -= extra[0]; 1846 + extra += extra[0]; 1847 + } 1848 + return NULL; 1849 + } 1850 + 1829 1851 /* 1830 1852 * Returns MIDIStreaming device capabilities. 1831 1853 */ ··· 1885 1863 ep = get_ep_desc(hostep); 1886 1864 if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep)) 1887 1865 continue; 1888 - ms_ep = (struct usb_ms_endpoint_descriptor *)hostep->extra; 1889 - if (hostep->extralen < 4 || 1890 - ms_ep->bLength < 4 || 1891 - ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || 1892 - ms_ep->bDescriptorSubtype != UAC_MS_GENERAL) 1866 + ms_ep = find_usb_ms_endpoint_descriptor(hostep); 1867 + if (!ms_ep) 1893 1868 continue; 1894 1869 if (usb_endpoint_dir_out(ep)) { 1895 1870 if (endpoints[epidx].out_ep) {
+27 -6
sound/usb/mixer.c
··· 292 292 * retrieve a mixer value 293 293 */ 294 294 295 + static inline int mixer_ctrl_intf(struct usb_mixer_interface *mixer) 296 + { 297 + return get_iface_desc(mixer->hostif)->bInterfaceNumber; 298 + } 299 + 295 300 static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, 296 301 int validx, int *value_ret) 297 302 { ··· 311 306 return -EIO; 312 307 313 308 while (timeout-- > 0) { 314 - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 309 + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); 315 310 err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 316 311 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 317 312 validx, idx, buf, val_len); ··· 359 354 if (ret) 360 355 goto error; 361 356 362 - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 357 + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); 363 358 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, 364 359 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 365 360 validx, idx, buf, size); ··· 484 479 return -EIO; 485 480 486 481 while (timeout-- > 0) { 487 - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 482 + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); 488 483 err = snd_usb_ctl_msg(chip->dev, 489 484 usb_sndctrlpipe(chip->dev, 0), request, 490 485 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, ··· 906 901 struct usb_audio_term *term, 907 902 void *p1, int id) 908 903 { 904 + struct uac2_effect_unit_descriptor *d = p1; 905 + int err; 906 + 907 + err = __check_input_term(state, d->bSourceID, term); 908 + if (err < 0) 909 + return err; 909 910 term->type = UAC3_EFFECT_UNIT << 16; /* virtual type */ 910 911 term->id = id; 911 912 return 0; ··· 1214 1203 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { 1215 1204 usb_audio_err(cval->head.mixer->chip, 1216 1205 "%d:%d: cannot get min/max values for control %d (id %d)\n", 1217 - cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip), 1206 + cval->head.id, mixer_ctrl_intf(cval->head.mixer), 1218 1207 cval->control, cval->head.id); 1219 1208 return -EINVAL; 1220 1209 } ··· 1433 1422 if (ret) 1434 1423 goto error; 1435 1424 1436 - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 1425 + idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8); 1437 1426 if (cval->head.mixer->protocol == UAC_VERSION_2) { 1438 1427 struct uac2_connectors_ctl_blk uac2_conn; 1439 1428 ··· 1684 1673 1685 1674 /* get min/max values */ 1686 1675 get_min_max_with_quirks(cval, 0, kctl); 1676 + 1677 + /* skip a bogus volume range */ 1678 + if (cval->max <= cval->min) { 1679 + usb_audio_dbg(mixer->chip, 1680 + "[%d] FU [%s] skipped due to invalid volume\n", 1681 + cval->head.id, kctl->id.name); 1682 + snd_ctl_free_one(kctl); 1683 + return; 1684 + } 1685 + 1687 1686 1688 1687 if (control == UAC_FU_VOLUME) { 1689 1688 check_mapped_dB(map, cval); ··· 3224 3203 list_for_each_entry(mixer, &chip->mixer_list, list) { 3225 3204 snd_iprintf(buffer, 3226 3205 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n", 3227 - chip->usb_id, snd_usb_ctrl_intf(chip), 3206 + chip->usb_id, mixer_ctrl_intf(mixer), 3228 3207 mixer->ignore_ctl_error); 3229 3208 snd_iprintf(buffer, "Card: %s\n", chip->card->longname); 3230 3209 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
+5
sound/usb/mixer_quirks.c
··· 34 34 #include "mixer_scarlett.h" 35 35 #include "mixer_scarlett_gen2.h" 36 36 #include "mixer_us16x08.h" 37 + #include "mixer_s1810c.h" 37 38 #include "helper.h" 38 39 39 40 struct std_mono_table { ··· 2277 2276 case USB_ID(0x2a39, 0x3fd3): /* RME ADI-2 DAC */ 2278 2277 case USB_ID(0x2a39, 0x3fd4): /* RME */ 2279 2278 err = snd_rme_controls_create(mixer); 2279 + break; 2280 + 2281 + case USB_ID(0x0194f, 0x010c): /* Presonus Studio 1810c */ 2282 + err = snd_sc1810_init_mixer(mixer); 2280 2283 break; 2281 2284 } 2282 2285
+595
sound/usb/mixer_s1810c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Presonus Studio 1810c driver for ALSA 4 + * Copyright (C) 2019 Nick Kossifidis <mickflemm@gmail.com> 5 + * 6 + * Based on reverse engineering of the communication protocol 7 + * between the windows driver / Univeral Control (UC) program 8 + * and the device, through usbmon. 9 + * 10 + * For now this bypasses the mixer, with all channels split, 11 + * so that the software can mix with greater flexibility. 12 + * It also adds controls for the 4 buttons on the front of 13 + * the device. 14 + */ 15 + 16 + #include <linux/usb.h> 17 + #include <linux/usb/audio-v2.h> 18 + #include <linux/slab.h> 19 + #include <sound/core.h> 20 + #include <sound/control.h> 21 + 22 + #include "usbaudio.h" 23 + #include "mixer.h" 24 + #include "mixer_quirks.h" 25 + #include "helper.h" 26 + #include "mixer_s1810c.h" 27 + 28 + #define SC1810C_CMD_REQ 160 29 + #define SC1810C_CMD_REQTYPE \ 30 + (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT) 31 + #define SC1810C_CMD_F1 0x50617269 32 + #define SC1810C_CMD_F2 0x14 33 + 34 + /* 35 + * DISCLAIMER: These are just guesses based on the 36 + * dumps I got. 37 + * 38 + * It seems like a selects between 39 + * device (0), mixer (0x64) and output (0x65) 40 + * 41 + * For mixer (0x64): 42 + * * b selects an input channel (see below). 43 + * * c selects an output channel pair (see below). 44 + * * d selects left (0) or right (1) of that pair. 45 + * * e 0-> disconnect, 0x01000000-> connect, 46 + * 0x0109-> used for stereo-linking channels, 47 + * e is also used for setting volume levels 48 + * in which case b is also set so I guess 49 + * this way it is possible to set the volume 50 + * level from the specified input to the 51 + * specified output. 52 + * 53 + * IN Channels: 54 + * 0 - 7 Mic/Inst/Line (Analog inputs) 55 + * 8 - 9 S/PDIF 56 + * 10 - 17 ADAT 57 + * 18 - 35 DAW (Inputs from the host) 58 + * 59 + * OUT Channels (pairs): 60 + * 0 -> Main out 61 + * 1 -> Line1/2 62 + * 2 -> Line3/4 63 + * 3 -> S/PDIF 64 + * 4 -> ADAT? 65 + * 66 + * For device (0): 67 + * * b and c are not used, at least not on the 68 + * dumps I got. 69 + * * d sets the control id to be modified 70 + * (see below). 71 + * * e sets the setting for that control. 72 + * (so for the switches I was interested 73 + * in it's 0/1) 74 + * 75 + * For output (0x65): 76 + * * b is the output channel (see above). 77 + * * c is zero. 78 + * * e I guess the same as with mixer except 0x0109 79 + * which I didn't see in my dumps. 80 + * 81 + * The two fixed fields have the same values for 82 + * mixer and output but a different set for device. 83 + */ 84 + struct s1810c_ctl_packet { 85 + u32 a; 86 + u32 b; 87 + u32 fixed1; 88 + u32 fixed2; 89 + u32 c; 90 + u32 d; 91 + u32 e; 92 + }; 93 + 94 + #define SC1810C_CTL_LINE_SW 0 95 + #define SC1810C_CTL_MUTE_SW 1 96 + #define SC1810C_CTL_AB_SW 3 97 + #define SC1810C_CTL_48V_SW 4 98 + 99 + #define SC1810C_SET_STATE_REQ 161 100 + #define SC1810C_SET_STATE_REQTYPE SC1810C_CMD_REQTYPE 101 + #define SC1810C_SET_STATE_F1 0x64656D73 102 + #define SC1810C_SET_STATE_F2 0xF4 103 + 104 + #define SC1810C_GET_STATE_REQ 162 105 + #define SC1810C_GET_STATE_REQTYPE \ 106 + (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN) 107 + #define SC1810C_GET_STATE_F1 SC1810C_SET_STATE_F1 108 + #define SC1810C_GET_STATE_F2 SC1810C_SET_STATE_F2 109 + 110 + #define SC1810C_STATE_F1_IDX 2 111 + #define SC1810C_STATE_F2_IDX 3 112 + 113 + /* 114 + * This packet includes mixer volumes and 115 + * various other fields, it's an extended 116 + * version of ctl_packet, with a and b 117 + * being zero and different f1/f2. 118 + */ 119 + struct s1810c_state_packet { 120 + u32 fields[63]; 121 + }; 122 + 123 + #define SC1810C_STATE_48V_SW 58 124 + #define SC1810C_STATE_LINE_SW 59 125 + #define SC1810C_STATE_MUTE_SW 60 126 + #define SC1810C_STATE_AB_SW 62 127 + 128 + struct s1810_mixer_state { 129 + uint16_t seqnum; 130 + struct mutex usb_mutex; 131 + struct mutex data_mutex; 132 + }; 133 + 134 + static int 135 + snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a, 136 + u32 b, u32 c, u32 d, u32 e) 137 + { 138 + struct s1810c_ctl_packet pkt = { 0 }; 139 + int ret = 0; 140 + 141 + pkt.fixed1 = SC1810C_CMD_F1; 142 + pkt.fixed2 = SC1810C_CMD_F2; 143 + 144 + pkt.a = a; 145 + pkt.b = b; 146 + pkt.c = c; 147 + pkt.d = d; 148 + /* 149 + * Value for settings 0/1 for this 150 + * output channel is always 0 (probably because 151 + * there is no ADAT output on 1810c) 152 + */ 153 + pkt.e = (c == 4) ? 0 : e; 154 + 155 + ret = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 156 + SC1810C_CMD_REQ, 157 + SC1810C_CMD_REQTYPE, 0, 0, &pkt, sizeof(pkt)); 158 + if (ret < 0) { 159 + dev_warn(&dev->dev, "could not send ctl packet\n"); 160 + return ret; 161 + } 162 + return 0; 163 + } 164 + 165 + /* 166 + * When opening Universal Control the program periodicaly 167 + * sends and receives state packets for syncinc state between 168 + * the device and the host. 169 + * 170 + * Note that if we send only the request to get data back we'll 171 + * get an error, we need to first send an empty state packet and 172 + * then ask to receive a filled. Their seqnumbers must also match. 173 + */ 174 + static int 175 + snd_sc1810c_get_status_field(struct usb_device *dev, 176 + u32 *field, int field_idx, uint16_t *seqnum) 177 + { 178 + struct s1810c_state_packet pkt_out = { { 0 } }; 179 + struct s1810c_state_packet pkt_in = { { 0 } }; 180 + int ret = 0; 181 + 182 + pkt_out.fields[SC1810C_STATE_F1_IDX] = SC1810C_SET_STATE_F1; 183 + pkt_out.fields[SC1810C_STATE_F2_IDX] = SC1810C_SET_STATE_F2; 184 + ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 185 + SC1810C_SET_STATE_REQ, 186 + SC1810C_SET_STATE_REQTYPE, 187 + (*seqnum), 0, &pkt_out, sizeof(pkt_out)); 188 + if (ret < 0) { 189 + dev_warn(&dev->dev, "could not send state packet (%d)\n", ret); 190 + return ret; 191 + } 192 + 193 + ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 194 + SC1810C_GET_STATE_REQ, 195 + SC1810C_GET_STATE_REQTYPE, 196 + (*seqnum), 0, &pkt_in, sizeof(pkt_in)); 197 + if (ret < 0) { 198 + dev_warn(&dev->dev, "could not get state field %u (%d)\n", 199 + field_idx, ret); 200 + return ret; 201 + } 202 + 203 + (*field) = pkt_in.fields[field_idx]; 204 + (*seqnum)++; 205 + return 0; 206 + } 207 + 208 + /* 209 + * This is what I got when bypassing the mixer with 210 + * all channels split. I'm not 100% sure of what's going 211 + * on, I could probably clean this up based on my observations 212 + * but I prefer to keep the same behavior as the windows driver. 213 + */ 214 + static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip) 215 + { 216 + u32 a, b, c, e, n, off; 217 + struct usb_device *dev = chip->dev; 218 + 219 + /* Set initial volume levels ? */ 220 + a = 0x64; 221 + e = 0xbc; 222 + for (n = 0; n < 2; n++) { 223 + off = n * 18; 224 + for (b = off, c = 0; b < 18 + off; b++) { 225 + /* This channel to all outputs ? */ 226 + for (c = 0; c <= 8; c++) { 227 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 228 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 229 + } 230 + /* This channel to main output (again) */ 231 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e); 232 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e); 233 + } 234 + /* 235 + * I noticed on UC that DAW channels have different 236 + * initial volumes, so this makes sense. 237 + */ 238 + e = 0xb53bf0; 239 + } 240 + 241 + /* Connect analog outputs ? */ 242 + a = 0x65; 243 + e = 0x01000000; 244 + for (b = 1; b < 3; b++) { 245 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e); 246 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e); 247 + } 248 + snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e); 249 + snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e); 250 + 251 + /* Set initial volume levels for S/PDIF mappings ? */ 252 + a = 0x64; 253 + e = 0xbc; 254 + c = 3; 255 + for (n = 0; n < 2; n++) { 256 + off = n * 18; 257 + for (b = off; b < 18 + off; b++) { 258 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 259 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 260 + } 261 + e = 0xb53bf0; 262 + } 263 + 264 + /* Connect S/PDIF output ? */ 265 + a = 0x65; 266 + e = 0x01000000; 267 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 268 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 269 + 270 + /* Connect all outputs (again) ? */ 271 + a = 0x65; 272 + e = 0x01000000; 273 + for (b = 0; b < 4; b++) { 274 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e); 275 + snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e); 276 + } 277 + 278 + /* Basic routing to get sound out of the device */ 279 + a = 0x64; 280 + e = 0x01000000; 281 + for (c = 0; c < 4; c++) { 282 + for (b = 0; b < 36; b++) { 283 + if ((c == 0 && b == 18) || /* DAW1/2 -> Main */ 284 + (c == 1 && b == 20) || /* DAW3/4 -> Line3/4 */ 285 + (c == 2 && b == 22) || /* DAW4/5 -> Line5/6 */ 286 + (c == 3 && b == 24)) { /* DAW5/6 -> S/PDIF */ 287 + /* Left */ 288 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 289 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0); 290 + b++; 291 + /* Right */ 292 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0); 293 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 294 + } else { 295 + /* Leave the rest disconnected */ 296 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0); 297 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0); 298 + } 299 + } 300 + } 301 + 302 + /* Set initial volume levels for S/PDIF (again) ? */ 303 + a = 0x64; 304 + e = 0xbc; 305 + c = 3; 306 + for (n = 0; n < 2; n++) { 307 + off = n * 18; 308 + for (b = off; b < 18 + off; b++) { 309 + snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e); 310 + snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e); 311 + } 312 + e = 0xb53bf0; 313 + } 314 + 315 + /* Connect S/PDIF outputs (again) ? */ 316 + a = 0x65; 317 + e = 0x01000000; 318 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 319 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 320 + 321 + /* Again ? */ 322 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e); 323 + snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e); 324 + 325 + return 0; 326 + } 327 + 328 + /* 329 + * Sync state with the device and retrieve the requested field, 330 + * whose index is specified in (kctl->private_value & 0xFF), 331 + * from the received fields array. 332 + */ 333 + static int 334 + snd_s1810c_get_switch_state(struct usb_mixer_interface *mixer, 335 + struct snd_kcontrol *kctl, u32 *state) 336 + { 337 + struct snd_usb_audio *chip = mixer->chip; 338 + struct s1810_mixer_state *private = mixer->private_data; 339 + u32 field = 0; 340 + u32 ctl_idx = (u32) (kctl->private_value & 0xFF); 341 + int ret = 0; 342 + 343 + mutex_lock(&private->usb_mutex); 344 + ret = snd_sc1810c_get_status_field(chip->dev, &field, 345 + ctl_idx, &private->seqnum); 346 + if (ret < 0) 347 + goto unlock; 348 + 349 + *state = field; 350 + unlock: 351 + mutex_unlock(&private->usb_mutex); 352 + return ret ? ret : 0; 353 + } 354 + 355 + /* 356 + * Send a control packet to the device for the control id 357 + * specified in (kctl->private_value >> 8) with value 358 + * specified in (kctl->private_value >> 16). 359 + */ 360 + static int 361 + snd_s1810c_set_switch_state(struct usb_mixer_interface *mixer, 362 + struct snd_kcontrol *kctl) 363 + { 364 + struct snd_usb_audio *chip = mixer->chip; 365 + struct s1810_mixer_state *private = mixer->private_data; 366 + u32 pval = (u32) kctl->private_value; 367 + u32 ctl_id = (pval >> 8) & 0xFF; 368 + u32 ctl_val = (pval >> 16) & 0x1; 369 + int ret = 0; 370 + 371 + mutex_lock(&private->usb_mutex); 372 + ret = snd_s1810c_send_ctl_packet(chip->dev, 0, 0, 0, ctl_id, ctl_val); 373 + mutex_unlock(&private->usb_mutex); 374 + return ret; 375 + } 376 + 377 + /* Generic get/set/init functions for switch controls */ 378 + 379 + static int 380 + snd_s1810c_switch_get(struct snd_kcontrol *kctl, 381 + struct snd_ctl_elem_value *ctl_elem) 382 + { 383 + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); 384 + struct usb_mixer_interface *mixer = list->mixer; 385 + struct s1810_mixer_state *private = mixer->private_data; 386 + u32 pval = (u32) kctl->private_value; 387 + u32 ctl_idx = pval & 0xFF; 388 + u32 state = 0; 389 + int ret = 0; 390 + 391 + mutex_lock(&private->data_mutex); 392 + ret = snd_s1810c_get_switch_state(mixer, kctl, &state); 393 + if (ret < 0) 394 + goto unlock; 395 + 396 + switch (ctl_idx) { 397 + case SC1810C_STATE_LINE_SW: 398 + case SC1810C_STATE_AB_SW: 399 + ctl_elem->value.enumerated.item[0] = (int)state; 400 + break; 401 + default: 402 + ctl_elem->value.integer.value[0] = (long)state; 403 + } 404 + 405 + unlock: 406 + mutex_unlock(&private->data_mutex); 407 + return (ret < 0) ? ret : 0; 408 + } 409 + 410 + static int 411 + snd_s1810c_switch_set(struct snd_kcontrol *kctl, 412 + struct snd_ctl_elem_value *ctl_elem) 413 + { 414 + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); 415 + struct usb_mixer_interface *mixer = list->mixer; 416 + struct s1810_mixer_state *private = mixer->private_data; 417 + u32 pval = (u32) kctl->private_value; 418 + u32 ctl_idx = pval & 0xFF; 419 + u32 curval = 0; 420 + u32 newval = 0; 421 + int ret = 0; 422 + 423 + mutex_lock(&private->data_mutex); 424 + ret = snd_s1810c_get_switch_state(mixer, kctl, &curval); 425 + if (ret < 0) 426 + goto unlock; 427 + 428 + switch (ctl_idx) { 429 + case SC1810C_STATE_LINE_SW: 430 + case SC1810C_STATE_AB_SW: 431 + newval = (u32) ctl_elem->value.enumerated.item[0]; 432 + break; 433 + default: 434 + newval = (u32) ctl_elem->value.integer.value[0]; 435 + } 436 + 437 + if (curval == newval) 438 + goto unlock; 439 + 440 + kctl->private_value &= ~(0x1 << 16); 441 + kctl->private_value |= (unsigned int)(newval & 0x1) << 16; 442 + ret = snd_s1810c_set_switch_state(mixer, kctl); 443 + 444 + unlock: 445 + mutex_unlock(&private->data_mutex); 446 + return (ret < 0) ? 0 : 1; 447 + } 448 + 449 + static int 450 + snd_s1810c_switch_init(struct usb_mixer_interface *mixer, 451 + const struct snd_kcontrol_new *new_kctl) 452 + { 453 + struct snd_kcontrol *kctl; 454 + struct usb_mixer_elem_info *elem; 455 + 456 + elem = kzalloc(sizeof(struct usb_mixer_elem_info), GFP_KERNEL); 457 + if (!elem) 458 + return -ENOMEM; 459 + 460 + elem->head.mixer = mixer; 461 + elem->control = 0; 462 + elem->head.id = 0; 463 + elem->channels = 1; 464 + 465 + kctl = snd_ctl_new1(new_kctl, elem); 466 + if (!kctl) { 467 + kfree(elem); 468 + return -ENOMEM; 469 + } 470 + kctl->private_free = snd_usb_mixer_elem_free; 471 + 472 + return snd_usb_mixer_add_control(&elem->head, kctl); 473 + } 474 + 475 + static int 476 + snd_s1810c_line_sw_info(struct snd_kcontrol *kctl, 477 + struct snd_ctl_elem_info *uinfo) 478 + { 479 + static const char *const texts[2] = { 480 + "Preamp On (Mic/Inst)", 481 + "Preamp Off (Line in)" 482 + }; 483 + 484 + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); 485 + } 486 + 487 + static const struct snd_kcontrol_new snd_s1810c_line_sw = { 488 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 489 + .name = "Line 1/2 Source Type", 490 + .info = snd_s1810c_line_sw_info, 491 + .get = snd_s1810c_switch_get, 492 + .put = snd_s1810c_switch_set, 493 + .private_value = (SC1810C_STATE_LINE_SW | SC1810C_CTL_LINE_SW << 8) 494 + }; 495 + 496 + static const struct snd_kcontrol_new snd_s1810c_mute_sw = { 497 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 498 + .name = "Mute Main Out Switch", 499 + .info = snd_ctl_boolean_mono_info, 500 + .get = snd_s1810c_switch_get, 501 + .put = snd_s1810c_switch_set, 502 + .private_value = (SC1810C_STATE_MUTE_SW | SC1810C_CTL_MUTE_SW << 8) 503 + }; 504 + 505 + static const struct snd_kcontrol_new snd_s1810c_48v_sw = { 506 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 507 + .name = "48V Phantom Power On Mic Inputs Switch", 508 + .info = snd_ctl_boolean_mono_info, 509 + .get = snd_s1810c_switch_get, 510 + .put = snd_s1810c_switch_set, 511 + .private_value = (SC1810C_STATE_48V_SW | SC1810C_CTL_48V_SW << 8) 512 + }; 513 + 514 + static int 515 + snd_s1810c_ab_sw_info(struct snd_kcontrol *kctl, 516 + struct snd_ctl_elem_info *uinfo) 517 + { 518 + static const char *const texts[2] = { 519 + "1/2", 520 + "3/4" 521 + }; 522 + 523 + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); 524 + } 525 + 526 + static const struct snd_kcontrol_new snd_s1810c_ab_sw = { 527 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 528 + .name = "Headphone 1 Source Route", 529 + .info = snd_s1810c_ab_sw_info, 530 + .get = snd_s1810c_switch_get, 531 + .put = snd_s1810c_switch_set, 532 + .private_value = (SC1810C_STATE_AB_SW | SC1810C_CTL_AB_SW << 8) 533 + }; 534 + 535 + static void snd_sc1810_mixer_state_free(struct usb_mixer_interface *mixer) 536 + { 537 + struct s1810_mixer_state *private = mixer->private_data; 538 + kfree(private); 539 + mixer->private_data = NULL; 540 + } 541 + 542 + /* Entry point, called from mixer_quirks.c */ 543 + int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer) 544 + { 545 + struct s1810_mixer_state *private = NULL; 546 + struct snd_usb_audio *chip = mixer->chip; 547 + struct usb_device *dev = chip->dev; 548 + int ret = 0; 549 + 550 + /* Run this only once */ 551 + if (!list_empty(&chip->mixer_list)) 552 + return 0; 553 + 554 + dev_info(&dev->dev, 555 + "Presonus Studio 1810c, device_setup: %u\n", chip->setup); 556 + if (chip->setup == 1) 557 + dev_info(&dev->dev, "(8out/18in @ 48KHz)\n"); 558 + else if (chip->setup == 2) 559 + dev_info(&dev->dev, "(6out/8in @ 192KHz)\n"); 560 + else 561 + dev_info(&dev->dev, "(8out/14in @ 96KHz)\n"); 562 + 563 + ret = snd_s1810c_init_mixer_maps(chip); 564 + if (ret < 0) 565 + return ret; 566 + 567 + private = kzalloc(sizeof(struct s1810_mixer_state), GFP_KERNEL); 568 + if (!private) 569 + return -ENOMEM; 570 + 571 + mutex_init(&private->usb_mutex); 572 + mutex_init(&private->data_mutex); 573 + 574 + mixer->private_data = private; 575 + mixer->private_free = snd_sc1810_mixer_state_free; 576 + 577 + private->seqnum = 1; 578 + 579 + ret = snd_s1810c_switch_init(mixer, &snd_s1810c_line_sw); 580 + if (ret < 0) 581 + return ret; 582 + 583 + ret = snd_s1810c_switch_init(mixer, &snd_s1810c_mute_sw); 584 + if (ret < 0) 585 + return ret; 586 + 587 + ret = snd_s1810c_switch_init(mixer, &snd_s1810c_48v_sw); 588 + if (ret < 0) 589 + return ret; 590 + 591 + ret = snd_s1810c_switch_init(mixer, &snd_s1810c_ab_sw); 592 + if (ret < 0) 593 + return ret; 594 + return ret; 595 + }
+7
sound/usb/mixer_s1810c.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Presonus Studio 1810c driver for ALSA 4 + * Copyright (C) 2019 Nick Kossifidis <mickflemm@gmail.com> 5 + */ 6 + 7 + int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer);
+6 -1
sound/usb/pcm.c
··· 357 357 ep = 0x81; 358 358 ifnum = 1; 359 359 goto add_sync_ep_from_ifnum; 360 - case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */ 360 + case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II/IIc */ 361 + /* MicroBook IIc */ 362 + if (altsd->bInterfaceClass == USB_CLASS_AUDIO) 363 + return 0; 364 + 365 + /* MicroBook II */ 361 366 ep = 0x84; 362 367 ifnum = 0; 363 368 goto add_sync_ep_from_ifnum;
+1 -1
sound/usb/proc.c
··· 70 70 snd_iprintf(buffer, " Interface %d\n", fp->iface); 71 71 snd_iprintf(buffer, " Altset %d\n", fp->altsetting); 72 72 snd_iprintf(buffer, " Format:"); 73 - for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt) 73 + pcm_for_each_format(fmt) 74 74 if (fp->formats & pcm_format_to_bits(fmt)) 75 75 snd_iprintf(buffer, " %s", 76 76 snd_pcm_format_name(fmt));
+1 -1
sound/usb/quirks-table.h
··· 3472 3472 }, 3473 3473 /* MOTU Microbook II */ 3474 3474 { 3475 - USB_DEVICE(0x07fd, 0x0004), 3475 + USB_DEVICE_VENDOR_SPEC(0x07fd, 0x0004), 3476 3476 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { 3477 3477 .vendor_name = "MOTU", 3478 3478 .product_name = "MicroBookII",
+87 -1
sound/usb/quirks.c
··· 1252 1252 return 0; /* keep this altsetting */ 1253 1253 } 1254 1254 1255 + static int s1810c_skip_setting_quirk(struct snd_usb_audio *chip, 1256 + int iface, int altno) 1257 + { 1258 + /* 1259 + * Altno settings: 1260 + * 1261 + * Playback (Interface 1): 1262 + * 1: 6 Analog + 2 S/PDIF 1263 + * 2: 6 Analog + 2 S/PDIF 1264 + * 3: 6 Analog 1265 + * 1266 + * Capture (Interface 2): 1267 + * 1: 8 Analog + 2 S/PDIF + 8 ADAT 1268 + * 2: 8 Analog + 2 S/PDIF + 4 ADAT 1269 + * 3: 8 Analog 1270 + */ 1271 + 1272 + /* 1273 + * I'll leave 2 as the default one and 1274 + * use device_setup to switch to the 1275 + * other two. 1276 + */ 1277 + if ((chip->setup == 0 || chip->setup > 2) && altno != 2) 1278 + return 1; 1279 + else if (chip->setup == 1 && altno != 1) 1280 + return 1; 1281 + else if (chip->setup == 2 && altno != 3) 1282 + return 1; 1283 + 1284 + return 0; 1285 + } 1286 + 1255 1287 int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, 1256 1288 int iface, 1257 1289 int altno) ··· 1297 1265 /* fasttrackpro usb: skip altsets incompatible with device_setup */ 1298 1266 if (chip->usb_id == USB_ID(0x0763, 0x2012)) 1299 1267 return fasttrackpro_skip_setting_quirk(chip, iface, altno); 1268 + /* presonus studio 1810c: skip altsets incompatible with device_setup */ 1269 + if (chip->usb_id == USB_ID(0x0194f, 0x010c)) 1270 + return s1810c_skip_setting_quirk(chip, iface, altno); 1271 + 1300 1272 1301 1273 return 0; 1302 1274 } ··· 1352 1316 case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */ 1353 1317 return snd_usb_axefx3_boot_quirk(dev); 1354 1318 case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */ 1355 - return snd_usb_motu_microbookii_boot_quirk(dev); 1319 + /* 1320 + * For some reason interface 3 with vendor-spec class is 1321 + * detected on MicroBook IIc. 1322 + */ 1323 + if (get_iface_desc(intf->altsetting)->bInterfaceClass == 1324 + USB_CLASS_VENDOR_SPEC && 1325 + get_iface_desc(intf->altsetting)->bInterfaceNumber < 3) 1326 + return snd_usb_motu_microbookii_boot_quirk(dev); 1327 + break; 1356 1328 } 1357 1329 1358 1330 return 0; ··· 1798 1754 else 1799 1755 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; 1800 1756 break; 1757 + case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook IIc */ 1758 + /* 1759 + * MaxPacketsOnly attribute is erroneously set in endpoint 1760 + * descriptors. As a result this card produces noise with 1761 + * all sample rates other than 96 KHz. 1762 + */ 1763 + fp->attributes &= ~UAC_EP_CS_ATTR_FILL_MAX; 1764 + break; 1801 1765 } 1766 + } 1767 + 1768 + /* 1769 + * registration quirk: 1770 + * the registration is skipped if a device matches with the given ID, 1771 + * unless the interface reaches to the defined one. This is for delaying 1772 + * the registration until the last known interface, so that the card and 1773 + * devices appear at the same time. 1774 + */ 1775 + 1776 + struct registration_quirk { 1777 + unsigned int usb_id; /* composed via USB_ID() */ 1778 + unsigned int interface; /* the interface to trigger register */ 1779 + }; 1780 + 1781 + #define REG_QUIRK_ENTRY(vendor, product, iface) \ 1782 + { .usb_id = USB_ID(vendor, product), .interface = (iface) } 1783 + 1784 + static const struct registration_quirk registration_quirks[] = { 1785 + REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */ 1786 + { 0 } /* terminator */ 1787 + }; 1788 + 1789 + /* return true if skipping registration */ 1790 + bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface) 1791 + { 1792 + const struct registration_quirk *q; 1793 + 1794 + for (q = registration_quirks; q->usb_id; q++) 1795 + if (chip->usb_id == q->usb_id) 1796 + return iface != q->interface; 1797 + 1798 + /* Register as normal */ 1799 + return false; 1802 1800 }
+2
sound/usb/quirks.h
··· 51 51 struct audioformat *fp, 52 52 int stream); 53 53 54 + bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface); 55 + 54 56 #endif /* __USBAUDIO_QUIRKS_H */
+3
sound/usb/stream.c
··· 502 502 subs = &as->substream[stream]; 503 503 if (subs->ep_num) 504 504 continue; 505 + if (snd_device_get_state(chip->card, as->pcm) != 506 + SNDRV_DEV_BUILD) 507 + chip->need_delayed_register = true; 505 508 err = snd_pcm_new_stream(as->pcm, stream, 1); 506 509 if (err < 0) 507 510 return err;
+1
sound/usb/usbaudio.h
··· 34 34 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ 35 35 unsigned int tx_length_quirk:1; /* Put length specifier in transfers */ 36 36 unsigned int setup_fmt_after_resume_quirk:1; /* setup the format to interface after resume */ 37 + unsigned int need_delayed_register:1; /* warn for delayed registration */ 37 38 int num_interfaces; 38 39 int num_suspended_intf; 39 40 int sample_rate_read_error;
+5 -4
sound/usb/usx2y/usbusx2yaudio.c
··· 906 906 */ 907 907 static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) 908 908 { 909 - kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); 910 - usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; 909 + int stream; 911 910 912 - kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); 913 - usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; 911 + for_each_pcm_streams(stream) { 912 + kfree(usX2Y_substream[stream]); 913 + usX2Y_substream[stream] = NULL; 914 + } 914 915 } 915 916 916 917 static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)