ASoC: Updates for v5.18

Quite a quiet release for ASoC, lots of work on drivers and platforms
 but nothing too groundbreaking but not much on the core itself:
 
  - Start of moving SoF to support multiple IPC mechanisms.
  - Use of NHLT ACPI table to reduce the amount of quirking required for
    Intel systems.
  - Some building blocks for use in forthcoming Intel AVS driver for
    legacy Intel DSP firmwares.
  - Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with
    TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek
    MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280, Renesas
    RZ/V2L, Texas Instruments TAS585M
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmI4aDoACgkQJNaLcl1U
 h9BPKgf/XSKCt67IzrbnI9UXp1Q13C54z57e+nGr4LBSRraT/WwdXFevefC6JZDq
 bYQWhigFrQyyYSyxVJYIvtywXXpMzJ1ypzHqcBGmqCufoX0zoaRwTFYg60yiYqdy
 cDsX82/1bhI9Dp3RWaEKaMyaa9FI0Kr3WTA6EKdo592u0hxj4UcK51r7qsp1JpsR
 tQWGMYqqwtajhamFgrIlKiJDDVnv2qEhrWdho5W/FPAby+fsJ6VJBMhwEx/F7cXu
 Mjfa0k2MoMAlNX9DxtIHweVECaN32HJsytrbgUAdYnBoGaZNkXwLwvyp9RIeDAMP
 NZ+w3lwFLw1N8S2ho6kqtDpO+tJU0Q==
 =Y6/E
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v5.18' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v5.18

Quite a quiet release for ASoC, lots of work on drivers and platforms
but nothing too groundbreaking but not much on the core itself:

 - Start of moving SoF to support multiple IPC mechanisms.
 - Use of NHLT ACPI table to reduce the amount of quirking required for
   Intel systems.
 - Some building blocks for use in forthcoming Intel AVS driver for
   legacy Intel DSP firmwares.
 - Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with
   TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek
   MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280, Renesas
   RZ/V2L, Texas Instruments TAS585M
This commit is contained in:
Takashi Iwai 2022-03-21 16:19:21 +01:00
commit 646b907e15
344 changed files with 21685 additions and 7021 deletions

View File

@ -21,6 +21,7 @@ properties:
- const: nvidia,tegra210-aconnect - const: nvidia,tegra210-aconnect
- items: - items:
- enum: - enum:
- nvidia,tegra234-aconnect
- nvidia,tegra186-aconnect - nvidia,tegra186-aconnect
- nvidia,tegra194-aconnect - nvidia,tegra194-aconnect
- const: nvidia,tegra210-aconnect - const: nvidia,tegra210-aconnect

View File

@ -23,7 +23,9 @@ properties:
- nvidia,tegra210-adma - nvidia,tegra210-adma
- nvidia,tegra186-adma - nvidia,tegra186-adma
- items: - items:
- const: nvidia,tegra194-adma - enum:
- nvidia,tegra234-adma
- nvidia,tegra194-adma
- const: nvidia,tegra186-adma - const: nvidia,tegra186-adma
reg: reg:

View File

@ -58,6 +58,7 @@ properties:
- enum: - enum:
- nvidia,tegra186-agic - nvidia,tegra186-agic
- nvidia,tegra194-agic - nvidia,tegra194-agic
- nvidia,tegra234-agic
- const: nvidia,tegra210-agic - const: nvidia,tegra210-agic
interrupt-controller: true interrupt-controller: true

View File

@ -31,6 +31,10 @@ properties:
- const: allwinner,sun50i-a64-i2s - const: allwinner,sun50i-a64-i2s
- const: allwinner,sun8i-h3-i2s - const: allwinner,sun8i-h3-i2s
- const: allwinner,sun50i-h6-i2s - const: allwinner,sun50i-h6-i2s
- const: allwinner,sun50i-r329-i2s
- items:
- const: allwinner,sun20i-d1-i2s
- const: allwinner,sun50i-r329-i2s
reg: reg:
maxItems: 1 maxItems: 1
@ -67,6 +71,7 @@ allOf:
- allwinner,sun8i-h3-i2s - allwinner,sun8i-h3-i2s
- allwinner,sun50i-a64-codec-i2s - allwinner,sun50i-a64-codec-i2s
- allwinner,sun50i-h6-i2s - allwinner,sun50i-h6-i2s
- allwinner,sun50i-r329-i2s
then: then:
required: required:

View File

@ -1,25 +0,0 @@
Audio Binding for Arndale boards
Required properties:
- compatible : Can be one of the following:
"samsung,arndale-rt5631",
"samsung,arndale-wm1811"
- samsung,audio-cpu: The phandle of the Samsung I2S controller
- samsung,audio-codec: The phandle of the audio codec
Optional:
- samsung,model: The name of the sound-card
Arndale Boards has many audio daughter cards, one of them is
rt5631/alc5631. Below example shows audio bindings for rt5631/
alc5631 based codec.
Example:
sound {
compatible = "samsung,arndale-rt5631";
samsung,audio-cpu = <&i2s0>
samsung,audio-codec = <&rt5631>;
};

View File

@ -71,4 +71,24 @@ patternProperties:
description: CPU to Codec rate channels. description: CPU to Codec rate channels.
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width-map:
description: Mapping of sample widths to slot widths. For hardware
that cannot support a fixed slot width or a slot width always
equal to sample width. A matrix of one or more 3-tuples.
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
-
description: Sample width in bits
minimum: 8
maximum: 64
-
description: Slot width in bits
minimum: 8
maximum: 256
-
description: Slot count
minimum: 1
maximum: 64
additionalProperties: true additionalProperties: true

View File

@ -0,0 +1,54 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/awinic,aw8738.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Awinic AW8738 Audio Amplifier
maintainers:
- Stephan Gerhold <stephan@gerhold.net>
description:
The Awinic AW8738 is a simple audio amplifier with different operation modes
(set using one-wire pulse control). The mode configures the speaker-guard
function (primarily the power limit for the amplifier).
allOf:
- $ref: name-prefix.yaml#
properties:
compatible:
const: awinic,aw8738
mode-gpios:
description:
GPIO used for one-wire pulse control. The pin is typically called SHDN
(active-low), but this is misleading since it is actually more than
just a simple shutdown/enable control.
maxItems: 1
awinic,mode:
description: Operation mode (number of pulses for one-wire pulse control)
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 7
sound-name-prefix: true
required:
- compatible
- mode-gpios
- awinic,mode
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
audio-amplifier {
compatible = "awinic,aw8738";
mode-gpios = <&msmgpio 114 GPIO_ACTIVE_HIGH>;
awinic,mode = <5>;
sound-name-prefix = "Speaker Amp";
};

View File

@ -1,86 +0,0 @@
Texas Instruments McASP controller
Required properties:
- compatible :
"ti,dm646x-mcasp-audio" : for DM646x platforms
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
"ti,dra7-mcasp-audio" : for DRA7xx platforms
"ti,omap4-mcasp-audio" : for OMAP4
- reg : Should contain reg specifiers for the entries in the reg-names property.
- reg-names : Should contain:
* "mpu" for the main registers (required). For compatibility with
existing software, it is recommended this is the first entry.
* "dat" for separate data port register access (optional).
- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
IEC60958-1, and AES-3 formats.
- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
or received over one serializer.
- serial-dir : A list of serializer configuration. Each entry is a number
indication for serializer pin direction.
(0 - INACTIVE, 1 - TX, 2 - RX)
- dmas: two element list of DMA controller phandles and DMA request line
ordered pairs.
- dma-names: identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas. The dma
identifiers must be "rx" and "tx".
Optional properties:
- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
- tx-num-evt : FIFO levels.
- rx-num-evt : FIFO levels.
- dismod : Specify the drive on TX pin during inactive slots
0 : 3-state
2 : logic low
3 : logic high
Defaults to 'logic low' when the property is not present
- sram-size-playback : size of sram to be allocated during playback
- sram-size-capture : size of sram to be allocated during capture
- interrupts : Interrupt numbers for McASP
- interrupt-names : Known interrupt names are "tx" and "rx"
- pinctrl-0: Should specify pin control group used for this controller.
- pinctrl-names: Should contain only one value - "default", for more details
please refer to pinctrl-bindings.txt
- fck_parent : Should contain a valid clock name which will be used as parent
for the McASP fck
- auxclk-fs-ratio: When McASP is bus master indicates the ratio between AUCLK
and FS rate if applicable:
AUCLK rate = auxclk-fs-ratio * FS rate
Optional GPIO support:
If any McASP pin need to be used as GPIO then the McASP node must have:
...
gpio-controller
#gpio-cells = <2>;
...
When requesting a GPIO, the first parameter is the PIN index in McASP_P*
registers.
For example to request the AXR2 pin of mcasp8:
function-gpios = <&mcasp8 2 0>;
Or to request the ACLKR pin of mcasp8:
function-gpios = <&mcasp8 29 0>;
For generic gpio information, please refer to bindings/gpio/gpio.txt
Example:
mcasp0: mcasp0@1d00000 {
compatible = "ti,da830-mcasp-audio";
reg = <0x100000 0x3000>;
reg-names "mpu";
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
serial-dir = <
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
0 0 0 0
0 0 0 1
2 0 0 0 >;
tx-num-evt = <1>;
rx-num-evt = <1>;
};

View File

@ -0,0 +1,201 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/davinci-mcasp-audio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: McASP Controller for TI SoCs
maintainers:
- Jayesh Choudhary <j-choudhary@ti.com>
properties:
compatible:
enum:
- ti,dm646x-mcasp-audio
- ti,da830-mcasp-audio
- ti,am33xx-mcasp-audio
- ti,dra7-mcasp-audio
- ti,omap4-mcasp-audio
reg:
minItems: 1
items:
- description: CFG registers
- description: data registers
reg-names:
minItems: 1
items:
- const: mpu
- const: dat
op-mode:
$ref: /schemas/types.yaml#/definitions/uint32
description: 0 - I2S or 1 - DIT operation mode
enum:
- 0
- 1
tdm-slots:
$ref: /schemas/types.yaml#/definitions/uint32
description:
number of channels over one serializer
the property is ignored in DIT mode
minimum: 2
maximum: 32
serial-dir:
description:
A list of serializer configuration
Entry is indication for serializer pin direction
0 - Inactive, 1 - TX, 2 - RX
All AXR pins should be present in the array even if inactive
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 25
items:
minimum: 0
maximum: 2
dmas:
minItems: 1
items:
- description: transmission DMA channel
- description: reception DMA channel
dma-names:
minItems: 1
items:
- const: tx
- const: rx
ti,hwmods:
$ref: /schemas/types.yaml#/definitions/string
description: Name of hwmod associated with McASP
maxItems: 1
deprecated: true
tx-num-evt:
$ref: /schemas/types.yaml#/definitions/uint32
description:
configures WFIFO threshold
0 disables the FIFO use
if property is missing, then also FIFO use is disabled
rx-num-evt:
$ref: /schemas/types.yaml#/definitions/uint32
description:
configures RFIFO threshold
0 disables the FIFO use
if property is missing, then also FIFO use is disabled
dismod:
$ref: /schemas/types.yaml#/definitions/uint32
description:
specify the drive on TX pin during inactive time slots
0 - 3-state, 2 - logic low, 3 - logic high
enum:
- 0
- 2
- 3
default: 2
interrupts:
anyOf:
- minItems: 1
items:
- description: TX interrupt
- description: RX interrupt
- items:
- description: common/combined interrupt
interrupt-names:
oneOf:
- minItems: 1
items:
- const: tx
- const: rx
- const: common
fck_parent:
$ref: /schemas/types.yaml#/definitions/string
description: parent clock name for McASP fck
maxItems: 1
auxclk-fs-ratio:
$ref: /schemas/types.yaml#/definitions/uint32
description: ratio of AUCLK and FS rate if applicable
gpio-controller: true
"#gpio-cells":
const: 2
clocks:
minItems: 1
items:
- description: functional clock
- description: module specific optional ahclkx clock
- description: module specific optional ahclkr clock
clock-names:
minItems: 1
items:
- const: fck
- const: ahclkx
- const: ahclkr
power-domains:
description: phandle to the corresponding power-domain
maxItems: 1
"#sound-dai-cells":
const: 0
port:
description: connection for when McASP is used via graph card
type: object
required:
- compatible
- reg
- reg-names
- dmas
- dma-names
- interrupts
- interrupt-names
allOf:
- if:
properties:
opmode:
enum:
- 0
then:
required:
- tdm-slots
additionalProperties: false
examples:
- |
mcasp0: mcasp0@1d00000 {
compatible = "ti,da830-mcasp-audio";
reg = <0x100000 0x3000>;
reg-names = "mpu";
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
op-mode = <0>; /* MCASP_IIS_MODE */
tdm-slots = <2>;
dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
dma-names = "tx", "rx";
serial-dir = <
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
0 0 0 0
0 0 0 1
2 0 0 0 >;
tx-num-evt = <1>;
rx-num-evt = <1>;
};

View File

@ -40,6 +40,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-tlv320aic32x4" "fsl,imx-audio-tlv320aic32x4"
"fsl,imx-audio-tlv320aic31xx"
"fsl,imx-audio-si476x" "fsl,imx-audio-si476x"
"fsl,imx-audio-wm8958" "fsl,imx-audio-wm8958"
@ -82,6 +84,7 @@ Optional properties:
- dai-format : audio format, for details see simple-card.yaml. - dai-format : audio format, for details see simple-card.yaml.
- frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml. - frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml.
- bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml. - bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml.
- mclk-id : main clock id, specific for each card configuration.
Optional unless SSI is selected as a CPU DAI: Optional unless SSI is selected as a CPU DAI:

View File

@ -0,0 +1,180 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/google,sc7280-herobrine.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Google SC7280-Herobrine ASoC sound card driver
maintainers:
- Srinivasa Rao Mandadapu <srivasam@codeaurora.org>
- Judy Hsiao <judyhsiao@chromium.org>
description:
This binding describes the SC7280 sound card which uses LPASS for audio.
properties:
compatible:
enum:
- google,sc7280-herobrine
audio-routing:
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
description:
A list of the connections between audio components. Each entry is a
pair of strings, the first being the connection's sink, the second
being the connection's source.
model:
$ref: /schemas/types.yaml#/definitions/string
description: User specified audio sound card name
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
"^dai-link@[0-9a-f]$":
description:
Each subnode represents a dai link. Subnodes of each dai links would be
cpu/codec dais.
type: object
properties:
link-name:
description: Indicates dai-link name and PCM stream name.
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
reg:
maxItems: 1
description: dai link address.
cpu:
description: Holds subnode which indicates cpu dai.
type: object
properties:
sound-dai: true
required:
- sound-dai
additionalProperties: false
codec:
description: Holds subnode which indicates codec dai.
type: object
properties:
sound-dai: true
required:
- sound-dai
additionalProperties: false
required:
- link-name
- cpu
- codec
- reg
additionalProperties: false
required:
- compatible
- model
- "#address-cells"
- "#size-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/sound/qcom,lpass.h>
sound {
compatible = "google,sc7280-herobrine";
model = "sc7280-wcd938x-max98360a-4dmic";
audio-routing =
"IN1_HPHL", "HPHL_OUT",
"IN2_HPHR", "HPHR_OUT",
"AMIC1", "MIC BIAS1",
"AMIC2", "MIC BIAS2",
"VA DMIC0", "MIC BIAS3",
"VA DMIC1", "MIC BIAS3",
"VA DMIC2", "MIC BIAS4",
"VA DMIC3", "MIC BIAS4",
"TX SWR_ADC0", "ADC1_OUTPUT",
"TX SWR_ADC1", "ADC2_OUTPUT",
"TX SWR_ADC2", "ADC3_OUTPUT",
"TX SWR_DMIC0", "DMIC1_OUTPUT",
"TX SWR_DMIC1", "DMIC2_OUTPUT",
"TX SWR_DMIC2", "DMIC3_OUTPUT",
"TX SWR_DMIC3", "DMIC4_OUTPUT";
#address-cells = <1>;
#size-cells = <0>;
dai-link@0 {
link-name = "WCD Playback";
reg = <LPASS_CDC_DMA_RX0>;
cpu {
sound-dai = <&lpass_cpu LPASS_CDC_DMA_RX0>;
};
codec {
sound-dai = <&wcd938x 0>, <&swr0 0>, <&rxmacro 0>;
};
};
dai-link@1 {
link-name = "WCD Capture";
reg = <LPASS_CDC_DMA_TX3>;
cpu {
sound-dai = <&lpass_cpu LPASS_CDC_DMA_TX3>;
};
codec {
sound-dai = <&wcd938x 1>, <&swr1 0>, <&txmacro 0>;
};
};
dai-link@2 {
link-name = "MI2S Playback";
reg = <MI2S_SECONDARY>;
cpu {
sound-dai = <&lpass_cpu MI2S_SECONDARY>;
};
codec {
sound-dai = <&max98360a>;
};
};
dai-link@3 {
link-name = "DMIC Capture";
reg = <LPASS_CDC_DMA_VA_TX0>;
cpu {
sound-dai = <&lpass_cpu LPASS_CDC_DMA_VA_TX0>;
};
codec {
sound-dai = <&vamacro 0>;
};
};
dai-link@5 {
link-name = "DP Playback";
reg = <LPASS_DP_RX>;
cpu {
sound-dai = <&lpass_cpu LPASS_DP_RX>;
};
codec {
sound-dai = <&mdss_dp>;
};
};
};

View File

@ -0,0 +1,100 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/microchip,pdmc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip Pulse Density Microphone Controller
maintainers:
- Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
description:
The Microchip Pulse Density Microphone Controller (PDMC) interfaces up to 4
digital microphones having Pulse Density Modulated (PDM) outputs.
properties:
compatible:
const: microchip,sama7g5-pdmc
reg:
maxItems: 1
"#sound-dai-cells":
const: 0
interrupts:
maxItems: 1
clocks:
items:
- description: Peripheral Bus Clock
- description: Generic Clock
clock-names:
items:
- const: pclk
- const: gclk
dmas:
description: RX DMA Channel
maxItems: 1
dma-names:
const: rx
microchip,mic-pos:
description: |
Position of PDM microphones on the DS line and the sampling edge (rising
or falling) of the CLK line. A microphone is represented as a pair of DS
line and the sampling edge. The first microphone is mapped to channel 0,
the second to channel 1, etc.
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description: value for DS line
- description: value for sampling edge
anyOf:
- enum:
- [0, 0]
- [0, 1]
- [1, 0]
- [1, 1]
minItems: 1
maxItems: 4
uniqueItems: true
required:
- compatible
- reg
- "#sound-dai-cells"
- interrupts
- clocks
- clock-names
- dmas
- dma-names
- microchip,mic-pos
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/at91.h>
#include <dt-bindings/dma/at91.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/sound/microchip,pdmc.h>
pdmc: sound@e1608000 {
compatible = "microchip,sama7g5-pdmc";
reg = <0xe1608000 0x4000>;
#sound-dai-cells = <0>;
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(37)>;
dma-names = "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 68>, <&pmc PMC_TYPE_GCK 68>;
clock-names = "pclk", "gclk";
microchip,mic-pos = <MCHP_PDMC_DS0 MCHP_PDMC_CLK_POSITIVE>,
<MCHP_PDMC_DS0 MCHP_PDMC_CLK_NEGATIVE>,
<MCHP_PDMC_DS1 MCHP_PDMC_CLK_POSITIVE>,
<MCHP_PDMC_DS1 MCHP_PDMC_CLK_NEGATIVE>;
};

View File

@ -19,6 +19,12 @@ properties:
interrupts: interrupts:
maxItems: 1 maxItems: 1
resets:
maxItems: 1
reset-names:
const: audiosys
memory-region: memory-region:
maxItems: 1 maxItems: 1
description: | description: |
@ -127,6 +133,8 @@ required:
- compatible - compatible
- reg - reg
- interrupts - interrupts
- resets
- reset-names
- mediatek,topckgen - mediatek,topckgen
- power-domains - power-domains
- clocks - clocks
@ -144,6 +152,8 @@ examples:
compatible = "mediatek,mt8195-audio"; compatible = "mediatek,mt8195-audio";
reg = <0x10890000 0x10000>; reg = <0x10890000 0x10000>;
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>; interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
resets = <&watchdog 14>;
reset-names = "audiosys";
mediatek,topckgen = <&topckgen>; mediatek,topckgen = <&topckgen>;
power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
memory-region = <&snd_dma_mem_reserved>; memory-region = <&snd_dma_mem_reserved>;

View File

@ -28,7 +28,9 @@ properties:
oneOf: oneOf:
- const: nvidia,tegra186-dspk - const: nvidia,tegra186-dspk
- items: - items:
- const: nvidia,tegra194-dspk - enum:
- nvidia,tegra234-dspk
- nvidia,tegra194-dspk
- const: nvidia,tegra186-dspk - const: nvidia,tegra186-dspk
reg: reg:

View File

@ -27,7 +27,9 @@ properties:
- nvidia,tegra210-admaif - nvidia,tegra210-admaif
- nvidia,tegra186-admaif - nvidia,tegra186-admaif
- items: - items:
- const: nvidia,tegra194-admaif - enum:
- nvidia,tegra234-admaif
- nvidia,tegra194-admaif
- const: nvidia,tegra186-admaif - const: nvidia,tegra186-admaif
reg: reg:

View File

@ -30,6 +30,7 @@ properties:
- const: nvidia,tegra210-adx - const: nvidia,tegra210-adx
- items: - items:
- enum: - enum:
- nvidia,tegra234-adx
- nvidia,tegra194-adx - nvidia,tegra194-adx
- nvidia,tegra186-adx - nvidia,tegra186-adx
- const: nvidia,tegra210-adx - const: nvidia,tegra210-adx

View File

@ -26,6 +26,7 @@ properties:
- enum: - enum:
- nvidia,tegra210-ahub - nvidia,tegra210-ahub
- nvidia,tegra186-ahub - nvidia,tegra186-ahub
- nvidia,tegra234-ahub
- items: - items:
- const: nvidia,tegra194-ahub - const: nvidia,tegra194-ahub
- const: nvidia,tegra186-ahub - const: nvidia,tegra186-ahub

View File

@ -31,6 +31,9 @@ properties:
- const: nvidia,tegra186-amx - const: nvidia,tegra186-amx
- const: nvidia,tegra210-amx - const: nvidia,tegra210-amx
- const: nvidia,tegra194-amx - const: nvidia,tegra194-amx
- items:
- const: nvidia,tegra234-amx
- const: nvidia,tegra194-amx
reg: reg:
maxItems: 1 maxItems: 1

View File

@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-dmic - const: nvidia,tegra210-dmic
- items: - items:
- enum: - enum:
- nvidia,tegra234-dmic
- nvidia,tegra194-dmic - nvidia,tegra194-dmic
- nvidia,tegra186-dmic - nvidia,tegra186-dmic
- const: nvidia,tegra210-dmic - const: nvidia,tegra210-dmic

View File

@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-i2s - const: nvidia,tegra210-i2s
- items: - items:
- enum: - enum:
- nvidia,tegra234-i2s
- nvidia,tegra194-i2s - nvidia,tegra194-i2s
- nvidia,tegra186-i2s - nvidia,tegra186-i2s
- const: nvidia,tegra210-i2s - const: nvidia,tegra210-i2s

View File

@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-amixer - const: nvidia,tegra210-amixer
- items: - items:
- enum: - enum:
- nvidia,tegra234-amixer
- nvidia,tegra194-amixer - nvidia,tegra194-amixer
- nvidia,tegra186-amixer - nvidia,tegra186-amixer
- const: nvidia,tegra210-amixer - const: nvidia,tegra210-amixer

View File

@ -31,6 +31,7 @@ properties:
- const: nvidia,tegra210-mvc - const: nvidia,tegra210-mvc
- items: - items:
- enum: - enum:
- nvidia,tegra234-mvc
- nvidia,tegra194-mvc - nvidia,tegra194-mvc
- nvidia,tegra186-mvc - nvidia,tegra186-mvc
- const: nvidia,tegra210-mvc - const: nvidia,tegra210-mvc

View File

@ -28,6 +28,7 @@ properties:
- const: nvidia,tegra210-sfc - const: nvidia,tegra210-sfc
- items: - items:
- enum: - enum:
- nvidia,tegra234-sfc
- nvidia,tegra194-sfc - nvidia,tegra194-sfc
- nvidia,tegra186-sfc - nvidia,tegra186-sfc
- const: nvidia,tegra210-sfc - const: nvidia,tegra210-sfc

View File

@ -22,35 +22,41 @@ properties:
- qcom,lpass-cpu - qcom,lpass-cpu
- qcom,apq8016-lpass-cpu - qcom,apq8016-lpass-cpu
- qcom,sc7180-lpass-cpu - qcom,sc7180-lpass-cpu
- qcom,sc7280-lpass-cpu
reg: reg:
maxItems: 2 minItems: 2
maxItems: 6
description: LPAIF core registers description: LPAIF core registers
reg-names: reg-names:
maxItems: 2 minItems: 2
maxItems: 6
clocks: clocks:
minItems: 3 minItems: 3
maxItems: 6 maxItems: 7
clock-names: clock-names:
minItems: 3 minItems: 3
maxItems: 6 maxItems: 7
interrupts: interrupts:
maxItems: 2 minItems: 2
maxItems: 4
description: LPAIF DMA buffer interrupt description: LPAIF DMA buffer interrupt
interrupt-names: interrupt-names:
maxItems: 2 minItems: 2
maxItems: 4
qcom,adsp: qcom,adsp:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: Phandle for the audio DSP node description: Phandle for the audio DSP node
iommus: iommus:
maxItems: 2 minItems: 2
maxItems: 3
description: Phandle to apps_smmu node with sid mask description: Phandle to apps_smmu node with sid mask
power-domains: power-domains:
@ -69,7 +75,7 @@ patternProperties:
"^dai-link@[0-9a-f]$": "^dai-link@[0-9a-f]$":
type: object type: object
description: | description: |
LPASS CPU dai node for each I2S device. Bindings of each node LPASS CPU dai node for each I2S device or Soundwire device. Bindings of each node
depends on the specific driver providing the functionality and depends on the specific driver providing the functionality and
properties. properties.
properties: properties:
@ -174,6 +180,59 @@ allOf:
- iommus - iommus
- power-domains - power-domains
- if:
properties:
compatible:
contains:
const: qcom,sc7280-lpass-cpu
then:
properties:
clock-names:
oneOf:
- items: #for I2S
- const: aon_cc_audio_hm_h
- const: core_cc_sysnoc_mport_core
- const: core_cc_ext_if1_ibit
- items: #for Soundwire
- const: aon_cc_audio_hm_h
- const: audio_cc_codec_mem0
- const: audio_cc_codec_mem1
- const: audio_cc_codec_mem2
- items: #for HDMI
- const: aon_cc_audio_hm_h
reg-names:
anyOf:
- items: #for I2S
- const: lpass-lpaif
- items: #for I2S and HDMI
- const: lpass-hdmiif
- const: lpass-lpaif
- items: #for I2S, soundwire and HDMI
- const: lpass-hdmiif
- const: lpass-lpaif
- const: lpass-rxtx-cdc-dma-lpm
- const: lpass-rxtx-lpaif
- const: lpass-va-lpaif
- const: lpass-va-cdc-dma-lpm
interrupt-names:
anyOf:
- items: #for I2S
- const: lpass-irq-lpaif
- items: #for I2S and HDMI
- const: lpass-irq-lpaif
- const: lpass-irq-hdmi
- items: #for I2S, soundwire and HDMI
- const: lpass-irq-lpaif
- const: lpass-irq-hdmi
- const: lpass-irq-vaif
- const: lpass-irq-rxtxif
required:
- iommus
- power-domains
examples: examples:
- | - |
#include <dt-bindings/sound/sc7180-lpass.h> #include <dt-bindings/sound/sc7180-lpass.h>

View File

@ -39,6 +39,14 @@ properties:
items: items:
- const: mclk - const: mclk
power-domains:
maxItems: 2
power-domain-names:
items:
- const: macro
- const: dcodec
required: required:
- compatible - compatible
- reg - reg

View File

@ -39,6 +39,14 @@ properties:
items: items:
- const: mclk - const: mclk
power-domains:
maxItems: 2
power-domain-names:
items:
- const: macro
- const: dcodec
qcom,dmic-sample-rate: qcom,dmic-sample-rate:
description: dmic sample rate description: dmic sample rate
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32

View File

@ -37,6 +37,14 @@ properties:
items: items:
- const: fsgen - const: fsgen
power-domains:
maxItems: 2
power-domain-names:
items:
- const: macro
- const: dcodec
qcom,dmic-sample-rate: qcom,dmic-sample-rate:
description: dmic sample rate description: dmic sample rate
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32

View File

@ -23,6 +23,10 @@ properties:
description: GPIO spec for reset line to use description: GPIO spec for reset line to use
maxItems: 1 maxItems: 1
us-euro-gpios:
description: GPIO spec for swapping gnd and mic segments
maxItems: 1
vdd-buck-supply: vdd-buck-supply:
description: A reference to the 1.8V buck supply description: A reference to the 1.8V buck supply

View File

@ -21,6 +21,7 @@ properties:
description: I2C address of the device. description: I2C address of the device.
interrupts: interrupts:
maxItems: 1
description: The CODEC's interrupt output. description: The CODEC's interrupt output.
realtek,dmic1-data-pin: realtek,dmic1-data-pin:
@ -94,7 +95,7 @@ required:
examples: examples:
- | - |
#include <dt-bindings/gpio/tegra-gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/irq.h>
i2c { i2c {
@ -104,10 +105,9 @@ examples:
codec@1a { codec@1a {
compatible = "realtek,rt5682s"; compatible = "realtek,rt5682s";
reg = <0x1a>; reg = <0x1a>;
interrupt-parent = <&gpio>; interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios = realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>; <&gpio 2 GPIO_ACTIVE_HIGH>;
realtek,dmic1-data-pin = <1>; realtek,dmic1-data-pin = <1>;
realtek,dmic1-clk-pin = <1>; realtek,dmic1-clk-pin = <1>;
realtek,jd-src = <1>; realtek,jd-src = <1>;

View File

@ -123,9 +123,7 @@ properties:
$ref: audio-graph-port.yaml# $ref: audio-graph-port.yaml#
unevaluatedProperties: false unevaluatedProperties: false
# use patternProperties to avoid naming "xxx,yyy" issue rcar_sound,dvc:
patternProperties:
"^rcar_sound,dvc$":
description: DVC subnode. description: DVC subnode.
type: object type: object
patternProperties: patternProperties:
@ -141,7 +139,7 @@ patternProperties:
- dma-names - dma-names
additionalProperties: false additionalProperties: false
"^rcar_sound,mix$": rcar_sound,mix:
description: MIX subnode. description: MIX subnode.
type: object type: object
patternProperties: patternProperties:
@ -150,7 +148,7 @@ patternProperties:
# no properties # no properties
additionalProperties: false additionalProperties: false
"^rcar_sound,ctu$": rcar_sound,ctu:
description: CTU subnode. description: CTU subnode.
type: object type: object
patternProperties: patternProperties:
@ -159,7 +157,7 @@ patternProperties:
# no properties # no properties
additionalProperties: false additionalProperties: false
"^rcar_sound,src$": rcar_sound,src:
description: SRC subnode. description: SRC subnode.
type: object type: object
patternProperties: patternProperties:
@ -182,7 +180,7 @@ patternProperties:
- dma-names - dma-names
additionalProperties: false additionalProperties: false
"^rcar_sound,ssiu$": rcar_sound,ssiu:
description: SSIU subnode. description: SSIU subnode.
type: object type: object
patternProperties: patternProperties:
@ -202,7 +200,7 @@ patternProperties:
- dma-names - dma-names
additionalProperties: false additionalProperties: false
"^rcar_sound,ssi$": rcar_sound,ssi:
description: SSI subnode. description: SSI subnode.
type: object type: object
patternProperties: patternProperties:
@ -239,7 +237,7 @@ patternProperties:
additionalProperties: false additionalProperties: false
# For DAI base # For DAI base
"^rcar_sound,dai$": rcar_sound,dai:
description: DAI subnode. description: DAI subnode.
type: object type: object
patternProperties: patternProperties:

View File

@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/sound/renesas,rz-ssi.yaml# $id: http://devicetree.org/schemas/sound/renesas,rz-ssi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/G2L ASoC Sound Serial Interface (SSIF-2) title: Renesas RZ/{G2L,V2L} ASoC Sound Serial Interface (SSIF-2)
maintainers: maintainers:
- Biju Das <biju.das.jz@bp.renesas.com> - Biju Das <biju.das.jz@bp.renesas.com>
@ -14,6 +14,7 @@ properties:
items: items:
- enum: - enum:
- renesas,r9a07g044-ssi # RZ/G2{L,LC} - renesas,r9a07g044-ssi # RZ/G2{L,LC}
- renesas,r9a07g054-ssi # RZ/V2L
- const: renesas,rz-ssi - const: renesas,rz-ssi
reg: reg:

View File

@ -31,6 +31,8 @@ properties:
description: | description: |
phandles to the I2S controller and bluetooth codec, phandles to the I2S controller and bluetooth codec,
in that order in that order
required:
- sound-dai
codec: codec:
type: object type: object
@ -38,6 +40,8 @@ properties:
sound-dai: sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
description: phandle to the WM8994 CODEC description: phandle to the WM8994 CODEC
required:
- sound-dai
samsung,audio-routing: samsung,audio-routing:
$ref: /schemas/types.yaml#/definitions/non-unique-string-array $ref: /schemas/types.yaml#/definitions/non-unique-string-array

View File

@ -0,0 +1,45 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/samsung,arndale.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Insignal Arndale boards audio complex
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
properties:
compatible:
enum:
- samsung,arndale-alc5631
- samsung,arndale-rt5631
- samsung,arndale-wm1811
samsung,audio-codec:
description: Phandle to the audio codec.
$ref: /schemas/types.yaml#/definitions/phandle
samsung,audio-cpu:
description: Phandle to the Samsung I2S controller.
$ref: /schemas/types.yaml#/definitions/phandle
samsung,model:
description: The user-visible name of this sound complex.
$ref: /schemas/types.yaml#/definitions/string
required:
- compatible
- samsung,audio-codec
- samsung,audio-cpu
additionalProperties: false
examples:
- |
sound {
compatible = "samsung,arndale-rt5631";
samsung,audio-cpu = <&i2s0>;
samsung,audio-codec = <&rt5631>;
};

View File

@ -1,14 +0,0 @@
Samsung SMDK audio complex
Required properties:
- compatible : "samsung,smdk-wm8994"
- samsung,i2s-controller: The phandle of the Samsung I2S0 controller
- samsung,audio-codec: The phandle of the WM8994 audio codec
Example:
sound {
compatible = "samsung,smdk-wm8994";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&wm8994>;
};

View File

@ -0,0 +1,38 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/samsung,smdk5250.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung SMDK5250 audio complex with WM8994 codec
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
properties:
compatible:
const: samsung,smdk-wm8994
samsung,audio-codec:
description: Phandle to the audio codec.
$ref: /schemas/types.yaml#/definitions/phandle
samsung,i2s-controller:
description: Phandle to the Samsung I2S controller.
$ref: /schemas/types.yaml#/definitions/phandle
required:
- compatible
- samsung,audio-codec
- samsung,i2s-controller
additionalProperties: false
examples:
- |
sound {
compatible = "samsung,smdk-wm8994";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&wm8994>;
};

View File

@ -0,0 +1,74 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/samsung,snow.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Google Snow audio complex with MAX9809x codec
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
properties:
compatible:
enum:
- google,snow-audio-max98090
- google,snow-audio-max98091
- google,snow-audio-max98095
codec:
type: object
properties:
sound-dai:
description: List of phandles to the CODEC and HDMI IP nodes.
items:
- description: Phandle to the MAX98090, MAX98091 or MAX98095 CODEC.
- description: Phandle to the HDMI IP block node.
required:
- sound-dai
cpu:
type: object
properties:
sound-dai:
description: Phandle to the Samsung I2S controller.
maxItems: 1
required:
- sound-dai
samsung,audio-codec:
description: Phandle to the audio codec.
$ref: /schemas/types.yaml#/definitions/phandle
deprecated: true
samsung,i2s-controller:
description: Phandle to the Samsung I2S controller.
$ref: /schemas/types.yaml#/definitions/phandle
deprecated: true
samsung,model:
description: The user-visible name of this sound complex.
$ref: /schemas/types.yaml#/definitions/string
required:
- compatible
- codec
- cpu
additionalProperties: false
examples:
- |
sound {
compatible = "google,snow-audio-max98095";
samsung,model = "Snow-I2S-MAX98095";
cpu {
sound-dai = <&i2s0 0>;
};
codec {
sound-dai = <&max98095 0>, <&hdmi>;
};
};

View File

@ -1,42 +0,0 @@
Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
Required properties:
- compatible : "samsung,tm2-audio"
- model : the user-visible name of this sound complex
- audio-codec : the first entry should be phandle of the wm5110 audio
codec node, as described in ../mfd/arizona.txt;
the second entry should be phandle of the HDMI
transmitter node
- i2s-controller : the list of phandle and argument tuples pointing to
I2S controllers, the first entry should be I2S0 and
the second one I2S1
- audio-amplifier : the phandle of the MAX98504 amplifier
- samsung,audio-routing : a list of the connections between audio components;
each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
source; valid names for sources and sinks are the
WM5110's and MAX98504's pins and the jacks on the
board: HP, SPK, Main Mic, Sub Mic, Third Mic,
Headset Mic
- mic-bias-gpios : GPIO pin that enables the Main Mic bias regulator
Example:
sound {
compatible = "samsung,tm2-audio";
audio-codec = <&wm5110>, <&hdmi>;
i2s-controller = <&i2s0 0>, <&i2s1 0>;
audio-amplifier = <&max98504>;
mic-bias-gpios = <&gpr3 2 0>;
model = "wm5110";
samsung,audio-routing =
"HP", "HPOUT1L",
"HP", "HPOUT1R",
"SPK", "SPKOUT",
"SPKOUT", "HPOUT2L",
"SPKOUT", "HPOUT2R",
"Main Mic", "MICBIAS2",
"IN1R", "Main Mic";
};

View File

@ -0,0 +1,80 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/samsung,tm2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
properties:
compatible:
const: samsung,tm2-audio
audio-amplifier:
description: Phandle to the MAX98504 amplifier.
$ref: /schemas/types.yaml#/definitions/phandle
audio-codec:
description: Phandles to the codecs.
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- description: Phandle to the WM5110 audio codec.
- description: Phandle to the HDMI transmitter node.
samsung,audio-routing:
description: |
List of the connections between audio components; each entry is
a pair of strings, the first being the connection's sink, the second
being the connection's source; valid names for sources and sinks are the
WM5110's and MAX98504's pins and the jacks on the board: HP, SPK, Main
Mic, Sub Mic, Third Mic, Headset Mic.
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
i2s-controller:
description: Phandles to the I2S controllers.
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- description: Phandle to I2S0.
- description: Phandle to I2S1.
mic-bias-gpios:
description: GPIO pin that enables the Main Mic bias regulator.
model:
description: The user-visible name of this sound complex.
$ref: /schemas/types.yaml#/definitions/string
required:
- compatible
- audio-amplifier
- audio-codec
- samsung,audio-routing
- i2s-controller
- mic-bias-gpios
- model
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
sound {
compatible = "samsung,tm2-audio";
audio-codec = <&wm5110>, <&hdmi>;
i2s-controller = <&i2s0 0>, <&i2s1 0>;
audio-amplifier = <&max98504>;
mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
model = "wm5110";
samsung,audio-routing = "HP", "HPOUT1L",
"HP", "HPOUT1R",
"SPK", "SPKOUT",
"SPKOUT", "HPOUT2L",
"SPKOUT", "HPOUT2R",
"RCV", "HPOUT3L",
"RCV", "HPOUT3R";
};

View File

@ -48,6 +48,15 @@ definitions:
It is useful for some aCPUs with fixed clocks. It is useful for some aCPUs with fixed clocks.
$ref: /schemas/types.yaml#/definitions/flag $ref: /schemas/types.yaml#/definitions/flag
system-clock-fixed:
description: |
Specifies that the clock frequency should not be modified.
Implied when system-clock-frequency is specified, but can be used when
a clock is mapped to the device whose frequency cannot or should not be
changed. When mclk-fs is also specified, this restricts the device to a
single fixed sampling rate.
$ref: /schemas/types.yaml#/definitions/flag
mclk-fs: mclk-fs:
description: | description: |
Multiplication factor between stream rate and codec mclk. Multiplication factor between stream rate and codec mclk.
@ -134,6 +143,8 @@ definitions:
$ref: "#/definitions/system-clock-frequency" $ref: "#/definitions/system-clock-frequency"
system-clock-direction-out: system-clock-direction-out:
$ref: "#/definitions/system-clock-direction-out" $ref: "#/definitions/system-clock-direction-out"
system-clock-fixed:
$ref: "#/definitions/system-clock-fixed"
required: required:
- sound-dai - sound-dai
@ -156,45 +167,45 @@ properties:
description: User specified audio sound card name. description: User specified audio sound card name.
$ref: /schemas/types.yaml#/definitions/string $ref: /schemas/types.yaml#/definitions/string
# use patternProperties to avoid naming "xxx,yyy" issue simple-audio-card,widgets:
patternProperties:
"^simple-audio-card,widgets$":
$ref: "#/definitions/widgets" $ref: "#/definitions/widgets"
"^simple-audio-card,routing$": simple-audio-card,routing:
$ref: "#/definitions/routing" $ref: "#/definitions/routing"
"^simple-audio-card,cpu(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
"^simple-audio-card,codec(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
# common properties # common properties
"^simple-audio-card,frame-master$": simple-audio-card,frame-master:
$ref: "#/definitions/frame-master" $ref: "#/definitions/frame-master"
"^simple-audio-card,bitclock-master$": simple-audio-card,bitclock-master:
$ref: "#/definitions/bitclock-master" $ref: "#/definitions/bitclock-master"
"^simple-audio-card,frame-inversion$": simple-audio-card,frame-inversion:
$ref: "#/definitions/frame-inversion" $ref: "#/definitions/frame-inversion"
"^simple-audio-card,bitclock-inversion$": simple-audio-card,bitclock-inversion:
$ref: "#/definitions/bitclock-inversion" $ref: "#/definitions/bitclock-inversion"
"^simple-audio-card,format$": simple-audio-card,format:
$ref: "#/definitions/format" $ref: "#/definitions/format"
"^simple-audio-card,mclk-fs$": simple-audio-card,mclk-fs:
$ref: "#/definitions/mclk-fs" $ref: "#/definitions/mclk-fs"
"^simple-audio-card,aux-devs$": simple-audio-card,aux-devs:
$ref: "#/definitions/aux-devs" $ref: "#/definitions/aux-devs"
"^simple-audio-card,convert-rate$": simple-audio-card,convert-rate:
$ref: "#/definitions/convert-rate" $ref: "#/definitions/convert-rate"
"^simple-audio-card,convert-channels$": simple-audio-card,convert-channels:
$ref: "#/definitions/convert-channels" $ref: "#/definitions/convert-channels"
"^simple-audio-card,prefix$": simple-audio-card,prefix:
$ref: "#/definitions/prefix" $ref: "#/definitions/prefix"
"^simple-audio-card,pin-switches$": simple-audio-card,pin-switches:
$ref: "#/definitions/pin-switches" $ref: "#/definitions/pin-switches"
"^simple-audio-card,hp-det-gpio$": simple-audio-card,hp-det-gpio:
maxItems: 1 maxItems: 1
"^simple-audio-card,mic-det-gpio$": simple-audio-card,mic-det-gpio:
maxItems: 1 maxItems: 1
patternProperties:
"^simple-audio-card,cpu(@[0-9a-f]+)?$":
$ref: "#/definitions/dai"
"^simple-audio-card,codec(@[0-9a-f]+)?$":
$ref: "#/definitions/dai"
"^simple-audio-card,dai-link(@[0-9a-f]+)?$": "^simple-audio-card,dai-link(@[0-9a-f]+)?$":
description: | description: |
Container for dai-link level properties and the CPU and CODEC sub-nodes. Container for dai-link level properties and the CPU and CODEC sub-nodes.

View File

@ -1,31 +0,0 @@
Audio Binding for Snow boards
Required properties:
- compatible : Can be one of the following,
"google,snow-audio-max98090" or
"google,snow-audio-max98091" or
"google,snow-audio-max98095"
- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller
- samsung,audio-codec (deprecated): The phandle of the audio codec
Required sub-nodes:
- 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
controller
- 'codec' subnode with a 'sound-dai' property containing list of phandles
to the CODEC nodes, first entry must be the phandle of the MAX98090,
MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible
string) and the second entry must be the phandle of the HDMI IP block node
Optional:
- samsung,model: The name of the sound-card
Example:
sound {
compatible = "google,snow-audio-max98095";
samsung,model = "Snow-I2S-MAX98095";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&max98095>;
};

View File

@ -0,0 +1,56 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/tas5805m.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TAS5805M audio amplifier
maintainers:
- Daniel Beer <daniel.beer@igorinstitute.com>
description: |
The TAS5805M is a class D audio amplifier with a built-in DSP.
properties:
compatible:
enum:
- ti,tas5805m
reg:
maxItems: 1
description: |
I2C address of the amplifier. See the datasheet for possible values.
pvdd-supply:
description: |
Regulator for audio power supply (PVDD in the datasheet).
pdn-gpios:
description: |
Power-down control GPIO (PDN pin in the datasheet).
ti,dsp-config-name:
description: |
The name of the DSP configuration that should be loaded for this
instance. Configuration blobs are sequences of register writes
generated from TI's PPC3 tool.
$ref: /schemas/types.yaml#/definitions/string
examples:
- |
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
tas5805m: tas5805m@2c {
reg = <0x2c>;
compatible = "ti,tas5805m";
pvdd-supply = <&audiopwr>;
pdn-gpios = <&tlmm 160 0>;
ti,dsp-config-name = "mono_pbtl_48khz";
};
};
additionalProperties: true

View File

@ -58,7 +58,7 @@ The pins can be used in referring sound node's audio-routing property.
Example: Example:
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/sound/tlv320aic31xx-micbias.h> #include <dt-bindings/sound/tlv320aic31xx.h>
tlv320aic31xx: tlv320aic31xx@18 { tlv320aic31xx: tlv320aic31xx@18 {
compatible = "ti,tlv320aic311x"; compatible = "ti,tlv320aic311x";

View File

@ -7779,10 +7779,10 @@ F: drivers/net/ethernet/freescale/fs_enet/
F: include/linux/fs_enet_pd.h F: include/linux/fs_enet_pd.h
FREESCALE SOC SOUND DRIVERS FREESCALE SOC SOUND DRIVERS
M: Nicolin Chen <nicoleotsuka@gmail.com> M: Shengjiu Wang <shengjiu.wang@gmail.com>
M: Xiubo Li <Xiubo.Lee@gmail.com> M: Xiubo Li <Xiubo.Lee@gmail.com>
R: Fabio Estevam <festevam@gmail.com> R: Fabio Estevam <festevam@gmail.com>
R: Shengjiu Wang <shengjiu.wang@gmail.com> R: Nicolin Chen <nicoleotsuka@gmail.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
S: Maintained S: Maintained
@ -19043,6 +19043,7 @@ TEXAS INSTRUMENTS ASoC DRIVERS
M: Peter Ujfalusi <peter.ujfalusi@gmail.com> M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
F: sound/soc/ti/ F: sound/soc/ti/
TEXAS INSTRUMENTS' DAC7612 DAC DRIVER TEXAS INSTRUMENTS' DAC7612 DAC DRIVER

View File

@ -11,7 +11,7 @@
#include <dt-bindings/pinctrl/am43xx.h> #include <dt-bindings/pinctrl/am43xx.h>
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h> #include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/sound/tlv320aic31xx-micbias.h> #include <dt-bindings/sound/tlv320aic31xx.h>
/ { / {
model = "TI AM43x EPOS EVM"; model = "TI AM43x EPOS EVM";

View File

@ -586,6 +586,13 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes)); return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
} }
static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
bool plugged)
{
if (dp->codec_dev)
dp->plugged_cb(dp->codec_dev, plugged);
}
static void cdn_dp_encoder_enable(struct drm_encoder *encoder) static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
{ {
struct cdn_dp_device *dp = encoder_to_dp(encoder); struct cdn_dp_device *dp = encoder_to_dp(encoder);
@ -641,6 +648,9 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret); DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
goto out; goto out;
} }
cdn_dp_audio_handle_plugged_change(dp, true);
out: out:
mutex_unlock(&dp->lock); mutex_unlock(&dp->lock);
} }
@ -651,6 +661,8 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
int ret; int ret;
mutex_lock(&dp->lock); mutex_lock(&dp->lock);
cdn_dp_audio_handle_plugged_change(dp, false);
if (dp->active) { if (dp->active) {
ret = cdn_dp_disable(dp); ret = cdn_dp_disable(dp);
if (ret) { if (ret) {
@ -846,11 +858,27 @@ static int cdn_dp_audio_get_eld(struct device *dev, void *data,
return 0; return 0;
} }
static int cdn_dp_audio_hook_plugged_cb(struct device *dev, void *data,
hdmi_codec_plugged_cb fn,
struct device *codec_dev)
{
struct cdn_dp_device *dp = dev_get_drvdata(dev);
mutex_lock(&dp->lock);
dp->plugged_cb = fn;
dp->codec_dev = codec_dev;
cdn_dp_audio_handle_plugged_change(dp, dp->connected);
mutex_unlock(&dp->lock);
return 0;
}
static const struct hdmi_codec_ops audio_codec_ops = { static const struct hdmi_codec_ops audio_codec_ops = {
.hw_params = cdn_dp_audio_hw_params, .hw_params = cdn_dp_audio_hw_params,
.audio_shutdown = cdn_dp_audio_shutdown, .audio_shutdown = cdn_dp_audio_shutdown,
.mute_stream = cdn_dp_audio_mute_stream, .mute_stream = cdn_dp_audio_mute_stream,
.get_eld = cdn_dp_audio_get_eld, .get_eld = cdn_dp_audio_get_eld,
.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
.no_capture_mute = 1, .no_capture_mute = 1,
}; };

View File

@ -10,6 +10,7 @@
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include <drm/drm_panel.h> #include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <sound/hdmi-codec.h>
#include "rockchip_drm_drv.h" #include "rockchip_drm_drv.h"
@ -101,5 +102,8 @@ struct cdn_dp_device {
u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 dpcd[DP_RECEIVER_CAP_SIZE];
bool sink_has_audio; bool sink_has_audio;
hdmi_codec_plugged_cb plugged_cb;
struct device *codec_dev;
}; };
#endif /* _CDN_DP_CORE_H */ #endif /* _CDN_DP_CORE_H */

View File

@ -59,7 +59,7 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
{ {
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"), DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"),
}, },
.driver_data = (void *)intel_tgl_bios, .driver_data = (void *)intel_tgl_bios,
}, },

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DT_BINDINGS_MICROCHIP_PDMC_H__
#define __DT_BINDINGS_MICROCHIP_PDMC_H__
/* PDM microphone's pin placement */
#define MCHP_PDMC_DS0 0
#define MCHP_PDMC_DS1 1
/* PDM microphone clock edge sampling */
#define MCHP_PDMC_CLK_POSITIVE 0
#define MCHP_PDMC_CLK_NEGATIVE 1
#endif /* __DT_BINDINGS_MICROCHIP_PDMC_H__ */

View File

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DT_TLV320AIC31XX_MICBIAS_H
#define __DT_TLV320AIC31XX_MICBIAS_H
#define MICBIAS_2_0V 1
#define MICBIAS_2_5V 2
#define MICBIAS_AVDDV 3
#endif /* __DT_TLV320AIC31XX_MICBIAS_H */

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DT_TLV320AIC31XX_H
#define __DT_TLV320AIC31XX_H
#define MICBIAS_2_0V 1
#define MICBIAS_2_5V 2
#define MICBIAS_AVDDV 3
#define PLL_CLKIN_MCLK 0x00
#define PLL_CLKIN_BCLK 0x01
#define PLL_CLKIN_GPIO1 0x02
#define PLL_CLKIN_DIN 0x03
#endif /* __DT_TLV320AIC31XX_H */

View File

@ -9,6 +9,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/timecounter.h> #include <linux/timecounter.h>
#include <sound/core.h> #include <sound/core.h>
@ -448,6 +449,8 @@ static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
#define snd_hdac_reg_writel(bus, addr, val) writel(val, addr) #define snd_hdac_reg_writel(bus, addr, val) writel(val, addr)
#define snd_hdac_reg_readl(bus, addr) readl(addr) #define snd_hdac_reg_readl(bus, addr) readl(addr)
#define snd_hdac_reg_writeq(bus, addr, val) writeq(val, addr)
#define snd_hdac_reg_readq(bus, addr) readq(addr)
/* /*
* macros for easy use * macros for easy use

View File

@ -2,6 +2,8 @@
#ifndef __SOUND_HDAUDIO_EXT_H #ifndef __SOUND_HDAUDIO_EXT_H
#define __SOUND_HDAUDIO_EXT_H #define __SOUND_HDAUDIO_EXT_H
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/iopoll.h>
#include <sound/hdaudio.h> #include <sound/hdaudio.h>
int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev, int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
@ -144,6 +146,54 @@ void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable);
writew(((readw(addr + reg) & ~(mask)) | (val)), \ writew(((readw(addr + reg) & ~(mask)) | (val)), \
addr + reg) addr + reg)
#define snd_hdac_adsp_writeb(chip, reg, value) \
snd_hdac_reg_writeb(chip, (chip)->dsp_ba + (reg), value)
#define snd_hdac_adsp_readb(chip, reg) \
snd_hdac_reg_readb(chip, (chip)->dsp_ba + (reg))
#define snd_hdac_adsp_writew(chip, reg, value) \
snd_hdac_reg_writew(chip, (chip)->dsp_ba + (reg), value)
#define snd_hdac_adsp_readw(chip, reg) \
snd_hdac_reg_readw(chip, (chip)->dsp_ba + (reg))
#define snd_hdac_adsp_writel(chip, reg, value) \
snd_hdac_reg_writel(chip, (chip)->dsp_ba + (reg), value)
#define snd_hdac_adsp_readl(chip, reg) \
snd_hdac_reg_readl(chip, (chip)->dsp_ba + (reg))
#define snd_hdac_adsp_writeq(chip, reg, value) \
snd_hdac_reg_writeq(chip, (chip)->dsp_ba + (reg), value)
#define snd_hdac_adsp_readq(chip, reg) \
snd_hdac_reg_readq(chip, (chip)->dsp_ba + (reg))
#define snd_hdac_adsp_updateb(chip, reg, mask, val) \
snd_hdac_adsp_writeb(chip, reg, \
(snd_hdac_adsp_readb(chip, reg) & ~(mask)) | (val))
#define snd_hdac_adsp_updatew(chip, reg, mask, val) \
snd_hdac_adsp_writew(chip, reg, \
(snd_hdac_adsp_readw(chip, reg) & ~(mask)) | (val))
#define snd_hdac_adsp_updatel(chip, reg, mask, val) \
snd_hdac_adsp_writel(chip, reg, \
(snd_hdac_adsp_readl(chip, reg) & ~(mask)) | (val))
#define snd_hdac_adsp_updateq(chip, reg, mask, val) \
snd_hdac_adsp_writeq(chip, reg, \
(snd_hdac_adsp_readq(chip, reg) & ~(mask)) | (val))
#define snd_hdac_adsp_readb_poll(chip, reg, val, cond, delay_us, timeout_us) \
readb_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
delay_us, timeout_us)
#define snd_hdac_adsp_readw_poll(chip, reg, val, cond, delay_us, timeout_us) \
readw_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
delay_us, timeout_us)
#define snd_hdac_adsp_readl_poll(chip, reg, val, cond, delay_us, timeout_us) \
readl_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
delay_us, timeout_us)
#define snd_hdac_adsp_readq_poll(chip, reg, val, cond, delay_us, timeout_us) \
readq_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
delay_us, timeout_us)
#define snd_hdac_stream_readb_poll(strm, reg, val, cond, delay_us, timeout_us) \
readb_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
delay_us, timeout_us)
#define snd_hdac_stream_readl_poll(strm, reg, val, cond, delay_us, timeout_us) \
readl_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
delay_us, timeout_us)
struct hdac_ext_device; struct hdac_ext_device;

View File

@ -18,6 +18,13 @@ enum nhlt_link_type {
NHLT_LINK_INVALID NHLT_LINK_INVALID
}; };
enum nhlt_device_type {
NHLT_DEVICE_BT = 0,
NHLT_DEVICE_DMIC = 1,
NHLT_DEVICE_I2S = 4,
NHLT_DEVICE_INVALID
};
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT) #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
struct wav_fmt { struct wav_fmt {
@ -41,13 +48,6 @@ struct wav_fmt_ext {
u8 sub_fmt[16]; u8 sub_fmt[16];
} __packed; } __packed;
enum nhlt_device_type {
NHLT_DEVICE_BT = 0,
NHLT_DEVICE_DMIC = 1,
NHLT_DEVICE_I2S = 4,
NHLT_DEVICE_INVALID
};
struct nhlt_specific_cfg { struct nhlt_specific_cfg {
u32 size; u32 size;
u8 caps[]; u8 caps[];
@ -133,6 +133,9 @@ void intel_nhlt_free(struct nhlt_acpi_table *addr);
int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt); int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt);
bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type); bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type);
int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type);
struct nhlt_specific_cfg * struct nhlt_specific_cfg *
intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
u32 bus_id, u8 link_type, u8 vbps, u8 bps, u32 bus_id, u8 link_type, u8 vbps, u8 bps,
@ -163,6 +166,11 @@ static inline bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt,
return false; return false;
} }
static inline int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type)
{
return 0;
}
static inline struct nhlt_specific_cfg * static inline struct nhlt_specific_cfg *
intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
u32 bus_id, u8 link_type, u8 vbps, u8 bps, u32 bus_id, u8 link_type, u8 vbps, u8 bps,

View File

@ -16,6 +16,12 @@
#define asoc_simple_init_mic(card, sjack, prefix) \ #define asoc_simple_init_mic(card, sjack, prefix) \
asoc_simple_init_jack(card, sjack, 0, prefix, NULL) asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
struct asoc_simple_tdm_width_map {
u8 sample_bits;
u8 slot_count;
u16 slot_width;
};
struct asoc_simple_dai { struct asoc_simple_dai {
const char *name; const char *name;
unsigned int sysclk; unsigned int sysclk;
@ -25,6 +31,9 @@ struct asoc_simple_dai {
unsigned int tx_slot_mask; unsigned int tx_slot_mask;
unsigned int rx_slot_mask; unsigned int rx_slot_mask;
struct clk *clk; struct clk *clk;
bool clk_fixed;
struct asoc_simple_tdm_width_map *tdm_width_map;
int n_tdm_widths;
}; };
struct asoc_simple_data { struct asoc_simple_data {
@ -131,6 +140,9 @@ int asoc_simple_parse_daifmt(struct device *dev,
struct device_node *codec, struct device_node *codec,
char *prefix, char *prefix,
unsigned int *retfmt); unsigned int *retfmt);
int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np,
struct asoc_simple_dai *dai);
__printf(3, 4) __printf(3, 4)
int asoc_simple_set_dailink_name(struct device *dev, int asoc_simple_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link, struct snd_soc_dai_link *dai_link,

View File

@ -60,9 +60,11 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* @acpi_ipc_irq_index: used for BYT-CR detection * @acpi_ipc_irq_index: used for BYT-CR detection
* @platform: string used for HDAudio codec support * @platform: string used for HDAudio codec support
* @codec_mask: used for HDAudio support * @codec_mask: used for HDAudio support
* @dmic_num: number of SoC- or chipset-attached PDM digital microphones
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver * @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
* @link_mask: links enabled on the board * @link_mask: SoundWire links enabled on the board
* @links: array of link _ADR descriptors, null terminated * @links: array of SoundWire link _ADR descriptors, null terminated
* @i2s_link_mask: I2S/TDM links enabled on the board
* @num_dai_drivers: number of elements in @dai_drivers * @num_dai_drivers: number of elements in @dai_drivers
* @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
*/ */
@ -74,6 +76,7 @@ struct snd_soc_acpi_mach_params {
bool common_hdmi_codec_drv; bool common_hdmi_codec_drv;
u32 link_mask; u32 link_mask;
const struct snd_soc_acpi_link_adr *links; const struct snd_soc_acpi_link_adr *links;
u32 i2s_link_mask;
u32 num_dai_drivers; u32 num_dai_drivers;
struct snd_soc_dai_driver *dai_drivers; struct snd_soc_dai_driver *dai_drivers;
}; };
@ -122,6 +125,24 @@ struct snd_soc_acpi_link_adr {
const struct snd_soc_acpi_adr_device *adr_d; const struct snd_soc_acpi_adr_device *adr_d;
}; };
/*
* when set the topology uses the -ssp<N> suffix, where N is determined based on
* BIOS or DMI information
*/
#define SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER BIT(0)
/*
* when more than one SSP is reported in the link mask, use the most significant.
* This choice was found to be valid on platforms with ES8336 codecs.
*/
#define SND_SOC_ACPI_TPLG_INTEL_SSP_MSB BIT(1)
/*
* when set the topology uses the -dmic<N>ch suffix, where N is determined based on
* BIOS or DMI information
*/
#define SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER BIT(2)
/** /**
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are * snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
* related to the hardware, except for the firmware and topology file names. * related to the hardware, except for the firmware and topology file names.
@ -142,8 +163,8 @@ struct snd_soc_acpi_link_adr {
* audio codecs whose presence if checked with ACPI * audio codecs whose presence if checked with ACPI
* @pdata: intended for platform data or machine specific-ops. This structure * @pdata: intended for platform data or machine specific-ops. This structure
* is not constant since this field may be updated at run-time * is not constant since this field may be updated at run-time
* @sof_fw_filename: Sound Open Firmware file name, if enabled
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled * @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
* @tplg_quirk_mask: quirks to select different topology files dynamically
*/ */
/* Descriptor for SST ASoC machine driver */ /* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach { struct snd_soc_acpi_mach {
@ -158,8 +179,8 @@ struct snd_soc_acpi_mach {
const void *quirk_data; const void *quirk_data;
void *pdata; void *pdata;
struct snd_soc_acpi_mach_params mach_params; struct snd_soc_acpi_mach_params mach_params;
const char *sof_fw_filename;
const char *sof_tplg_filename; const char *sof_tplg_filename;
const u32 tplg_quirk_mask;
}; };
#define SND_SOC_ACPI_MAX_CODECS 3 #define SND_SOC_ACPI_MAX_CODECS 3

View File

@ -429,6 +429,7 @@ struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(
const struct snd_soc_dapm_widget *widget); const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai); struct snd_soc_dai *dai);
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card); void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);

View File

@ -39,6 +39,14 @@ enum sof_fw_state {
SOF_FW_CRASHED, SOF_FW_CRASHED,
}; };
/* DSP power states */
enum sof_dsp_power_states {
SOF_DSP_PM_D0,
SOF_DSP_PM_D1,
SOF_DSP_PM_D2,
SOF_DSP_PM_D3,
};
/* /*
* SOF Platform data. * SOF Platform data.
*/ */

View File

@ -116,4 +116,9 @@ struct sof_ipc_dai_config {
}; };
} __packed; } __packed;
struct sof_dai_private_data {
struct sof_ipc_comp_dai *comp_dai;
struct sof_ipc_dai_config *dai_config;
};
#endif #endif

View File

@ -31,7 +31,7 @@
/* Global Message - Generic */ /* Global Message - Generic */
#define SOF_GLB_TYPE_SHIFT 28 #define SOF_GLB_TYPE_SHIFT 28
#define SOF_GLB_TYPE_MASK (0xfL << SOF_GLB_TYPE_SHIFT) #define SOF_GLB_TYPE_MASK (0xfUL << SOF_GLB_TYPE_SHIFT)
#define SOF_GLB_TYPE(x) ((x) << SOF_GLB_TYPE_SHIFT) #define SOF_GLB_TYPE(x) ((x) << SOF_GLB_TYPE_SHIFT)
/* Command Message - Generic */ /* Command Message - Generic */

View File

@ -25,6 +25,7 @@
#define SOF_IPC_INFO_LOCKS BIT(1) #define SOF_IPC_INFO_LOCKS BIT(1)
#define SOF_IPC_INFO_LOCKSV BIT(2) #define SOF_IPC_INFO_LOCKSV BIT(2)
#define SOF_IPC_INFO_GDB BIT(3) #define SOF_IPC_INFO_GDB BIT(3)
#define SOF_IPC_INFO_D3_PERSISTENT BIT(4)
/* extended data types that can be appended onto end of sof_ipc_fw_ready */ /* extended data types that can be appended onto end of sof_ipc_fw_ready */
enum sof_ipc_ext_data { enum sof_ipc_ext_data {

View File

@ -87,9 +87,6 @@ struct sof_ipc_comp {
*/ */
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1) #define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
/* the UUID size in bytes, shared between FW and host */
#define SOF_UUID_SIZE 16
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */ /* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
struct sof_ipc_buffer { struct sof_ipc_buffer {
struct sof_ipc_comp comp; struct sof_ipc_comp comp;
@ -237,7 +234,7 @@ struct sof_ipc_comp_process {
/* reserved for future use */ /* reserved for future use */
uint32_t reserved[7]; uint32_t reserved[7];
uint8_t data[0]; uint8_t data[];
} __packed; } __packed;
/* frees components, buffers and pipelines /* frees components, buffers and pipelines
@ -303,9 +300,4 @@ enum sof_event_types {
SOF_KEYWORD_DETECT_DAPM_EVENT, SOF_KEYWORD_DETECT_DAPM_EVENT,
}; };
/* extended data struct for UUID components */
struct sof_ipc_comp_ext {
uint8_t uuid[SOF_UUID_SIZE];
} __packed;
#endif #endif

View File

@ -26,8 +26,8 @@
/* SOF ABI version major, minor and patch numbers */ /* SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3 #define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 18 #define SOF_ABI_MINOR 19
#define SOF_ABI_PATCH 0 #define SOF_ABI_PATCH 1
/* SOF ABI version number. Format within 32bit word is MMmmmppp */ /* SOF ABI version number. Format within 32bit word is MMmmmppp */
#define SOF_ABI_MAJOR_SHIFT 24 #define SOF_ABI_MAJOR_SHIFT 24

View File

@ -11,6 +11,7 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/intel-dsp-config.h> #include <sound/intel-dsp-config.h>
#include <sound/intel-nhlt.h> #include <sound/intel-nhlt.h>
#include <sound/soc-acpi.h>
static int dsp_driver; static int dsp_driver;
@ -31,7 +32,12 @@ struct config_entry {
u16 device; u16 device;
u8 acpi_hid[ACPI_ID_LEN]; u8 acpi_hid[ACPI_ID_LEN];
const struct dmi_system_id *dmi_table; const struct dmi_system_id *dmi_table;
u8 codec_hid[ACPI_ID_LEN]; const struct snd_soc_acpi_codecs *codec_hid;
};
static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
.num_codecs = 3,
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
}; };
/* /*
@ -77,7 +83,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0x5a98, .device = 0x5a98,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
#endif #endif
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
@ -163,7 +169,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0x3198, .device = 0x3198,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
#endif #endif
@ -193,6 +199,11 @@ static const struct config_entry config_table[] = {
{} {}
} }
}, },
{
.flags = FLAG_SOF,
.device = 0x09dc8,
.codec_hid = &essx_83x6,
},
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x9dc8, .device = 0x9dc8,
@ -251,7 +262,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0x02c8, .device = 0x02c8,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
@ -280,7 +291,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0x06c8, .device = 0x06c8,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
@ -327,7 +338,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0x4dc8, .device = 0x4dc8,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
@ -353,7 +364,7 @@ static const struct config_entry config_table[] = {
{ {
.flags = FLAG_SOF, .flags = FLAG_SOF,
.device = 0xa0c8, .device = 0xa0c8,
.codec_hid = "ESSX8336", .codec_hid = &essx_83x6,
}, },
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
@ -414,8 +425,15 @@ static const struct config_entry *snd_intel_dsp_find_config
continue; continue;
if (table->dmi_table && !dmi_check_system(table->dmi_table)) if (table->dmi_table && !dmi_check_system(table->dmi_table))
continue; continue;
if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1)) if (table->codec_hid) {
continue; int i;
for (i = 0; i < table->codec_hid->num_codecs; i++)
if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
break;
if (i == table->codec_hid->num_codecs)
continue;
}
return table; return table;
} }
return NULL; return NULL;

View File

@ -130,6 +130,28 @@ bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type)
} }
EXPORT_SYMBOL(intel_nhlt_has_endpoint_type); EXPORT_SYMBOL(intel_nhlt_has_endpoint_type);
int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type)
{
struct nhlt_endpoint *epnt;
int ssp_mask = 0;
int i;
if (!nhlt || (device_type != NHLT_DEVICE_BT && device_type != NHLT_DEVICE_I2S))
return 0;
epnt = (struct nhlt_endpoint *)nhlt->desc;
for (i = 0; i < nhlt->endpoint_count; i++) {
if (epnt->linktype == NHLT_LINK_SSP && epnt->device_type == device_type) {
/* for SSP the virtual bus id is the SSP port */
ssp_mask |= BIT(epnt->virtual_bus_id);
}
epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
}
return ssp_mask;
}
EXPORT_SYMBOL(intel_nhlt_ssp_endpoint_mask);
static struct nhlt_specific_cfg * static struct nhlt_specific_cfg *
nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch,
u32 rate, u8 vbps, u8 bps) u32 rate, u8 vbps, u8 bps)

View File

@ -44,6 +44,7 @@ config SND_SOC_AMD_RV_RT5682_MACH
config SND_SOC_AMD_RENOIR config SND_SOC_AMD_RENOIR
tristate "AMD Audio Coprocessor - Renoir support" tristate "AMD Audio Coprocessor - Renoir support"
select SND_AMD_ACP_CONFIG
depends on X86 && PCI depends on X86 && PCI
help help
This option enables ACP support for Renoir platform This option enables ACP support for Renoir platform

View File

@ -110,6 +110,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = {
.fw_filename = "sof-rn.ri", .fw_filename = "sof-rn.ri",
.sof_tplg_filename = "sof-rn-rt5682-max98360.tplg", .sof_tplg_filename = "sof-rn-rt5682-max98360.tplg",
}, },
{
.id = "RTL5682",
.drv_name = "rt5682s-rt1019",
.pdata = (void *)&acp_quirk_data,
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &amp_rt1019,
.fw_filename = "sof-rn.ri",
.sof_tplg_filename = "sof-rn-rt5682-rt1019.tplg",
},
{ {
.id = "AMDI1019", .id = "AMDI1019",
.drv_name = "renoir-dsp", .drv_name = "renoir-dsp",

View File

@ -1217,9 +1217,8 @@ static const struct snd_soc_component_driver acp_asoc_platform = {
static int acp_audio_probe(struct platform_device *pdev) static int acp_audio_probe(struct platform_device *pdev)
{ {
int status; int status, irq;
struct audio_drv_data *audio_drv_data; struct audio_drv_data *audio_drv_data;
struct resource *res;
const u32 *pdata = pdev->dev.platform_data; const u32 *pdata = pdev->dev.platform_data;
if (!pdata) { if (!pdata) {
@ -1249,13 +1248,11 @@ static int acp_audio_probe(struct platform_device *pdev)
audio_drv_data->asic_type = *pdata; audio_drv_data->asic_type = *pdata;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq = platform_get_irq(pdev, 0);
if (!res) { if (irq < 0)
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
return -ENODEV; return -ENODEV;
}
status = devm_request_irq(&pdev->dev, res->start, dma_irq_handler, status = devm_request_irq(&pdev->dev, irq, dma_irq_handler,
0, "ACP_IRQ", &pdev->dev); 0, "ACP_IRQ", &pdev->dev);
if (status) { if (status) {
dev_err(&pdev->dev, "ACP IRQ request failed\n"); dev_err(&pdev->dev, "ACP IRQ request failed\n");

View File

@ -15,6 +15,9 @@ config SND_SOC_AMD_ACP_COMMON
if SND_SOC_AMD_ACP_COMMON if SND_SOC_AMD_ACP_COMMON
config SND_SOC_AMD_ACP_PDM
tristate
config SND_SOC_AMD_ACP_I2S config SND_SOC_AMD_ACP_I2S
tristate tristate
@ -22,10 +25,17 @@ config SND_SOC_AMD_ACP_PCM
tristate tristate
select SND_SOC_ACPI if ACPI select SND_SOC_ACPI if ACPI
config SND_SOC_AMD_ACP_PCI
tristate "AMD ACP PCI Driver Support"
depends on X86 && PCI
help
This options enables generic PCI driver for ACP device.
config SND_AMD_ASOC_RENOIR config SND_AMD_ASOC_RENOIR
tristate "AMD ACP ASOC Renoir Support" tristate "AMD ACP ASOC Renoir Support"
select SND_SOC_AMD_ACP_PCM select SND_SOC_AMD_ACP_PCM
select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_I2S
select SND_SOC_AMD_ACP_PDM
depends on X86 && PCI depends on X86 && PCI
help help
This option enables Renoir I2S support on AMD platform. This option enables Renoir I2S support on AMD platform.

View File

@ -7,6 +7,8 @@
#common acp driver #common acp driver
snd-acp-pcm-objs := acp-platform.o snd-acp-pcm-objs := acp-platform.o
snd-acp-i2s-objs := acp-i2s.o snd-acp-i2s-objs := acp-i2s.o
snd-acp-pdm-objs := acp-pdm.o
snd-acp-pci-objs := acp-pci.o
#platform specific driver #platform specific driver
snd-acp-renoir-objs := acp-renoir.o snd-acp-renoir-objs := acp-renoir.o
@ -18,6 +20,8 @@ snd-acp-sof-mach-objs := acp-sof-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o
obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o
obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o

View File

@ -23,13 +23,33 @@
static struct acp_card_drvdata rt5682_rt1019_data = { static struct acp_card_drvdata rt5682_rt1019_data = {
.hs_cpu_id = I2S_SP, .hs_cpu_id = I2S_SP,
.amp_cpu_id = I2S_SP, .amp_cpu_id = I2S_SP,
.dmic_cpu_id = NONE, .dmic_cpu_id = DMIC,
.hs_codec_id = RT5682, .hs_codec_id = RT5682,
.amp_codec_id = RT1019, .amp_codec_id = RT1019,
.dmic_codec_id = NONE, .dmic_codec_id = DMIC,
.gpio_spkr_en = EN_SPKR_GPIO_GB, .gpio_spkr_en = EN_SPKR_GPIO_GB,
}; };
static struct acp_card_drvdata rt5682s_max_data = {
.hs_cpu_id = I2S_SP,
.amp_cpu_id = I2S_SP,
.dmic_cpu_id = DMIC,
.hs_codec_id = RT5682S,
.amp_codec_id = MAX98360A,
.dmic_codec_id = DMIC,
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
};
static struct acp_card_drvdata rt5682s_rt1019_data = {
.hs_cpu_id = I2S_SP,
.amp_cpu_id = I2S_SP,
.dmic_cpu_id = DMIC,
.hs_codec_id = RT5682S,
.amp_codec_id = RT1019,
.dmic_codec_id = DMIC,
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
};
static const struct snd_kcontrol_new acp_controls[] = { static const struct snd_kcontrol_new acp_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Headset Mic"),
@ -96,9 +116,17 @@ static int acp_asoc_probe(struct platform_device *pdev)
static const struct platform_device_id board_ids[] = { static const struct platform_device_id board_ids[] = {
{ {
.name = "rn_rt5682_rt1019", .name = "acp3xalc56821019",
.driver_data = (kernel_ulong_t)&rt5682_rt1019_data, .driver_data = (kernel_ulong_t)&rt5682_rt1019_data,
}, },
{
.name = "acp3xalc5682sm98360",
.driver_data = (kernel_ulong_t)&rt5682s_max_data,
},
{
.name = "acp3xalc5682s1019",
.driver_data = (kernel_ulong_t)&rt5682s_rt1019_data,
},
{ } { }
}; };
static struct platform_driver acp_asoc_audio = { static struct platform_driver acp_asoc_audio = {
@ -113,5 +141,7 @@ module_platform_driver(acp_asoc_audio);
MODULE_IMPORT_NS(SND_SOC_AMD_MACH); MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
MODULE_DESCRIPTION("ACP chrome audio support"); MODULE_DESCRIPTION("ACP chrome audio support");
MODULE_ALIAS("platform:rn_rt5682_rt1019"); MODULE_ALIAS("platform:acp3xalc56821019");
MODULE_ALIAS("platform:acp3xalc5682sm98360");
MODULE_ALIAS("platform:acp3xalc5682s1019");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -291,6 +291,32 @@ static const struct snd_soc_ops acp_card_rt5682s_ops = {
.shutdown = acp_card_shutdown, .shutdown = acp_card_shutdown,
}; };
static const unsigned int dmic_channels[] = {
DUAL_CHANNEL, FOUR_CHANNEL,
};
static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
.count = ARRAY_SIZE(dmic_channels),
.list = dmic_channels,
.mask = 0,
};
static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&dmic_constraints_channels);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&constraints_rates);
return 0;
}
static const struct snd_soc_ops acp_card_dmic_ops = {
.startup = acp_card_dmic_startup,
};
/* Declare RT1019 codec components */ /* Declare RT1019 codec components */
SND_SOC_DAILINK_DEF(rt1019, SND_SOC_DAILINK_DEF(rt1019,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
@ -438,6 +464,8 @@ SND_SOC_DAILINK_DEF(sof_sp,
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp"))); DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
SND_SOC_DAILINK_DEF(sof_dmic, SND_SOC_DAILINK_DEF(sof_dmic,
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic"))); DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
SND_SOC_DAILINK_DEF(pdm_dmic,
DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
int acp_sofdsp_dai_links_create(struct snd_soc_card *card) int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
{ {
@ -556,6 +584,8 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
num_links++; num_links++;
links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * num_links, GFP_KERNEL); links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * num_links, GFP_KERNEL);
if (!links)
return -ENOMEM;
if (drv_data->hs_cpu_id == I2S_SP) { if (drv_data->hs_cpu_id == I2S_SP) {
links[i].name = "acp-headset-codec"; links[i].name = "acp-headset-codec";
@ -613,6 +643,26 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
links[i].ops = &acp_card_maxim_ops; links[i].ops = &acp_card_maxim_ops;
links[i].init = acp_card_maxim_init; links[i].init = acp_card_maxim_init;
} }
i++;
}
if (drv_data->dmic_cpu_id == DMIC) {
links[i].name = "acp-dmic-codec";
links[i].id = DMIC_BE_ID;
if (drv_data->dmic_codec_id == DMIC) {
links[i].codecs = dmic_codec;
links[i].num_codecs = ARRAY_SIZE(dmic_codec);
} else {
/* Use dummy codec if codec id not specified */
links[i].codecs = dummy_codec;
links[i].num_codecs = ARRAY_SIZE(dummy_codec);
}
links[i].cpus = pdm_dmic;
links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
links[i].platforms = platform_component;
links[i].num_platforms = ARRAY_SIZE(platform_component);
links[i].ops = &acp_card_dmic_ops;
links[i].dpcm_capture = 1;
} }
card->dai_link = links; card->dai_link = links;

160
sound/soc/amd/acp/acp-pci.c Normal file
View File

@ -0,0 +1,160 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
/*
* Generic PCI interface for ACP device
*/
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "amd.h"
#include "../mach-config.h"
#define DRV_NAME "acp_pci"
#define ACP3x_REG_START 0x1240000
#define ACP3x_REG_END 0x125C000
static struct platform_device *dmic_dev;
static struct platform_device *pdev;
static const struct resource acp3x_res[] = {
{
.start = 0,
.end = ACP3x_REG_END - ACP3x_REG_START,
.name = "acp_mem",
.flags = IORESOURCE_MEM,
},
{
.start = 0,
.end = 0,
.name = "acp_dai_irq",
.flags = IORESOURCE_IRQ,
},
};
static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
struct platform_device_info pdevinfo;
struct device *dev = &pci->dev;
const struct resource *res_acp;
struct acp_chip_info *chip;
struct resource *res;
unsigned int flag, addr, num_res, i;
int ret;
flag = snd_amd_acp_find_config(pci);
if (flag != FLAG_AMD_LEGACY)
return -ENODEV;
chip = devm_kzalloc(&pci->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
if (pci_enable_device(pci)) {
dev_err(&pci->dev, "pci_enable_device failed\n");
return -ENODEV;
}
ret = pci_request_regions(pci, "AMD ACP3x audio");
if (ret < 0) {
dev_err(&pci->dev, "pci_request_regions failed\n");
return -ENOMEM;
}
pci_set_master(pci);
switch (pci->revision) {
case 0x01:
res_acp = acp3x_res;
num_res = ARRAY_SIZE(acp3x_res);
chip->name = "acp_asoc_renoir";
chip->acp_rev = ACP3X_DEV;
break;
default:
dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision);
return -EINVAL;
}
dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0);
if (IS_ERR(dmic_dev)) {
dev_err(dev, "failed to create DMIC device\n");
return PTR_ERR(dmic_dev);
}
addr = pci_resource_start(pci, 0);
chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
res = devm_kzalloc(&pci->dev, sizeof(struct resource) * num_res, GFP_KERNEL);
if (!res) {
platform_device_unregister(dmic_dev);
return -ENOMEM;
}
for (i = 0; i < num_res; i++, res_acp++) {
res[i].name = res_acp->name;
res[i].flags = res_acp->flags;
res[i].start = addr + res_acp->start;
res[i].end = addr + res_acp->end;
if (res_acp->flags == IORESOURCE_IRQ) {
res[i].start = pci->irq;
res[i].end = res[i].start;
}
}
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.name = chip->name;
pdevinfo.id = 0;
pdevinfo.parent = &pci->dev;
pdevinfo.num_res = num_res;
pdevinfo.res = &res[0];
pdevinfo.data = chip;
pdevinfo.size_data = sizeof(*chip);
pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(pdev)) {
dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name);
platform_device_unregister(dmic_dev);
ret = PTR_ERR(pdev);
}
return ret;
};
static void acp_pci_remove(struct pci_dev *pci)
{
if (dmic_dev)
platform_device_unregister(dmic_dev);
if (pdev)
platform_device_unregister(pdev);
}
/* PCI IDs */
static const struct pci_device_id acp_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_PCI_DEV_ID)},
{ 0, }
};
MODULE_DEVICE_TABLE(pci, acp_pci_ids);
/* pci_driver definition */
static struct pci_driver snd_amd_acp_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = acp_pci_ids,
.probe = acp_pci_probe,
.remove = acp_pci_remove,
};
module_pci_driver(snd_amd_acp_pci_driver);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS(DRV_NAME);

193
sound/soc/amd/acp/acp-pdm.c Normal file
View File

@ -0,0 +1,193 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2022 Advanced Micro Devices, Inc.
//
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
// Vijendar Mukunda <Vijendar.Mukunda@amd.com>
//
/*
* Generic Hardware interface for ACP Audio PDM controller
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
#include "amd.h"
#define DRV_NAME "acp-pdm"
#define PDM_DMA_STAT 0x10
#define PDM_DMA_INTR_MASK 0x10000
#define PDM_DEC_64 0x2
#define PDM_CLK_FREQ_MASK 0x07
#define PDM_MISC_CTRL_MASK 0x10
#define PDM_ENABLE 0x01
#define PDM_DISABLE 0x00
#define DMA_EN_MASK 0x02
#define DELAY_US 5
#define PDM_TIMEOUT 1000
#define ACP_REGION2_OFFSET 0x02000000
static int acp_dmic_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
u32 physical_addr, size_dmic, period_bytes;
unsigned int dmic_ctrl;
/* Enable default DMIC clk */
writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
dmic_ctrl |= PDM_MISC_CTRL_MASK;
writel(dmic_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL);
period_bytes = frames_to_bytes(substream->runtime,
substream->runtime->period_size);
size_dmic = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
physical_addr = stream->reg_offset + MEM_WINDOW_START;
/* Init DMIC Ring buffer */
writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
writel(size_dmic, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE);
writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
return 0;
}
static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
unsigned int dma_enable;
int ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
if (!(dma_enable & DMA_EN_MASK)) {
writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_ENABLE);
writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
}
ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE,
dma_enable, (dma_enable & DMA_EN_MASK),
DELAY_US, PDM_TIMEOUT);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
if ((dma_enable & DMA_EN_MASK)) {
writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_ENABLE);
writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE);
}
ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE,
dma_enable, !(dma_enable & DMA_EN_MASK),
DELAY_US, PDM_TIMEOUT);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int acp_dmic_hwparams(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hwparams, struct snd_soc_dai *dai)
{
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
unsigned int channels, ch_mask;
channels = params_channels(hwparams);
switch (channels) {
case 2:
ch_mask = 0;
break;
case 4:
ch_mask = 1;
break;
case 6:
ch_mask = 2;
break;
default:
dev_err(dev, "Invalid channels %d\n", channels);
return -EINVAL;
}
if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) {
dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams));
return -EINVAL;
}
writel(ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
return 0;
}
static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
u32 ext_int_ctrl;
stream->dai_id = DMIC_INSTANCE;
stream->irq_bit = BIT(PDM_DMA_STAT);
stream->pte_offset = ACP_SRAM_PDM_PTE_OFFSET;
stream->reg_offset = ACP_REGION2_OFFSET;
/* Enable DMIC Interrupts */
ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
ext_int_ctrl |= PDM_DMA_INTR_MASK;
writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
return 0;
}
static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
u32 ext_int_ctrl;
/* Disable DMIC interrrupts */
ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL);
}
const struct snd_soc_dai_ops acp_dmic_dai_ops = {
.prepare = acp_dmic_prepare,
.hw_params = acp_dmic_hwparams,
.trigger = acp_dmic_dai_trigger,
.startup = acp_dmic_dai_startup,
.shutdown = acp_dmic_dai_shutdown,
};
EXPORT_SYMBOL_NS_GPL(acp_dmic_dai_ops, SND_SOC_ACP_COMMON);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS(DRV_NAME);

View File

@ -25,15 +25,46 @@
#define DRV_NAME "acp_asoc_renoir" #define DRV_NAME "acp_asoc_renoir"
#define ACP_SOFT_RST_DONE_MASK 0x00010001
#define ACP_PWR_ON_MASK 0x01
#define ACP_PWR_OFF_MASK 0x00
#define ACP_PGFSM_STAT_MASK 0x03
#define ACP_POWERED_ON 0x00
#define ACP_PWR_ON_IN_PROGRESS 0x01
#define ACP_POWERED_OFF 0x02
#define DELAY_US 5
#define ACP_TIMEOUT 500
#define ACP_ERROR_MASK 0x20000000
#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
static struct snd_soc_acpi_codecs amp_rt1019 = { static struct snd_soc_acpi_codecs amp_rt1019 = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"10EC1019"} .codecs = {"10EC1019"}
}; };
static struct snd_soc_acpi_codecs amp_max = {
.num_codecs = 1,
.codecs = {"MX98360A"}
};
static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = {
{ {
.id = "10EC5682", .id = "10EC5682",
.drv_name = "rn_rt5682_rt1019", .drv_name = "acp3xalc56821019",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &amp_rt1019,
},
{
.id = "RTL5682",
.drv_name = "acp3xalc5682sm98360",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &amp_max,
},
{
.id = "RTL5682",
.drv_name = "acp3xalc5682s1019",
.machine_quirk = snd_soc_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &amp_rt1019, .quirk_data = &amp_rt1019,
}, },
@ -97,13 +128,145 @@ static struct snd_soc_dai_driver acp_renoir_dai[] = {
.ops = &asoc_acp_cpu_dai_ops, .ops = &asoc_acp_cpu_dai_ops,
.probe = &asoc_acp_i2s_probe, .probe = &asoc_acp_i2s_probe,
}, },
{
.name = "acp-pdm-dmic",
.id = DMIC_INSTANCE,
.capture = {
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &acp_dmic_dai_ops,
},
}; };
static int acp3x_power_on(void __iomem *base)
{
u32 val;
val = readl(base + ACP_PGFSM_STATUS);
if (val == ACP_POWERED_ON)
return 0;
if ((val & ACP_PGFSM_STAT_MASK) != ACP_PWR_ON_IN_PROGRESS)
writel(ACP_PWR_ON_MASK, base + ACP_PGFSM_CONTROL);
return readl_poll_timeout(base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT);
}
static int acp3x_power_off(void __iomem *base)
{
u32 val;
writel(ACP_PWR_OFF_MASK, base + ACP_PGFSM_CONTROL);
return readl_poll_timeout(base + ACP_PGFSM_STATUS, val,
(val & ACP_PGFSM_STAT_MASK) == ACP_POWERED_OFF,
DELAY_US, ACP_TIMEOUT);
}
static int acp3x_reset(void __iomem *base)
{
u32 val;
int ret;
writel(1, base + ACP_SOFT_RESET);
ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK,
DELAY_US, ACP_TIMEOUT);
if (ret)
return ret;
writel(0, base + ACP_SOFT_RESET);
return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
}
static void acp3x_enable_interrupts(void __iomem *base)
{
u32 ext_intr_ctrl;
writel(0x01, base + ACP_EXTERNAL_INTR_ENB);
ext_intr_ctrl = readl(base + ACP_EXTERNAL_INTR_CNTL);
ext_intr_ctrl |= ACP_ERROR_MASK;
writel(ext_intr_ctrl, base + ACP_EXTERNAL_INTR_CNTL);
}
static void acp3x_disable_interrupts(void __iomem *base)
{
writel(ACP_EXT_INTR_STAT_CLEAR_MASK, base + ACP_EXTERNAL_INTR_STAT);
writel(0x00, base + ACP_EXTERNAL_INTR_ENB);
}
static int rn_acp_init(void __iomem *base)
{
int ret;
/* power on */
ret = acp3x_power_on(base);
if (ret)
return ret;
writel(0x01, base + ACP_CONTROL);
/* Reset */
ret = acp3x_reset(base);
if (ret)
return ret;
acp3x_enable_interrupts(base);
return 0;
}
static int rn_acp_deinit(void __iomem *base)
{
int ret = 0;
acp3x_disable_interrupts(base);
/* Reset */
ret = acp3x_reset(base);
if (ret)
return ret;
writel(0x00, base + ACP_CONTROL);
/* power off */
ret = acp3x_power_off(base);
if (ret)
return ret;
return 0;
}
static int renoir_audio_probe(struct platform_device *pdev) static int renoir_audio_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct acp_chip_info *chip;
struct acp_dev_data *adata; struct acp_dev_data *adata;
struct resource *res; struct resource *res;
int ret;
chip = dev_get_platdata(&pdev->dev);
if (!chip || !chip->base) {
dev_err(&pdev->dev, "ACP chip data is NULL\n");
return -ENODEV;
}
if (chip->acp_rev != ACP3X_DEV) {
dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev);
return -ENODEV;
}
ret = rn_acp_init(chip->base);
if (ret) {
dev_err(&pdev->dev, "ACP Init failed\n");
return -EINVAL;
}
adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
if (!adata) if (!adata)
@ -119,13 +282,11 @@ static int renoir_audio_probe(struct platform_device *pdev)
if (!adata->acp_base) if (!adata->acp_base)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); ret = platform_get_irq_byname(pdev, "acp_dai_irq");
if (!res) { if (ret < 0)
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); return ret;
return -ENODEV; adata->i2s_irq = ret;
}
adata->i2s_irq = res->start;
adata->dev = dev; adata->dev = dev;
adata->dai_driver = acp_renoir_dai; adata->dai_driver = acp_renoir_dai;
adata->num_dai = ARRAY_SIZE(acp_renoir_dai); adata->num_dai = ARRAY_SIZE(acp_renoir_dai);
@ -142,6 +303,20 @@ static int renoir_audio_probe(struct platform_device *pdev)
static int renoir_audio_remove(struct platform_device *pdev) static int renoir_audio_remove(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct acp_chip_info *chip;
int ret;
chip = dev_get_platdata(&pdev->dev);
if (!chip || !chip->base) {
dev_err(&pdev->dev, "ACP chip data is NULL\n");
return -ENODEV;
}
ret = rn_acp_deinit(chip->base);
if (ret) {
dev_err(&pdev->dev, "ACP de-init Failed\n");
return -EINVAL;
}
acp_platform_unregister(dev); acp_platform_unregister(dev);
return 0; return 0;

View File

@ -40,6 +40,15 @@ static struct acp_card_drvdata sof_rt5682_max_data = {
.gpio_spkr_en = EN_SPKR_GPIO_NONE, .gpio_spkr_en = EN_SPKR_GPIO_NONE,
}; };
static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
.hs_cpu_id = I2S_SP,
.amp_cpu_id = I2S_SP,
.dmic_cpu_id = DMIC,
.hs_codec_id = RT5682S,
.amp_codec_id = RT1019,
.dmic_codec_id = DMIC,
};
static struct acp_card_drvdata sof_rt5682s_max_data = { static struct acp_card_drvdata sof_rt5682s_max_data = {
.hs_cpu_id = I2S_SP, .hs_cpu_id = I2S_SP,
.amp_cpu_id = I2S_SP, .amp_cpu_id = I2S_SP,
@ -126,6 +135,10 @@ static const struct platform_device_id board_ids[] = {
.name = "rt5682s-max", .name = "rt5682s-max",
.driver_data = (kernel_ulong_t)&sof_rt5682s_max_data .driver_data = (kernel_ulong_t)&sof_rt5682s_max_data
}, },
{
.name = "rt5682s-rt1019",
.driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data
},
{ } { }
}; };
static struct platform_driver acp_asoc_audio = { static struct platform_driver acp_asoc_audio = {
@ -143,4 +156,5 @@ MODULE_DESCRIPTION("ACP chrome SOF audio support");
MODULE_ALIAS("platform:rt5682-rt1019"); MODULE_ALIAS("platform:rt5682-rt1019");
MODULE_ALIAS("platform:rt5682-max"); MODULE_ALIAS("platform:rt5682-max");
MODULE_ALIAS("platform:rt5682s-max"); MODULE_ALIAS("platform:rt5682s-max");
MODULE_ALIAS("platform:rt5682s-rt1019");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -12,13 +12,19 @@
#define __AMD_ACP_H #define __AMD_ACP_H
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h> #include <sound/soc-acpi.h>
#include <sound/soc-dai.h>
#include "chip_offset_byte.h" #include "chip_offset_byte.h"
#define ACP3X_DEV 3
#define I2S_SP_INSTANCE 0x00 #define I2S_SP_INSTANCE 0x00
#define I2S_BT_INSTANCE 0x01 #define I2S_BT_INSTANCE 0x01
#define DMIC_INSTANCE 0x02
#define MEM_WINDOW_START 0x4000000 #define MEM_WINDOW_START 0x4080000
#define ACP_I2S_REG_START 0x1242400 #define ACP_I2S_REG_START 0x1242400
#define ACP_I2S_REG_END 0x1242810 #define ACP_I2S_REG_END 0x1242810
@ -38,6 +44,7 @@
#define ACP_SRAM_SP_CP_PTE_OFFSET 0x100 #define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
#define ACP_SRAM_BT_PB_PTE_OFFSET 0x200 #define ACP_SRAM_BT_PB_PTE_OFFSET 0x200
#define ACP_SRAM_BT_CP_PTE_OFFSET 0x300 #define ACP_SRAM_BT_CP_PTE_OFFSET 0x300
#define ACP_SRAM_PDM_PTE_OFFSET 0x400
#define PAGE_SIZE_4K_ENABLE 0x2 #define PAGE_SIZE_4K_ENABLE 0x2
#define I2S_SP_TX_MEM_WINDOW_START 0x4000000 #define I2S_SP_TX_MEM_WINDOW_START 0x4000000
@ -68,6 +75,12 @@
#define ACP_MAX_STREAM 6 #define ACP_MAX_STREAM 6
struct acp_chip_info {
char *name; /* Platform name */
unsigned int acp_rev; /* ACP Revision id */
void __iomem *base; /* ACP memory PCI base */
};
struct acp_stream { struct acp_stream {
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
int irq_bit; int irq_bit;
@ -96,6 +109,7 @@ struct acp_dev_data {
}; };
extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;
extern const struct snd_soc_dai_ops acp_dmic_dai_ops;
int asoc_acp_i2s_probe(struct snd_soc_dai *dai); int asoc_acp_i2s_probe(struct snd_soc_dai *dai);
int acp_platform_register(struct device *dev); int acp_platform_register(struct device *dev);
@ -103,6 +117,9 @@ int acp_platform_unregister(struct device *dev);
int acp_machine_select(struct acp_dev_data *adata); int acp_machine_select(struct acp_dev_data *adata);
/* Machine configuration */
int snd_amd_acp_find_config(struct pci_dev *pci);
static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)
{ {
u64 byte_count, low = 0, high = 0; u64 byte_count, low = 0, high = 0;
@ -131,6 +148,10 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH); high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW); low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
break; break;
case DMIC_INSTANCE:
high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
break;
default: default:
dev_err(adata->dev, "Invalid dai id %x\n", dai_id); dev_err(adata->dev, "Invalid dai id %x\n", dai_id);
return -EINVAL; return -EINVAL;

View File

@ -14,6 +14,12 @@
#define ACPAXI2AXI_ATU_CTRL 0xC40 #define ACPAXI2AXI_ATU_CTRL 0xC40
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0xC20 #define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0xC20
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24 #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24
#define ACP_PGFSM_CONTROL 0x141C
#define ACP_PGFSM_STATUS 0x1420
#define ACP_SOFT_RESET 0x1000
#define ACP_CONTROL 0x1004
#define ACP_EXTERNAL_INTR_ENB 0x1800 #define ACP_EXTERNAL_INTR_ENB 0x1800
#define ACP_EXTERNAL_INTR_CNTL 0x1804 #define ACP_EXTERNAL_INTR_CNTL 0x1804
#define ACP_EXTERNAL_INTR_STAT 0x1808 #define ACP_EXTERNAL_INTR_STAT 0x1808
@ -73,4 +79,24 @@
#define ACP_BTTDM_ITER 0x280C #define ACP_BTTDM_ITER 0x280C
#define ACP_BTTDM_TXFRMT 0x2810 #define ACP_BTTDM_TXFRMT 0x2810
/* Registers from ACP_WOV_PDM block */
#define ACP_WOV_PDM_ENABLE 0x2C04
#define ACP_WOV_PDM_DMA_ENABLE 0x2C08
#define ACP_WOV_RX_RINGBUFADDR 0x2C0C
#define ACP_WOV_RX_RINGBUFSIZE 0x2C10
#define ACP_WOV_RX_LINKPOSITIONCNTR 0x2C14
#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x2C18
#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x2C1C
#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x2C20
#define ACP_WOV_PDM_FIFO_FLUSH 0x2C24
#define ACP_WOV_PDM_NO_OF_CHANNELS 0x2C28
#define ACP_WOV_PDM_DECIMATION_FACTOR 0x2C2C
#define ACP_WOV_PDM_VAD_CTRL 0x2C30
#define ACP_WOV_BUFFER_STATUS 0x2C58
#define ACP_WOV_MISC_CTRL 0x2C5C
#define ACP_WOV_CLK_CTRL 0x2C60
#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x2C64
#define ACP_WOV_ERROR_STATUS_REGISTER 0x2C68
#endif #endif

View File

@ -14,6 +14,7 @@
#define FLAG_AMD_SOF BIT(1) #define FLAG_AMD_SOF BIT(1)
#define FLAG_AMD_SOF_ONLY_DMIC BIT(2) #define FLAG_AMD_SOF_ONLY_DMIC BIT(2)
#define FLAG_AMD_LEGACY BIT(3)
#define ACP_PCI_DEV_ID 0x15E2 #define ACP_PCI_DEV_ID 0x15E2

View File

@ -394,13 +394,10 @@ static int acp3x_audio_probe(struct platform_device *pdev)
if (!adata->acp3x_base) if (!adata->acp3x_base)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); status = platform_get_irq(pdev, 0);
if (!res) { if (status < 0)
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); return status;
return -ENODEV; adata->i2s_irq = status;
}
adata->i2s_irq = res->start;
dev_set_drvdata(&pdev->dev, adata); dev_set_drvdata(&pdev->dev, adata);
status = devm_snd_soc_register_component(&pdev->dev, status = devm_snd_soc_register_component(&pdev->dev,

View File

@ -87,7 +87,7 @@ struct acp3x_platform_info {
struct i2s_dev_data { struct i2s_dev_data {
bool tdm_mode; bool tdm_mode;
unsigned int i2s_irq; int i2s_irq;
u16 i2s_instance; u16 i2s_instance;
u32 tdm_fmt; u32 tdm_fmt;
u32 substream_type; u32 substream_type;

View File

@ -399,13 +399,11 @@ static int acp_pdm_audio_probe(struct platform_device *pdev)
if (!adata->acp_base) if (!adata->acp_base)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); status = platform_get_irq(pdev, 0);
if (!res) { if (status < 0)
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); return status;
return -ENODEV; adata->pdm_irq = status;
}
adata->pdm_irq = res->start;
adata->capture_stream = NULL; adata->capture_stream = NULL;
dev_set_drvdata(&pdev->dev, adata); dev_set_drvdata(&pdev->dev, adata);

View File

@ -212,10 +212,15 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
acpi_integer dmic_status; acpi_integer dmic_status;
#endif #endif
const struct dmi_system_id *dmi_id; const struct dmi_system_id *dmi_id;
unsigned int irqflags; unsigned int irqflags, flag;
int ret, index; int ret, index;
u32 addr; u32 addr;
/* Return if acp config flag is defined */
flag = snd_amd_acp_find_config(pci);
if (flag)
return -ENODEV;
/* Renoir device check */ /* Renoir device check */
if (pci->revision != 0x01) if (pci->revision != 0x01)
return -ENODEV; return -ENODEV;

View File

@ -88,3 +88,6 @@ static inline void rn_writel(u32 val, void __iomem *base_addr)
{ {
writel(val, base_addr - ACP_PHY_BASE_ADDRESS); writel(val, base_addr - ACP_PHY_BASE_ADDRESS);
} }
/* Machine configuration */
int snd_amd_acp_find_config(struct pci_dev *pci);

View File

@ -110,7 +110,7 @@ static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
static int acp5x_8821_startup(struct snd_pcm_substream *substream) static int acp5x_8821_startup(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card); struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);
@ -131,7 +131,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream)
static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream, static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct snd_soc_dai *codec_dai = struct snd_soc_dai *codec_dai =
snd_soc_card_get_codec_dai(card, snd_soc_card_get_codec_dai(card,
@ -153,7 +153,7 @@ static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream,
static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream) static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card); struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);
@ -170,13 +170,14 @@ static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)
static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream, static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
int ret, i; int ret, i;
unsigned int num_codecs = rtd->num_codecs; unsigned int num_codecs = rtd->num_codecs;
unsigned int bclk_val; unsigned int bclk_val;
ret = 0;
for (i = 0; i < num_codecs; i++) { for (i = 0; i < num_codecs; i++) {
codec_dai = asoc_rtd_to_codec(rtd, i); codec_dai = asoc_rtd_to_codec(rtd, i);
if ((strcmp(codec_dai->name, "spi-VLV1776:00") == 0) || if ((strcmp(codec_dai->name, "spi-VLV1776:00") == 0) ||
@ -242,7 +243,7 @@ SND_SOC_DAILINK_DEF(platform,
static struct snd_soc_dai_link acp5x_dai[] = { static struct snd_soc_dai_link acp5x_dai[] = {
{ {
.name = "acp5x-8825-play", .name = "acp5x-8821-play",
.stream_name = "Playback/Capture", .stream_name = "Playback/Capture",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAIFMT_CBC_CFC,
@ -341,7 +342,6 @@ static struct snd_soc_card acp5x_card = {
.num_controls = ARRAY_SIZE(acp5x_8821_controls), .num_controls = ARRAY_SIZE(acp5x_8821_controls),
}; };
static int acp5x_vg_quirk_cb(const struct dmi_system_id *id) static int acp5x_vg_quirk_cb(const struct dmi_system_id *id)
{ {
acp5x_machine_id = VG_JUPITER; acp5x_machine_id = VG_JUPITER;
@ -371,7 +371,7 @@ static int acp5x_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
dmi_check_system(acp5x_vg_quirk_table); dmi_check_system(acp5x_vg_quirk_table);
switch(acp5x_machine_id) { switch (acp5x_machine_id) {
case VG_JUPITER: case VG_JUPITER:
card = &acp5x_card; card = &acp5x_card;
acp5x_card.dev = &pdev->dev; acp5x_card.dev = &pdev->dev;

View File

@ -281,7 +281,7 @@ static int acp5x_dma_hw_params(struct snd_soc_component *component,
return -EINVAL; return -EINVAL;
} }
size = params_buffer_bytes(params); size = params_buffer_bytes(params);
rtd->dma_addr = substream->dma_buffer.addr; rtd->dma_addr = substream->runtime->dma_addr;
rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
config_acp5x_dma(rtd, substream->stream); config_acp5x_dma(rtd, substream->stream);
return 0; return 0;
@ -388,13 +388,11 @@ static int acp5x_audio_probe(struct platform_device *pdev)
if (!adata->acp5x_base) if (!adata->acp5x_base)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); status = platform_get_irq(pdev, 0);
if (!res) { if (status < 0)
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); return status;
return -ENODEV; adata->i2s_irq = status;
}
adata->i2s_irq = res->start;
dev_set_drvdata(&pdev->dev, adata); dev_set_drvdata(&pdev->dev, adata);
status = devm_snd_soc_register_component(&pdev->dev, status = devm_snd_soc_register_component(&pdev->dev,
&acp5x_i2s_component, &acp5x_i2s_component,
@ -426,51 +424,51 @@ static int acp5x_audio_remove(struct platform_device *pdev)
static int __maybe_unused acp5x_pcm_resume(struct device *dev) static int __maybe_unused acp5x_pcm_resume(struct device *dev)
{ {
struct i2s_dev_data *adata; struct i2s_dev_data *adata;
u32 val, reg_val, frmt_val; struct i2s_stream_instance *rtd;
u32 val;
reg_val = 0;
frmt_val = 0;
adata = dev_get_drvdata(dev); adata = dev_get_drvdata(dev);
if (adata->play_stream && adata->play_stream->runtime) { if (adata->play_stream && adata->play_stream->runtime) {
struct i2s_stream_instance *rtd = rtd = adata->play_stream->runtime->private_data;
adata->play_stream->runtime->private_data;
config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK); config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
switch (rtd->i2s_instance) { acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_HSTDM_ITER);
case I2S_HS_INSTANCE: if (adata->tdm_mode == TDM_ENABLE) {
reg_val = ACP_HSTDM_ITER; acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_HSTDM_TXFRMT);
frmt_val = ACP_HSTDM_TXFRMT; val = acp_readl(adata->acp5x_base + ACP_HSTDM_ITER);
break; acp_writel(val | 0x2, adata->acp5x_base + ACP_HSTDM_ITER);
case I2S_SP_INSTANCE: }
default: }
reg_val = ACP_I2STDM_ITER; if (adata->i2ssp_play_stream && adata->i2ssp_play_stream->runtime) {
frmt_val = ACP_I2STDM_TXFRMT; rtd = adata->i2ssp_play_stream->runtime->private_data;
config_acp5x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_I2STDM_ITER);
if (adata->tdm_mode == TDM_ENABLE) {
acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_I2STDM_TXFRMT);
val = acp_readl(adata->acp5x_base + ACP_I2STDM_ITER);
acp_writel(val | 0x2, adata->acp5x_base + ACP_I2STDM_ITER);
} }
acp_writel((rtd->xfer_resolution << 3),
rtd->acp5x_base + reg_val);
} }
if (adata->capture_stream && adata->capture_stream->runtime) { if (adata->capture_stream && adata->capture_stream->runtime) {
struct i2s_stream_instance *rtd = rtd = adata->capture_stream->runtime->private_data;
adata->capture_stream->runtime->private_data;
config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE); config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
switch (rtd->i2s_instance) { acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_HSTDM_IRER);
case I2S_HS_INSTANCE: if (adata->tdm_mode == TDM_ENABLE) {
reg_val = ACP_HSTDM_IRER; acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_HSTDM_RXFRMT);
frmt_val = ACP_HSTDM_RXFRMT; val = acp_readl(adata->acp5x_base + ACP_HSTDM_IRER);
break; acp_writel(val | 0x2, adata->acp5x_base + ACP_HSTDM_IRER);
case I2S_SP_INSTANCE:
default:
reg_val = ACP_I2STDM_IRER;
frmt_val = ACP_I2STDM_RXFRMT;
} }
acp_writel((rtd->xfer_resolution << 3),
rtd->acp5x_base + reg_val);
} }
if (adata->tdm_mode == TDM_ENABLE) { if (adata->i2ssp_capture_stream && adata->i2ssp_capture_stream->runtime) {
acp_writel(adata->tdm_fmt, adata->acp5x_base + frmt_val); rtd = adata->i2ssp_capture_stream->runtime->private_data;
val = acp_readl(adata->acp5x_base + reg_val); config_acp5x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
acp_writel(val | 0x2, adata->acp5x_base + reg_val); acp_writel((rtd->xfer_resolution << 3), rtd->acp5x_base + ACP_I2STDM_IRER);
if (adata->tdm_mode == TDM_ENABLE) {
acp_writel(adata->tdm_fmt, adata->acp5x_base + ACP_I2STDM_RXFRMT);
val = acp_readl(adata->acp5x_base + ACP_I2STDM_IRER);
acp_writel(val | 0x2, adata->acp5x_base + ACP_I2STDM_IRER);
}
} }
acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB); acp_writel(1, adata->acp5x_base + ACP_EXTERNAL_INTR_ENB);
return 0; return 0;

View File

@ -85,7 +85,7 @@
struct i2s_dev_data { struct i2s_dev_data {
bool tdm_mode; bool tdm_mode;
bool master_mode; bool master_mode;
unsigned int i2s_irq; int i2s_irq;
u16 i2s_instance; u16 i2s_instance;
u32 tdm_fmt; u32 tdm_fmt;
void __iomem *acp5x_base; void __iomem *acp5x_base;

View File

@ -160,4 +160,20 @@ config SND_MCHP_SOC_SPDIFRX
This S/PDIF RX driver is compliant with IEC-60958 standard and This S/PDIF RX driver is compliant with IEC-60958 standard and
includes programmable User Data and Channel Status fields. includes programmable User Data and Channel Status fields.
config SND_MCHP_SOC_PDMC
tristate "Microchip ASoC driver for boards using PDMC"
depends on OF && (ARCH_AT91 || COMPILE_TEST)
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
help
Say Y or M if you want to add support for Microchip ASoC PDMC driver on the
following Microchip platforms:
- sama7g5
The Pulse Density Microphone Controller (PDMC) interfaces up to 4 digital
microphones PDM outputs. It generates a single clock line and samples 1 or
2 data lines. The signal path includes an audio grade programmable
decimation filter and outputs 24-bit audio words.
endif endif

View File

@ -7,6 +7,7 @@ snd-soc-atmel-i2s-objs := atmel-i2s.o
snd-soc-mchp-i2s-mcc-objs := mchp-i2s-mcc.o snd-soc-mchp-i2s-mcc-objs := mchp-i2s-mcc.o
snd-soc-mchp-spdiftx-objs := mchp-spdiftx.o snd-soc-mchp-spdiftx-objs := mchp-spdiftx.o
snd-soc-mchp-spdifrx-objs := mchp-spdifrx.o snd-soc-mchp-spdifrx-objs := mchp-spdifrx.o
snd-soc-mchp-pdmc-objs := mchp-pdmc.o
# pdc and dma need to both be built-in if any user of # pdc and dma need to both be built-in if any user of
# ssc is built-in. # ssc is built-in.
@ -21,6 +22,7 @@ obj-$(CONFIG_SND_ATMEL_SOC_I2S) += snd-soc-atmel-i2s.o
obj-$(CONFIG_SND_MCHP_SOC_I2S_MCC) += snd-soc-mchp-i2s-mcc.o obj-$(CONFIG_SND_MCHP_SOC_I2S_MCC) += snd-soc-mchp-i2s-mcc.o
obj-$(CONFIG_SND_MCHP_SOC_SPDIFTX) += snd-soc-mchp-spdiftx.o obj-$(CONFIG_SND_MCHP_SOC_SPDIFTX) += snd-soc-mchp-spdiftx.o
obj-$(CONFIG_SND_MCHP_SOC_SPDIFRX) += snd-soc-mchp-spdifrx.o obj-$(CONFIG_SND_MCHP_SOC_SPDIFRX) += snd-soc-mchp-spdifrx.o
obj-$(CONFIG_SND_MCHP_SOC_PDMC) += snd-soc-mchp-pdmc.o
# AT91 Machine Support # AT91 Machine Support
snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o

View File

@ -280,7 +280,10 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
/* Enable PMC peripheral clock for this SSC */ /* Enable PMC peripheral clock for this SSC */
pr_debug("atmel_ssc_dai: Starting clock\n"); pr_debug("atmel_ssc_dai: Starting clock\n");
clk_enable(ssc_p->ssc->clk); ret = clk_enable(ssc_p->ssc->clk);
if (ret)
return ret;
ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
/* Reset the SSC unless initialized to keep it in a clean state */ /* Reset the SSC unless initialized to keep it in a clean state */

1083
sound/soc/atmel/mchp-pdmc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -920,7 +920,7 @@ static int mchp_spdifrx_probe(struct platform_device *pdev)
err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to register PMC: %d\n", err); dev_err(&pdev->dev, "failed to register PCM: %d\n", err);
return err; return err;
} }

View File

@ -115,7 +115,8 @@ static int snd_proto_probe(struct platform_device *pdev)
cpu_np = of_parse_phandle(np, "i2s-controller", 0); cpu_np = of_parse_phandle(np, "i2s-controller", 0);
if (!cpu_np) { if (!cpu_np) {
dev_err(&pdev->dev, "i2s-controller missing\n"); dev_err(&pdev->dev, "i2s-controller missing\n");
return -EINVAL; ret = -EINVAL;
goto put_codec_node;
} }
dai->cpus->of_node = cpu_np; dai->cpus->of_node = cpu_np;
dai->platforms->of_node = cpu_np; dai->platforms->of_node = cpu_np;
@ -125,7 +126,8 @@ static int snd_proto_probe(struct platform_device *pdev)
&bitclkmaster, &framemaster); &bitclkmaster, &framemaster);
if (bitclkmaster != framemaster) { if (bitclkmaster != framemaster) {
dev_err(&pdev->dev, "Must be the same bitclock and frame master\n"); dev_err(&pdev->dev, "Must be the same bitclock and frame master\n");
return -EINVAL; ret = -EINVAL;
goto put_cpu_node;
} }
if (bitclkmaster) { if (bitclkmaster) {
if (codec_np == bitclkmaster) if (codec_np == bitclkmaster)
@ -136,18 +138,20 @@ static int snd_proto_probe(struct platform_device *pdev)
dai_fmt |= snd_soc_daifmt_parse_clock_provider_as_flag(np, NULL); dai_fmt |= snd_soc_daifmt_parse_clock_provider_as_flag(np, NULL);
} }
of_node_put(bitclkmaster);
of_node_put(framemaster);
dai->dai_fmt = dai_fmt; dai->dai_fmt = dai_fmt;
of_node_put(codec_np);
of_node_put(cpu_np);
ret = snd_soc_register_card(&snd_proto); ret = snd_soc_register_card(&snd_proto);
if (ret) if (ret)
dev_err_probe(&pdev->dev, ret, dev_err_probe(&pdev->dev, ret,
"snd_soc_register_card() failed\n"); "snd_soc_register_card() failed\n");
put_cpu_node:
of_node_put(bitclkmaster);
of_node_put(framemaster);
of_node_put(cpu_np);
put_codec_node:
of_node_put(codec_np);
return ret; return ret;
} }

View File

@ -214,6 +214,7 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0); cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
if (!cpu_np) { if (!cpu_np) {
dev_err(&pdev->dev, "dai and pcm info missing\n"); dev_err(&pdev->dev, "dai and pcm info missing\n");
of_node_put(codec_np);
return -EINVAL; return -EINVAL;
} }
at91sam9g20ek_dai.cpus->of_node = cpu_np; at91sam9g20ek_dai.cpus->of_node = cpu_np;

View File

@ -142,7 +142,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
if (!cpu_np) { if (!cpu_np) {
dev_err(&pdev->dev, "atmel,ssc-controller node missing\n"); dev_err(&pdev->dev, "atmel,ssc-controller node missing\n");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out_put_codec_np;
} }
dai->cpus->of_node = cpu_np; dai->cpus->of_node = cpu_np;
dai->platforms->of_node = cpu_np; dai->platforms->of_node = cpu_np;
@ -153,12 +153,9 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "Failed to set SSC %d for audio: %d\n", dev_err(&pdev->dev, "Failed to set SSC %d for audio: %d\n",
ret, priv->ssc_id); ret, priv->ssc_id);
goto out; goto out_put_cpu_np;
} }
of_node_put(codec_np);
of_node_put(cpu_np);
ret = devm_snd_soc_register_card(&pdev->dev, card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Platform device allocation failed\n"); dev_err(&pdev->dev, "Platform device allocation failed\n");
@ -167,10 +164,14 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s ok\n", __func__); dev_dbg(&pdev->dev, "%s ok\n", __func__);
return ret; goto out_put_cpu_np;
out_put_audio: out_put_audio:
atmel_ssc_put_audio(priv->ssc_id); atmel_ssc_put_audio(priv->ssc_id);
out_put_cpu_np:
of_node_put(cpu_np);
out_put_codec_np:
of_node_put(codec_np);
out: out:
return ret; return ret;
} }

View File

@ -53,6 +53,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_AK5558 imply SND_SOC_AK5558
imply SND_SOC_ALC5623 imply SND_SOC_ALC5623
imply SND_SOC_ALC5632 imply SND_SOC_ALC5632
imply SND_SOC_AW8738
imply SND_SOC_BT_SCO imply SND_SOC_BT_SCO
imply SND_SOC_BD28623 imply SND_SOC_BD28623
imply SND_SOC_CQ0093VC imply SND_SOC_CQ0093VC
@ -244,6 +245,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WCD9335 imply SND_SOC_WCD9335
imply SND_SOC_WCD934X imply SND_SOC_WCD934X
imply SND_SOC_WCD938X_SDW imply SND_SOC_WCD938X_SDW
imply SND_SOC_LPASS_MACRO_COMMON
imply SND_SOC_LPASS_RX_MACRO imply SND_SOC_LPASS_RX_MACRO
imply SND_SOC_LPASS_TX_MACRO imply SND_SOC_LPASS_TX_MACRO
imply SND_SOC_WL1273 imply SND_SOC_WL1273
@ -578,6 +580,15 @@ config SND_SOC_ALC5632
tristate tristate
depends on I2C depends on I2C
config SND_SOC_AW8738
tristate "Awinic AW8738 Audio Amplifier"
select GPIOLIB
help
Enable support for the Awinic AW8738 audio amplifier (or similar).
The driver supports simple audio amplifiers similar to
SND_SOC_SIMPLE_AMPLIFIER, but additionally allows setting the
operation mode using the Awinic-specific one-wire pulse control.
config SND_SOC_BD28623 config SND_SOC_BD28623
tristate "ROHM BD28623 CODEC" tristate "ROHM BD28623 CODEC"
help help
@ -733,6 +744,7 @@ config SND_SOC_CS4349
config SND_SOC_CS47L15 config SND_SOC_CS47L15
tristate tristate
depends on MFD_CS47L15
config SND_SOC_CS47L24 config SND_SOC_CS47L24
tristate tristate
@ -740,15 +752,19 @@ config SND_SOC_CS47L24
config SND_SOC_CS47L35 config SND_SOC_CS47L35
tristate tristate
depends on MFD_CS47L35
config SND_SOC_CS47L85 config SND_SOC_CS47L85
tristate tristate
depends on MFD_CS47L85
config SND_SOC_CS47L90 config SND_SOC_CS47L90
tristate tristate
depends on MFD_CS47L90
config SND_SOC_CS47L92 config SND_SOC_CS47L92
tristate tristate
depends on MFD_CS47L92
# Cirrus Logic Quad-Channel ADC # Cirrus Logic Quad-Channel ADC
config SND_SOC_CS53L30 config SND_SOC_CS53L30
@ -842,7 +858,6 @@ config SND_SOC_DA9055
config SND_SOC_DMIC config SND_SOC_DMIC
tristate "Generic Digital Microphone CODEC" tristate "Generic Digital Microphone CODEC"
depends on GPIOLIB
help help
Enable support for the Generic Digital Microphone CODEC. Enable support for the Generic Digital Microphone CODEC.
Select this if your sound card has DMICs. Select this if your sound card has DMICs.
@ -1349,7 +1364,6 @@ config SND_SOC_RT9120
tristate "Richtek RT9120 Stereo Class-D Amplifier" tristate "Richtek RT9120 Stereo Class-D Amplifier"
depends on I2C depends on I2C
select REGMAP_I2C select REGMAP_I2C
select GPIOLIB
help help
Enable support for Richtek RT9120 20W, stereo, inductor-less, Enable support for Richtek RT9120 20W, stereo, inductor-less,
high-efficiency Class-D audio amplifier. high-efficiency Class-D audio amplifier.
@ -1393,11 +1407,10 @@ config SND_SOC_SIGMADSP_REGMAP
config SND_SOC_SIMPLE_AMPLIFIER config SND_SOC_SIMPLE_AMPLIFIER
tristate "Simple Audio Amplifier" tristate "Simple Audio Amplifier"
select GPIOLIB
config SND_SOC_SIMPLE_MUX config SND_SOC_SIMPLE_MUX
tristate "Simple Audio Mux" tristate "Simple Audio Mux"
select GPIOLIB depends on GPIOLIB
config SND_SOC_SPDIF config SND_SOC_SPDIF
tristate "S/PDIF CODEC" tristate "S/PDIF CODEC"
@ -1485,6 +1498,15 @@ config SND_SOC_TAS5720
Enable support for Texas Instruments TAS5720L/M high-efficiency mono Enable support for Texas Instruments TAS5720L/M high-efficiency mono
Class-D audio power amplifiers. Class-D audio power amplifiers.
config SND_SOC_TAS5805M
tristate "Texas Instruments TAS5805M speaker amplifier"
depends on I2C
help
Enable support for Texas Instruments TAS5805M Class-D
amplifiers. This is a speaker amplifier with an integrated
DSP. DSP configuration for each instance needs to be supplied
via a device-tree attribute.
config SND_SOC_TAS6424 config SND_SOC_TAS6424
tristate "Texas Instruments TAS6424 Quad-Channel Audio amplifier" tristate "Texas Instruments TAS6424 Quad-Channel Audio amplifier"
depends on I2C depends on I2C
@ -1901,7 +1923,6 @@ config SND_SOC_WSA881X
config SND_SOC_ZL38060 config SND_SOC_ZL38060
tristate "Microsemi ZL38060 Connected Home Audio Processor" tristate "Microsemi ZL38060 Connected Home Audio Processor"
depends on SPI_MASTER depends on SPI_MASTER
select GPIOLIB
select REGMAP select REGMAP
help help
Support for ZL38060 Connected Home Audio Processor from Microsemi, Support for ZL38060 Connected Home Audio Processor from Microsemi,
@ -1915,7 +1936,7 @@ config SND_SOC_LM4857
config SND_SOC_MAX9759 config SND_SOC_MAX9759
tristate "Maxim MAX9759 speaker Amplifier" tristate "Maxim MAX9759 speaker Amplifier"
select GPIOLIB depends on GPIOLIB
config SND_SOC_MAX9768 config SND_SOC_MAX9768
tristate tristate
@ -1998,6 +2019,9 @@ config SND_SOC_TPA6130A2
tristate "Texas Instruments TPA6130A2 headphone amplifier" tristate "Texas Instruments TPA6130A2 headphone amplifier"
depends on I2C depends on I2C
config SND_SOC_LPASS_MACRO_COMMON
tristate
config SND_SOC_LPASS_WSA_MACRO config SND_SOC_LPASS_WSA_MACRO
depends on COMMON_CLK depends on COMMON_CLK
select REGMAP_MMIO select REGMAP_MMIO
@ -2006,16 +2030,19 @@ config SND_SOC_LPASS_WSA_MACRO
config SND_SOC_LPASS_VA_MACRO config SND_SOC_LPASS_VA_MACRO
depends on COMMON_CLK depends on COMMON_CLK
select REGMAP_MMIO select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)" tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
config SND_SOC_LPASS_RX_MACRO config SND_SOC_LPASS_RX_MACRO
depends on COMMON_CLK depends on COMMON_CLK
select REGMAP_MMIO select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)" tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"
config SND_SOC_LPASS_TX_MACRO config SND_SOC_LPASS_TX_MACRO
depends on COMMON_CLK depends on COMMON_CLK
select REGMAP_MMIO select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)" tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"
endmenu endmenu

View File

@ -45,6 +45,7 @@ snd-soc-ak4671-objs := ak4671.o
snd-soc-ak5386-objs := ak5386.o snd-soc-ak5386-objs := ak5386.o
snd-soc-ak5558-objs := ak5558.o snd-soc-ak5558-objs := ak5558.o
snd-soc-arizona-objs := arizona.o arizona-jack.o snd-soc-arizona-objs := arizona.o arizona-jack.o
snd-soc-aw8738-objs := aw8738.o
snd-soc-bd28623-objs := bd28623.o snd-soc-bd28623-objs := bd28623.o
snd-soc-bt-sco-objs := bt-sco.o snd-soc-bt-sco-objs := bt-sco.o
snd-soc-cpcap-objs := cpcap.o snd-soc-cpcap-objs := cpcap.o
@ -112,6 +113,7 @@ snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o snd-soc-lm4857-objs := lm4857.o
snd-soc-lm49453-objs := lm49453.o snd-soc-lm49453-objs := lm49453.o
snd-soc-lochnagar-sc-objs := lochnagar-sc.o snd-soc-lochnagar-sc-objs := lochnagar-sc.o
snd-soc-lpass-macro-common-objs := lpass-macro-common.o
snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o
snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o
snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o
@ -236,6 +238,7 @@ snd-soc-sti-sas-objs := sti-sas.o
snd-soc-tas5086-objs := tas5086.o snd-soc-tas5086-objs := tas5086.o
snd-soc-tas571x-objs := tas571x.o snd-soc-tas571x-objs := tas571x.o
snd-soc-tas5720-objs := tas5720.o snd-soc-tas5720-objs := tas5720.o
snd-soc-tas5805m-objs := tas5805m.o
snd-soc-tas6424-objs := tas6424.o snd-soc-tas6424-objs := tas6424.o
snd-soc-tda7419-objs := tda7419.o snd-soc-tda7419-objs := tda7419.o
snd-soc-tas2770-objs := tas2770.o snd-soc-tas2770-objs := tas2770.o
@ -386,6 +389,7 @@ obj-$(CONFIG_SND_SOC_AK5558) += snd-soc-ak5558.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o
obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
@ -574,6 +578,7 @@ obj-$(CONFIG_SND_SOC_TAS2764) += snd-soc-tas2764.o
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
obj-$(CONFIG_SND_SOC_TAS5805M) += snd-soc-tas5805m.o
obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o
obj-$(CONFIG_SND_SOC_TDA7419) += snd-soc-tda7419.o obj-$(CONFIG_SND_SOC_TDA7419) += snd-soc-tda7419.o
obj-$(CONFIG_SND_SOC_TAS2770) += snd-soc-tas2770.o obj-$(CONFIG_SND_SOC_TAS2770) += snd-soc-tas2770.o
@ -674,6 +679,7 @@ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
obj-$(CONFIG_SND_SOC_LPASS_MACRO_COMMON) += snd-soc-lpass-macro-common.o
obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o
obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o
obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o

View File

@ -653,15 +653,10 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
struct ak4613_priv *priv; struct ak4613_priv *priv;
regmap_cfg = NULL; regmap_cfg = NULL;
if (np) { if (np)
const struct of_device_id *of_id; regmap_cfg = of_device_get_match_data(dev);
else
of_id = of_match_device(ak4613_of_match, dev);
if (of_id)
regmap_cfg = of_id->data;
} else {
regmap_cfg = (const struct regmap_config *)id->driver_data; regmap_cfg = (const struct regmap_config *)id->driver_data;
}
if (!regmap_cfg) if (!regmap_cfg)
return -EINVAL; return -EINVAL;

104
sound/soc/codecs/aw8738.c Normal file
View File

@ -0,0 +1,104 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
struct aw8738_priv {
struct gpio_desc *gpiod_mode;
unsigned int mode;
};
static int aw8738_drv_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
struct aw8738_priv *aw = snd_soc_component_get_drvdata(c);
int i;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
for (i = 0; i < aw->mode; i++) {
gpiod_set_value_cansleep(aw->gpiod_mode, 0);
udelay(2);
gpiod_set_value_cansleep(aw->gpiod_mode, 1);
udelay(2);
}
msleep(40);
break;
case SND_SOC_DAPM_PRE_PMD:
gpiod_set_value_cansleep(aw->gpiod_mode, 0);
usleep_range(1000, 2000);
break;
default:
WARN(1, "Unexpected event");
return -EINVAL;
}
return 0;
}
static const struct snd_soc_dapm_widget aw8738_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN"),
SND_SOC_DAPM_OUT_DRV_E("DRV", SND_SOC_NOPM, 0, 0, NULL, 0, aw8738_drv_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_OUTPUT("OUT"),
};
static const struct snd_soc_dapm_route aw8738_dapm_routes[] = {
{ "DRV", NULL, "IN" },
{ "OUT", NULL, "DRV" },
};
static const struct snd_soc_component_driver aw8738_component_driver = {
.dapm_widgets = aw8738_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(aw8738_dapm_widgets),
.dapm_routes = aw8738_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(aw8738_dapm_routes),
};
static int aw8738_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct aw8738_priv *aw;
int ret;
aw = devm_kzalloc(dev, sizeof(*aw), GFP_KERNEL);
if (!aw)
return -ENOMEM;
platform_set_drvdata(pdev, aw);
aw->gpiod_mode = devm_gpiod_get(dev, "mode", GPIOD_OUT_LOW);
if (IS_ERR(aw->gpiod_mode))
return dev_err_probe(dev, PTR_ERR(aw->gpiod_mode),
"Failed to get 'mode' gpio");
ret = device_property_read_u32(dev, "awinic,mode", &aw->mode);
if (ret)
return -EINVAL;
return devm_snd_soc_register_component(&pdev->dev,
&aw8738_component_driver,
NULL, 0);
}
#ifdef CONFIG_OF
static const struct of_device_id aw8738_of_match[] = {
{ .compatible = "awinic,aw8738" },
{ }
};
MODULE_DEVICE_TABLE(of, aw8738_of_match);
#endif
static struct platform_driver aw8738_driver = {
.probe = aw8738_probe,
.driver = {
.name = "aw8738",
.of_match_table = of_match_ptr(aw8738_of_match),
},
};
module_platform_driver(aw8738_driver);
MODULE_DESCRIPTION("Awinic AW8738 Amplifier Driver");
MODULE_LICENSE("GPL v2");

View File

@ -13,11 +13,15 @@
static const struct snd_soc_dapm_widget bt_sco_widgets[] = { static const struct snd_soc_dapm_widget bt_sco_widgets[] = {
SND_SOC_DAPM_INPUT("RX"), SND_SOC_DAPM_INPUT("RX"),
SND_SOC_DAPM_OUTPUT("TX"), SND_SOC_DAPM_OUTPUT("TX"),
SND_SOC_DAPM_AIF_IN("BT_SCO_RX", "Playback", 0,
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("BT_SCO_TX", "Capture", 0,
SND_SOC_NOPM, 0, 0),
}; };
static const struct snd_soc_dapm_route bt_sco_routes[] = { static const struct snd_soc_dapm_route bt_sco_routes[] = {
{ "Capture", NULL, "RX" }, { "BT_SCO_TX", NULL, "RX" },
{ "TX", NULL, "Playback" }, { "TX", NULL, "BT_SCO_RX" },
}; };
static struct snd_soc_dai_driver bt_sco_dai[] = { static struct snd_soc_dai_driver bt_sco_dai[] = {

View File

@ -1115,9 +1115,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
.set_sysclk = cs35l41_component_set_sysclk, .set_sysclk = cs35l41_component_set_sysclk,
}; };
static int cs35l41_handle_pdata(struct device *dev, static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_platform_data *pdata)
struct cs35l41_platform_data *pdata,
struct cs35l41_private *cs35l41)
{ {
struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1;
struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2;
@ -1260,7 +1258,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
if (pdata) { if (pdata) {
cs35l41->pdata = *pdata; cs35l41->pdata = *pdata;
} else { } else {
ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41); ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata);
if (ret != 0) if (ret != 0)
return ret; return ret;
} }

Some files were not shown because too many files have changed in this diff Show More