Commit 4b73a4cd authored by Mark Brown's avatar Mark Brown

ASoC: Cleanup MediaTek soundcard machine drivers

Merge series from AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>:

Changes in v5:
 - Cleaned up MT8186 soundcard migration commit which erroneously
   had leftovers from development
 - Changed the mtk_pcm_constraints_data structure to hold pointers
   to snd_pcm_hw_constraint_list, as to really reuse the const data
 - Tested again on all of the listed MTK platforms.

Changes in v4:
 - Rebased over next-20240409
 - Dropped the first 4 patches from v3 as were already picked by Mark
 - Fixed W=1 build issue

Changes in v3:
 - Added audio-routing names in enum in all yaml files
 - Added mention of disallowing old and new properties together in
   commit message of bindings patches
 - Fixed validation errors with sound-card-common.yaml inclusion
   due to missing model property in examples
 - Removed `else` enforcing headset-codec/speaker-codecs requirement
   if xxx-dai-link not present to avoid future commit noise as the
   deprecated statement will disallow deprecated properties as required

Changes in v2:
 - Bindings: Changed link-name/codec/clk-provider to remove `items`
   and leave just the enum
 - Moved .*-dai-link pattern additionalProperties after `type: object`
 - Added ref to sound-card-common.yaml
 - Fixed dai-link-xxx -> xxx-dai-link typo in example comment

This series performs a cleanup of most of the MediaTek AFE drivers and
soundcard machine drivers, reducing code duplication and setting a base
to be consistent with their devicetree bindings, as many of those are
using different properties and nodes for no good reason.

Summarizing:
 - Commonizes functions and ops where possible
 - Adds a common probe mechanism, increasing maintainability of
   soundcard drivers for older MediaTek SoCs
 - Migrates all drivers to support the new bindings
   - Obviously retains compatibility with old device trees
 - Reduces machine-specific parameters hardcoding in drivers
   - Can now set machine-specific params in device tree
   - Uses the `audio-routing` and `dai-link` nodes like some
     other non-MediaTek SoC sound drivers
 - Imposes consistency between MediaTek ASoC machine soundcard
   drivers bindings
 - Reduces code size and greatly reduces the amount of code that
   will be required for newer drivers (retaining compatibility with
   the old bindings was costly in terms of code size, otherwise
   this series would've removed ~1000 more lines, or something
   along that line).

This series was (manually) tested on MT8173, MT8192, MT8195 and MT8186
Chromebooks.

AngeloGioacchino Del Regno (18):
  ASoC: mediatek: Add common machine soundcard driver probe mechanism
  ASoC: mediatek: common: Constify struct mtk_sof_priv
  ASoC: mediatek: mt8188: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8195: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8192: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8186: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: Add common snd_soc_ops .startup() callback
  ASoC: mediatek: mt8195: Migrate to the common mtk_soundcard_startup
  ASoC: mediatek: mt8192: Migrate to the common mtk_soundcard_startup
  ASoC: mediatek: mt8186-rt1019: Migrate to the common
    mtk_soundcard_startup
  ASoC: mediatek: Add common mtk_afe_component_probe callback
  ASoC: mediatek: Use common mtk_afe_pcm_platform with common probe cb
  ASoC: mediatek: mt8186: Unify mt8186-mt6366 machine drivers
  ASoC: dt-bindings: mt8195: Document audio-routing and dai-link subnode
  ASoC: dt-bindings: mt8192: Document audio-routing and dai-link subnode
  ASoC: dt-bindings: mt8186: Document audio-routing and dai-link subnode
  arm64: dts: mediatek: mt8195-cherry: Specify sound DAI links and
    routing
  arm64: dts: mediatek: mt8186-corsola: Specify sound DAI links and
    routing

 .../sound/mt8186-mt6366-da7219-max98357.yaml  |  131 +-
 .../sound/mt8186-mt6366-rt1019-rt5682s.yaml   |  120 +-
 .../sound/mt8192-mt6359-rt1015-rt5682.yaml    |  139 +-
 .../bindings/sound/mt8195-mt6359.yaml         |  134 ++
 .../boot/dts/mediatek/mt8186-corsola.dtsi     |   42 +-
 .../boot/dts/mediatek/mt8195-cherry.dtsi      |   45 +
 sound/soc/mediatek/Kconfig                    |   24 +-
 .../mediatek/common/mtk-afe-platform-driver.c |   18 +
 .../soc/mediatek/common/mtk-dsp-sof-common.c  |   15 +-
 .../soc/mediatek/common/mtk-dsp-sof-common.h  |    1 -
 sound/soc/mediatek/common/mtk-soc-card.h      |    7 +-
 .../mediatek/common/mtk-soundcard-driver.c    |  199 +++
 .../mediatek/common/mtk-soundcard-driver.h    |   42 +
 sound/soc/mediatek/mt6797/mt6797-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt7986/mt7986-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt8183/mt8183-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt8186/Makefile            |    3 +-
 .../mt8186/mt8186-mt6366-da7219-max98357.c    | 1189 -----------------
 ...t6366-rt1019-rt5682s.c => mt8186-mt6366.c} |  578 ++++----
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c    |   21 +-
 sound/soc/mediatek/mt8188/mt8188-mt6359.c     |  203 +--
 sound/soc/mediatek/mt8192/mt8192-afe-pcm.c    |   25 +-
 .../mt8192/mt8192-mt6359-rt1015-rt5682.c      |  301 ++---
 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    |   21 +-
 sound/soc/mediatek/mt8195/mt8195-mt6359.c     |  487 +++----
 25 files changed, 1597 insertions(+), 2190 deletions(-)
 delete mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
 rename sound/soc/mediatek/mt8186/{mt8186-mt6366-rt1019-rt5682s.c => mt8186-mt6366.c} (72%)

--
2.44.0
parents 58300f8d 787f190c
......@@ -12,17 +12,46 @@ maintainers:
description:
This binding describes the MT8186 sound card.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
enum:
- mediatek,mt8186-mt6366-da7219-max98357-sound
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.
Valid names could be the input or output widgets of audio components,
power supplies, MicBias of codec and the software switch.
minItems: 2
items:
enum:
# Sinks
- HDMI1
- Headphones
- Line Out
- MIC
- Speakers
# Sources
- Headset Mic
- HPL
- HPR
- Speaker
- TX
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8186 ASoC platform.
headset-codec:
type: object
deprecated: true
additionalProperties: false
properties:
sound-dai:
......@@ -32,6 +61,7 @@ properties:
playback-codecs:
type: object
deprecated: true
additionalProperties: false
properties:
sound-dai:
......@@ -53,32 +83,115 @@ properties:
A list of the desired dai-links in the sound card. Each entry is a
name defined in the machine driver.
additionalProperties: false
patternProperties:
".*-dai-link$":
type: object
additionalProperties: false
description:
Container for dai-link level properties and CODEC sub-nodes.
properties:
link-name:
description: Indicates dai-link name and PCM stream name
items:
enum:
- I2S0
- I2S1
- I2S2
- I2S3
codec:
description: Holds subnode which indicates codec dai.
type: object
additionalProperties: false
properties:
sound-dai:
minItems: 1
maxItems: 2
required:
- sound-dai
dai-format:
description: audio format
items:
enum:
- i2s
- right_j
- left_j
- dsp_a
- dsp_b
mediatek,clk-provider:
$ref: /schemas/types.yaml#/definitions/string
description: Indicates dai-link clock master.
items:
enum:
- cpu
- codec
required:
- link-name
unevaluatedProperties: false
required:
- compatible
- mediatek,platform
- headset-codec
- playback-codecs
# Disallow legacy properties if xxx-dai-link nodes are specified
if:
not:
patternProperties:
".*-dai-link$": false
then:
properties:
headset-codec: false
speaker-codecs: false
examples:
- |
sound: mt8186-sound {
compatible = "mediatek,mt8186-mt6366-da7219-max98357-sound";
mediatek,platform = <&afe>;
model = "mt8186_da7219_m98357";
pinctrl-names = "aud_clk_mosi_off",
"aud_clk_mosi_on";
pinctrl-0 = <&aud_clk_mosi_off>;
pinctrl-1 = <&aud_clk_mosi_on>;
mediatek,platform = <&afe>;
audio-routing =
"Headphones", "HPL",
"Headphones", "HPR",
"MIC", "Headset Mic",
"Speakers", "Speaker",
"HDMI1", "TX";
hs-playback-dai-link {
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
};
headset-codec {
sound-dai = <&da7219>;
hs-capture-dai-link {
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
};
playback-codecs {
sound-dai = <&anx_bridge_dp>,
<&max98357a>;
spk-dp-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&anx_bridge_dp>, <&max98357a>;
};
};
};
......
......@@ -12,6 +12,9 @@ maintainers:
description:
This binding describes the MT8186 sound card.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
enum:
......@@ -19,6 +22,34 @@ properties:
- mediatek,mt8186-mt6366-rt5682s-max98360-sound
- mediatek,mt8186-mt6366-rt5650-sound
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.
Valid names could be the input or output widgets of audio components,
power supplies, MicBias of codec and the software switch.
minItems: 2
items:
enum:
# Sinks
- HDMI1
- Headphone
- IN1P
- IN1N
- Line Out
- Speakers
# Sources
- Headset Mic
- HPOL
- HPOR
- Speaker
- SPOL
- SPOR
- TX
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8186 ASoC platform.
......@@ -32,6 +63,7 @@ properties:
headset-codec:
type: object
deprecated: true
additionalProperties: false
properties:
sound-dai:
......@@ -41,6 +73,7 @@ properties:
playback-codecs:
type: object
deprecated: true
additionalProperties: false
properties:
sound-dai:
......@@ -62,13 +95,56 @@ properties:
A list of the desired dai-links in the sound card. Each entry is a
name defined in the machine driver.
additionalProperties: false
patternProperties:
".*-dai-link$":
type: object
additionalProperties: false
description:
Container for dai-link level properties and CODEC sub-nodes.
properties:
link-name:
description: Indicates dai-link name and PCM stream name
enum: [ I2S0, I2S1, I2S2, I2S3 ]
codec:
description: Holds subnode which indicates codec dai.
type: object
additionalProperties: false
properties:
sound-dai:
minItems: 1
maxItems: 2
required:
- sound-dai
dai-format:
description: audio format
enum: [ i2s, right_j, left_j, dsp_a, dsp_b ]
mediatek,clk-provider:
$ref: /schemas/types.yaml#/definitions/string
description: Indicates dai-link clock master.
enum: [ cpu, codec ]
required:
- link-name
unevaluatedProperties: false
required:
- compatible
- mediatek,platform
- headset-codec
- playback-codecs
# Disallow legacy properties if xxx-dai-link nodes are specified
if:
not:
patternProperties:
".*-dai-link$": false
then:
properties:
headset-codec: false
speaker-codecs: false
examples:
- |
......@@ -76,23 +152,49 @@ examples:
sound: mt8186-sound {
compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound";
mediatek,platform = <&afe>;
model = "mt8186_rt1019_rt5682s";
pinctrl-names = "aud_clk_mosi_off",
"aud_clk_mosi_on",
"aud_gpio_dmic_sec";
pinctrl-0 = <&aud_clk_mosi_off>;
pinctrl-1 = <&aud_clk_mosi_on>;
pinctrl-2 = <&aud_gpio_dmic_sec>;
mediatek,platform = <&afe>;
dmic-gpios = <&pio 23 GPIO_ACTIVE_HIGH>;
headset-codec {
sound-dai = <&rt5682s>;
audio-routing =
"Headphone", "HPOL",
"Headphone", "HPOR",
"IN1P", "Headset Mic",
"Speakers", "Speaker",
"HDMI1", "TX";
hs-playback-dai-link {
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
};
hs-capture-dai-link {
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
};
playback-codecs {
sound-dai = <&it6505dptx>,
<&rt1019p>;
spk-hdmi-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&it6505dptx>, <&rt1019p>;
};
};
};
......
......@@ -13,6 +13,9 @@ maintainers:
description:
This binding describes the MT8192 sound card.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
enum:
......@@ -20,6 +23,31 @@ properties:
- mediatek,mt8192_mt6359_rt1015p_rt5682
- mediatek,mt8192_mt6359_rt1015p_rt5682s
audio-routing:
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.
Valid names could be the input or output widgets of audio components,
power supplies, MicBias of codec and the software switch.
minItems: 2
items:
enum:
# Sinks
- Speakers
- Headphone Jack
- IN1P
- Left Spk
- Right Spk
# Sources
- Headset Mic
- HPOL
- HPOR
- Left SPO
- Right SPO
- Speaker
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8192 ASoC platform.
......@@ -27,10 +55,12 @@ properties:
mediatek,hdmi-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of HDMI codec.
deprecated: true
headset-codec:
type: object
additionalProperties: false
deprecated: true
properties:
sound-dai:
......@@ -41,6 +71,7 @@ properties:
speaker-codecs:
type: object
additionalProperties: false
deprecated: true
properties:
sound-dai:
......@@ -51,33 +82,121 @@ properties:
required:
- sound-dai
additionalProperties: false
patternProperties:
".*-dai-link$":
type: object
additionalProperties: false
description:
Container for dai-link level properties and CODEC sub-nodes.
properties:
link-name:
description: Indicates dai-link name and PCM stream name
enum:
- I2S0
- I2S1
- I2S2
- I2S3
- I2S4
- I2S5
- I2S6
- I2S7
- I2S8
- I2S9
- TDM
codec:
description: Holds subnode which indicates codec dai.
type: object
additionalProperties: false
properties:
sound-dai:
minItems: 1
maxItems: 2
required:
- sound-dai
dai-format:
description: audio format
enum: [ i2s, right_j, left_j, dsp_a, dsp_b ]
mediatek,clk-provider:
$ref: /schemas/types.yaml#/definitions/string
description: Indicates dai-link clock master.
enum: [ cpu, codec ]
required:
- link-name
unevaluatedProperties: false
required:
- compatible
- mediatek,platform
- headset-codec
- speaker-codecs
# Disallow legacy properties if xxx-dai-link nodes are specified
if:
not:
patternProperties:
".*-dai-link$": false
then:
properties:
headset-codec: false
speaker-codecs: false
mediatek,hdmi-codec: false
examples:
- |
sound: mt8192-sound {
compatible = "mediatek,mt8192_mt6359_rt1015_rt5682";
mediatek,platform = <&afe>;
mediatek,hdmi-codec = <&anx_bridge_dp>;
model = "mt8192_mt6359_rt1015_rt5682";
pinctrl-names = "aud_clk_mosi_off",
"aud_clk_mosi_on";
pinctrl-0 = <&aud_clk_mosi_off>;
pinctrl-1 = <&aud_clk_mosi_on>;
mediatek,platform = <&afe>;
audio-routing =
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR",
"IN1P", "Headset Mic",
"Speakers", "Speaker";
spk-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt1015p>;
};
};
hs-playback-dai-link {
link-name = "I2S8";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
};
headset-codec {
sound-dai = <&rt5682>;
hs-capture-dai-link {
link-name = "I2S9";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
};
speaker-codecs {
sound-dai = <&rt1015_l>,
<&rt1015_r>;
displayport-dai-link {
link-name = "TDM";
dai-format = "dsp_a";
codec {
sound-dai = <&anx_bridge_dp>;
};
};
};
......
......@@ -12,6 +12,9 @@ maintainers:
description:
This binding describes the MT8195 sound card.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
enum:
......@@ -23,6 +26,33 @@ properties:
$ref: /schemas/types.yaml#/definitions/string
description: User specified audio sound card name
audio-routing:
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.
Valid names could be the input or output widgets of audio components,
power supplies, MicBias of codec and the software switch.
minItems: 2
items:
enum:
# Sinks
- Ext Spk
- Headphone
- IN1P
- Left Spk
- Right Spk
# Sources
- Headset Mic
- HPOL
- HPOR
- Left BE_OUT
- Left SPO
- Right BE_OUT
- Right SPO
- Speaker
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8195 ASoC platform.
......@@ -30,10 +60,12 @@ properties:
mediatek,dptx-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8195 Display Port Tx codec node.
deprecated: true
mediatek,hdmi-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8195 HDMI codec node.
deprecated: true
mediatek,adsp:
$ref: /schemas/types.yaml#/definitions/phandle
......@@ -45,20 +77,122 @@ properties:
A list of the desired dai-links in the sound card. Each entry is a
name defined in the machine driver.
patternProperties:
".*-dai-link$":
type: object
additionalProperties: false
description:
Container for dai-link level properties and CODEC sub-nodes.
properties:
link-name:
description: Indicates dai-link name and PCM stream name
enum:
- DPTX_BE
- ETDM1_IN_BE
- ETDM2_IN_BE
- ETDM1_OUT_BE
- ETDM2_OUT_BE
- ETDM3_OUT_BE
- PCM1_BE
codec:
description: Holds subnode which indicates codec dai.
type: object
additionalProperties: false
properties:
sound-dai:
minItems: 1
maxItems: 2
required:
- sound-dai
dai-format:
description: audio format
enum: [ i2s, right_j, left_j, dsp_a, dsp_b ]
mediatek,clk-provider:
$ref: /schemas/types.yaml#/definitions/string
description: Indicates dai-link clock master.
enum: [ cpu, codec ]
required:
- link-name
additionalProperties: false
required:
- compatible
- mediatek,platform
# Disallow legacy properties if xxx-dai-link nodes are specified
if:
not:
patternProperties:
".*-dai-link$": false
then:
properties:
mediatek,dptx-codec: false
mediatek,hdmi-codec: false
examples:
- |
sound: mt8195-sound {
compatible = "mediatek,mt8195_mt6359_rt1019_rt5682";
model = "mt8195_r1019_5682";
mediatek,platform = <&afe>;
pinctrl-names = "default";
pinctrl-0 = <&aud_pins_default>;
audio-routing =
"Headphone", "HPOL",
"Headphone", "HPOR",
"IN1P", "Headset Mic",
"Ext Spk", "Speaker";
mm-dai-link {
link-name = "ETDM1_IN_BE";
mediatek,clk-provider = "cpu";
};
hs-playback-dai-link {
link-name = "ETDM1_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
};
hs-capture-dai-link {
link-name = "ETDM2_IN_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
};
spk-playback-dai-link {
link-name = "ETDM2_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&spk_amplifier>;
};
};
hdmi-dai-link {
link-name = "ETDM3_OUT_BE";
codec {
sound-dai = <&hdmi_tx>;
};
};
displayport-dai-link {
link-name = "DPTX_BE";
codec {
sound-dai = <&dp_tx>;
};
};
};
...
......@@ -185,27 +185,11 @@ config SND_SOC_MT8186
Select Y if you have such device.
If unsure select "N".
config SND_SOC_MT8186_MT6366_DA7219_MAX98357
tristate "ASoC Audio driver for MT8186 with DA7219 MAX98357A codec"
config SND_SOC_MT8186_MT6366
tristate "ASoC Audio driver for MT8186 with MT6366 and I2S codecs"
depends on I2C && GPIOLIB
depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
select SND_SOC_MT6358
select SND_SOC_MAX98357A
select SND_SOC_DA7219
select SND_SOC_BT_SCO
select SND_SOC_DMIC
select SND_SOC_HDMI_CODEC
help
This adds ASoC driver for Mediatek MT8186 boards
with the MT6366(MT6358) DA7219 MAX98357A codecs.
Select Y if you have such device.
If unsure select "N".
config SND_SOC_MT8186_MT6366_RT1019_RT5682S
tristate "ASoC Audio driver for MT8186 with RT1019 RT5682S MAX98357A/MAX98360 codec"
depends on I2C && GPIOLIB
depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
select SND_SOC_MAX98357A
select SND_SOC_MT6358
select SND_SOC_MAX98357A
select SND_SOC_RT1015P
......@@ -215,8 +199,8 @@ config SND_SOC_MT8186_MT6366_RT1019_RT5682S
select SND_SOC_DMIC
select SND_SOC_HDMI_CODEC
help
This adds ASoC driver for Mediatek MT8186 boards
with the MT6366(MT6358) RT1019 RT5682S codecs.
This adds the ASoC machine driver for Mediatek MT8186 boards
with the MT6366(MT6358) and other I2S audio codecs.
Select Y if you have such device.
If unsure select "N".
......
......@@ -126,10 +126,28 @@ int mtk_afe_pcm_new(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);
static int mtk_afe_component_probe(struct snd_soc_component *component)
{
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
int ret;
snd_soc_component_init_regmap(component, afe->regmap);
/* If the list was never initialized there are no sub-DAIs */
if (afe->sub_dais.next && afe->sub_dais.prev) {
ret = mtk_afe_add_sub_dai_control(component);
if (ret)
return ret;
}
return 0;
}
const struct snd_soc_component_driver mtk_afe_pcm_platform = {
.name = AFE_PCM_NAME,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
.probe = mtk_afe_component_probe,
};
EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform);
......
......@@ -15,7 +15,7 @@ int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_soc_card *card = rtd->card;
struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
int i, j, ret = 0;
for (i = 0; i < sof_priv->num_streams; i++) {
......@@ -55,7 +55,6 @@ int mtk_sof_card_probe(struct snd_soc_card *card)
int i;
struct snd_soc_dai_link *dai_link;
struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
/* Set stream_name to help sof bind widgets */
for_each_card_prelinks(card, i, dai_link) {
......@@ -63,7 +62,7 @@ int mtk_sof_card_probe(struct snd_soc_card *card)
dai_link->stream_name = dai_link->name;
}
INIT_LIST_HEAD(&sof_priv->dai_link_list);
INIT_LIST_HEAD(&soc_card_data->sof_dai_link_list);
return 0;
}
......@@ -73,7 +72,7 @@ static struct snd_soc_pcm_runtime *mtk_sof_find_tplg_be(struct snd_soc_pcm_runti
{
struct snd_soc_card *card = rtd->card;
struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
struct snd_soc_pcm_runtime *fe;
struct snd_soc_pcm_runtime *be;
struct snd_soc_dpcm *dpcm;
......@@ -113,7 +112,7 @@ static int mtk_sof_check_tplg_be_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_soc_card *card = rtd->card;
struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
struct snd_soc_pcm_runtime *sof_be;
struct mtk_dai_link *dai_link;
int ret = 0;
......@@ -125,7 +124,7 @@ static int mtk_sof_check_tplg_be_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
else if (sof_be->dai_link->be_hw_params_fixup)
ret = sof_be->dai_link->be_hw_params_fixup(sof_be, params);
} else {
list_for_each_entry(dai_link, &sof_priv->dai_link_list, list) {
list_for_each_entry(dai_link, &soc_card_data->sof_dai_link_list, list) {
if (strcmp(dai_link->name, rtd->dai_link->name) == 0) {
if (dai_link->be_hw_params_fixup)
ret = dai_link->be_hw_params_fixup(rtd, params);
......@@ -144,7 +143,7 @@ int mtk_sof_card_late_probe(struct snd_soc_card *card)
struct snd_soc_component *sof_comp = NULL;
struct mtk_soc_card_data *soc_card_data =
snd_soc_card_get_drvdata(card);
struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
struct snd_soc_dai_link *dai_link;
struct mtk_dai_link *mtk_dai_link;
int i;
......@@ -173,7 +172,7 @@ int mtk_sof_card_late_probe(struct snd_soc_card *card)
mtk_dai_link->be_hw_params_fixup = dai_link->be_hw_params_fixup;
mtk_dai_link->name = dai_link->name;
list_add(&mtk_dai_link->list, &sof_priv->dai_link_list);
list_add(&mtk_dai_link->list, &soc_card_data->sof_dai_link_list);
}
if (dai_link->no_pcm)
......
......@@ -30,7 +30,6 @@ struct mtk_sof_priv {
int num_streams;
int (*sof_dai_link_fixup)(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params);
struct list_head dai_link_list;
};
int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
......
......@@ -9,9 +9,14 @@
#ifndef _MTK_SOC_CARD_H_
#define _MTK_SOC_CARD_H_
struct mtk_platform_card_data;
struct mtk_sof_priv;
struct mtk_soc_card_data {
const struct mtk_sof_priv *sof_priv;
struct list_head sof_dai_link_list;
struct mtk_platform_card_data *card_data;
void *mach_priv;
void *sof_priv;
};
#endif
......@@ -10,6 +10,8 @@
#include <linux/of.h>
#include <sound/soc.h>
#include "mtk-dsp-sof-common.h"
#include "mtk-soc-card.h"
#include "mtk-soundcard-driver.h"
static int set_card_codec_info(struct snd_soc_card *card,
......@@ -136,3 +138,200 @@ void clean_card_reference(struct snd_soc_card *card)
snd_soc_of_put_dai_link_codecs(dai_link);
}
EXPORT_SYMBOL_GPL(clean_card_reference);
int mtk_soundcard_startup(struct snd_pcm_substream *substream,
enum mtk_pcm_constraint_type ctype)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct mtk_soc_card_data *soc_card = snd_soc_card_get_drvdata(rtd->card);
const struct mtk_pcm_constraints_data *mpc = &soc_card->card_data->pcm_constraints[ctype];
int ret;
if (unlikely(!mpc))
return -EINVAL;
ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
mpc->rates);
if (ret < 0) {
dev_err(rtd->dev, "hw_constraint_list rate failed\n");
return ret;
}
ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
mpc->channels);
if (ret < 0) {
dev_err(rtd->dev, "hw_constraint_list channel failed\n");
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(mtk_soundcard_startup);
static int mtk_soundcard_playback_startup(struct snd_pcm_substream *substream)
{
return mtk_soundcard_startup(substream, MTK_CONSTRAINT_PLAYBACK);
}
const struct snd_soc_ops mtk_soundcard_common_playback_ops = {
.startup = mtk_soundcard_playback_startup,
};
EXPORT_SYMBOL_GPL(mtk_soundcard_common_playback_ops);
static int mtk_soundcard_capture_startup(struct snd_pcm_substream *substream)
{
return mtk_soundcard_startup(substream, MTK_CONSTRAINT_CAPTURE);
}
const struct snd_soc_ops mtk_soundcard_common_capture_ops = {
.startup = mtk_soundcard_capture_startup,
};
EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops);
int mtk_soundcard_common_probe(struct platform_device *pdev)
{
struct device_node *platform_node, *adsp_node;
const struct mtk_soundcard_pdata *pdata;
struct mtk_soc_card_data *soc_card_data;
struct snd_soc_dai_link *orig_dai_link, *dai_link;
struct snd_soc_jack *jacks;
struct snd_soc_card *card;
int i, orig_num_links, ret;
bool needs_legacy_probe;
pdata = device_get_match_data(&pdev->dev);
if (!pdata)
return -EINVAL;
card = pdata->card_data->card;
card->dev = &pdev->dev;
orig_dai_link = card->dai_link;
orig_num_links = card->num_links;
ret = snd_soc_of_parse_card_name(card, "model");
if (ret)
return ret;
if (!card->name) {
if (!pdata->card_name)
return -EINVAL;
card->name = pdata->card_name;
}
needs_legacy_probe = !of_property_read_bool(pdev->dev.of_node, "audio-routing");
if (needs_legacy_probe) {
/*
* If we have no .soc_probe() callback there's no way of using
* any legacy probe mechanism, as that cannot not be generic.
*/
if (!pdata->soc_probe)
return -EINVAL;
dev_info_once(&pdev->dev, "audio-routing not found: using legacy probe\n");
} else {
ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
if (ret)
return ret;
}
soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL);
if (!soc_card_data)
return -ENOMEM;
soc_card_data->card_data = pdata->card_data;
jacks = devm_kcalloc(card->dev, soc_card_data->card_data->num_jacks,
sizeof(*jacks), GFP_KERNEL);
if (!jacks)
return -ENOMEM;
soc_card_data->card_data->jacks = jacks;
platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
if (!platform_node)
return dev_err_probe(&pdev->dev, -EINVAL,
"Property mediatek,platform missing or invalid\n");
/* Check if this SoC has an Audio DSP */
if (pdata->sof_priv)
adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
else
adsp_node = NULL;
if (adsp_node) {
if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node,
"mediatek,dai-link",
card->dai_link, card->num_links);
if (ret) {
of_node_put(adsp_node);
of_node_put(platform_node);
return dev_err_probe(&pdev->dev, ret,
"Cannot parse mediatek,dai-link\n");
}
}
soc_card_data->sof_priv = pdata->sof_priv;
card->probe = mtk_sof_card_probe;
card->late_probe = mtk_sof_card_late_probe;
if (!card->topology_shortname_created) {
snprintf(card->topology_shortname, 32, "sof-%s", card->name);
card->topology_shortname_created = true;
}
card->name = card->topology_shortname;
}
/*
* Regardless of whether the ADSP is wanted and/or present in a machine
* specific device tree or not and regardless of whether any AFE_SOF
* link is present, we have to make sure that the platforms->of_node
* is not NULL, and set to either ADSP (adsp_node) or AFE (platform_node).
*/
for_each_card_prelinks(card, i, dai_link) {
if (adsp_node && !strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")))
dai_link->platforms->of_node = adsp_node;
else if (!dai_link->platforms->name && !dai_link->platforms->of_node)
dai_link->platforms->of_node = platform_node;
}
if (!needs_legacy_probe) {
ret = parse_dai_link_info(card);
if (ret)
goto err_restore_dais;
} else {
if (adsp_node)
of_node_put(adsp_node);
of_node_put(platform_node);
}
if (pdata->soc_probe) {
ret = pdata->soc_probe(soc_card_data, needs_legacy_probe);
if (ret) {
if (!needs_legacy_probe)
clean_card_reference(card);
goto err_restore_dais;
}
}
snd_soc_card_set_drvdata(card, soc_card_data);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (!needs_legacy_probe)
clean_card_reference(card);
if (ret) {
dev_err_probe(&pdev->dev, ret, "Cannot register card\n");
goto err_restore_dais;
}
return 0;
err_restore_dais:
card->dai_link = orig_dai_link;
card->num_links = orig_num_links;
return ret;
}
EXPORT_SYMBOL_GPL(mtk_soundcard_common_probe);
......@@ -9,6 +9,48 @@
#ifndef _MTK_SOUNDCARD_DRIVER_H_
#define _MTK_SOUNDCARD_DRIVER_H_
struct mtk_sof_priv;
struct mtk_soc_card_data;
struct snd_pcm_hw_constraint_list;
enum mtk_pcm_constraint_type {
MTK_CONSTRAINT_PLAYBACK,
MTK_CONSTRAINT_CAPTURE,
MTK_CONSTRAINT_HDMIDP,
MTK_CONSTRAINT_MAX
};
struct mtk_pcm_constraints_data {
const struct snd_pcm_hw_constraint_list *channels;
const struct snd_pcm_hw_constraint_list *rates;
};
struct mtk_platform_card_data {
struct snd_soc_card *card;
struct snd_soc_jack *jacks;
const struct mtk_pcm_constraints_data *pcm_constraints;
u8 num_jacks;
u8 num_pcm_constraints;
u8 flags;
};
struct mtk_soundcard_pdata {
const char *card_name;
struct mtk_platform_card_data *card_data;
const struct mtk_sof_priv *sof_priv;
int (*soc_probe)(struct mtk_soc_card_data *card_data, bool legacy);
};
/* Common playback/capture card startup ops */
extern const struct snd_soc_ops mtk_soundcard_common_playback_ops;
extern const struct snd_soc_ops mtk_soundcard_common_capture_ops;
/* Exported for custom/extended soundcard startup ops */
int mtk_soundcard_startup(struct snd_pcm_substream *substream,
enum mtk_pcm_constraint_type ctype);
int parse_dai_link_info(struct snd_soc_card *card);
void clean_card_reference(struct snd_soc_card *card);
int mtk_soundcard_common_probe(struct platform_device *pdev);
#endif
......@@ -704,18 +704,6 @@ static int mt6797_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt6797_afe_component_probe(struct snd_soc_component *component)
{
return mtk_afe_add_sub_dai_control(component);
}
static const struct snd_soc_component_driver mt6797_afe_component = {
.name = AFE_PCM_NAME,
.probe = mt6797_afe_component_probe,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
};
static int mt6797_dai_memif_register(struct mtk_base_afe *afe)
{
struct mtk_base_afe_dai *dai;
......@@ -852,7 +840,7 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
/* register component */
ret = devm_snd_soc_register_component(dev, &mt6797_afe_component,
ret = devm_snd_soc_register_component(dev, &mtk_afe_pcm_platform,
NULL, 0);
if (ret) {
dev_warn(dev, "err_platform\n");
......
......@@ -429,18 +429,6 @@ static int mt7986_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt7986_afe_component_probe(struct snd_soc_component *component)
{
return mtk_afe_add_sub_dai_control(component);
}
static const struct snd_soc_component_driver mt7986_afe_component = {
.name = AFE_PCM_NAME,
.probe = mt7986_afe_component_probe,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
};
static int mt7986_dai_memif_register(struct mtk_base_afe *afe)
{
struct mtk_base_afe_dai *dai;
......@@ -573,7 +561,7 @@ static int mt7986_afe_pcm_dev_probe(struct platform_device *pdev)
/* register component */
ret = devm_snd_soc_register_component(&pdev->dev,
&mt7986_afe_component,
&mtk_afe_pcm_platform,
NULL, 0);
if (ret)
return dev_err_probe(dev, ret, "Cannot register AFE component\n");
......
......@@ -1042,18 +1042,6 @@ static int mt8183_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt8183_afe_component_probe(struct snd_soc_component *component)
{
return mtk_afe_add_sub_dai_control(component);
}
static const struct snd_soc_component_driver mt8183_afe_component = {
.name = AFE_PCM_NAME,
.probe = mt8183_afe_component_probe,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
};
static int mt8183_dai_memif_register(struct mtk_base_afe *afe)
{
struct mtk_base_afe_dai *dai;
......@@ -1232,7 +1220,7 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
/* register component */
ret = devm_snd_soc_register_component(&pdev->dev,
&mt8183_afe_component,
&mtk_afe_pcm_platform,
NULL, 0);
if (ret) {
dev_warn(dev, "err_platform\n");
......
......@@ -18,5 +18,4 @@ snd-soc-mt8186-afe-objs := \
mt8186-mt6366-common.o
obj-$(CONFIG_SND_SOC_MT8186) += snd-soc-mt8186-afe.o
obj-$(CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357) += mt8186-mt6366-da7219-max98357.o
obj-$(CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S) += mt8186-mt6366-rt1019-rt5682s.o
obj-$(CONFIG_SND_SOC_MT8186_MT6366) += mt8186-mt6366.o
......@@ -3030,25 +3030,6 @@ static int mt8188_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt8188_afe_component_probe(struct snd_soc_component *component)
{
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
int ret;
snd_soc_component_init_regmap(component, afe->regmap);
ret = mtk_afe_add_sub_dai_control(component);
return ret;
}
static const struct snd_soc_component_driver mt8188_afe_component = {
.name = AFE_PCM_NAME,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
.probe = mt8188_afe_component_probe,
};
static int init_memif_priv_data(struct mtk_base_afe *afe)
{
struct mt8188_afe_private *afe_priv = afe->platform_priv;
......@@ -3350,7 +3331,7 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
}
/* register component */
ret = devm_snd_soc_register_component(dev, &mt8188_afe_component,
ret = devm_snd_soc_register_component(dev, &mtk_afe_pcm_platform,
afe->dai_drivers, afe->num_dai_drivers);
if (ret) {
dev_warn(dev, "err_platform\n");
......
This diff is collapsed.
......@@ -2125,22 +2125,6 @@ static int mt8192_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt8192_afe_component_probe(struct snd_soc_component *component)
{
return mtk_afe_add_sub_dai_control(component);
}
static const struct snd_soc_component_driver mt8192_afe_component = {
.name = AFE_PCM_NAME,
.probe = mt8192_afe_component_probe,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
};
static const struct snd_soc_component_driver mt8192_afe_pcm_component = {
.name = "mt8192-afe-pcm-dai",
};
static int mt8192_dai_memif_register(struct mtk_base_afe *afe)
{
struct mtk_base_afe_dai *dai;
......@@ -2302,16 +2286,11 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
/* register platform */
ret = devm_snd_soc_register_component(&pdev->dev,
&mt8192_afe_component, NULL, 0);
if (ret)
return dev_err_probe(dev, ret, "Couldn't register AFE component\n");
ret = devm_snd_soc_register_component(&pdev->dev,
&mt8192_afe_pcm_component,
&mtk_afe_pcm_platform,
afe->dai_drivers,
afe->num_dai_drivers);
if (ret)
return dev_err_probe(dev, ret, "Couldn't register AFE-PCM component\n");
return dev_err_probe(dev, ret, "Couldn't register AFE component\n");
return 0;
}
......
......@@ -2944,25 +2944,6 @@ static int mt8195_afe_runtime_resume(struct device *dev)
return 0;
}
static int mt8195_afe_component_probe(struct snd_soc_component *component)
{
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
int ret = 0;
snd_soc_component_init_regmap(component, afe->regmap);
ret = mtk_afe_add_sub_dai_control(component);
return ret;
}
static const struct snd_soc_component_driver mt8195_afe_component = {
.name = AFE_PCM_NAME,
.pointer = mtk_afe_pcm_pointer,
.pcm_construct = mtk_afe_pcm_new,
.probe = mt8195_afe_component_probe,
};
static int init_memif_priv_data(struct mtk_base_afe *afe)
{
struct mt8195_afe_private *afe_priv = afe->platform_priv;
......@@ -3164,7 +3145,7 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev)
}
/* register component */
ret = devm_snd_soc_register_component(dev, &mt8195_afe_component,
ret = devm_snd_soc_register_component(dev, &mtk_afe_pcm_platform,
afe->dai_drivers, afe->num_dai_drivers);
if (ret) {
dev_warn(dev, "err_platform\n");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment