diff options
Diffstat (limited to 'sound/soc/intel/common')
31 files changed, 3175 insertions, 1124 deletions
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index f7370e5b4e9e..7822bcae6c69 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-sst-dsp-objs := sst-dsp.o -snd-soc-sst-ipc-objs := sst-ipc.o -snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \ +snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \ soc-acpi-intel-hsw-bdw-match.o \ soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ @@ -12,8 +10,13 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \ soc-acpi-intel-arl-match.o \ soc-acpi-intel-lnl-match.o \ + soc-acpi-intel-ptl-match.o \ soc-acpi-intel-hda-match.o \ - soc-acpi-intel-sdw-mockup-match.o + soc-acpi-intel-sdw-mockup-match.o sof-function-topology-lib.o + +snd-soc-acpi-intel-match-y += soc-acpi-intel-ssp-common.o + +snd-soc-acpi-intel-sdca-quirks-y += soc-acpi-intel-sdca-quirks.o -obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o +obj-$(CONFIG_SND_SOC_ACPI_INTEL_SDCA_QUIRKS) += snd-soc-acpi-intel-sdca-quirks.o diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 0da79a3ba1f0..a68efbe98948 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -7,6 +7,7 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include <sound/soc-acpi-intel-ssp-common.h> static const struct snd_soc_acpi_codecs essx_83x6 = { .num_codecs = 3, @@ -34,6 +35,86 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = { + { + .adr = 0x00023201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00023301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = { + { + .adr = 0x00033001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00033101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { .adr = 0x000020025D071100ull, @@ -133,6 +214,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = { + { + .adr = 0x000232025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { { .adr = 0x000130025D131601ull, @@ -415,6 +505,25 @@ static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = { } }; +static const struct snd_soc_acpi_link_adr adl_cs42l43_l0_cs35l56_l23[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_r_adr), + .adr_d = cs35l56_2_r_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_l_adr), + .adr_d = cs35l56_3_l_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr adl_rvp[] = { { .mask = BIT(0), @@ -447,9 +556,18 @@ static const struct snd_soc_acpi_link_adr adl_chromebook_base[] = { {} }; -static const struct snd_soc_acpi_codecs adl_max98373_amp = { - .num_codecs = 1, - .codecs = {"MX98373"} +static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link02[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt1316_0_group2_adr), + .adr_d = rt1316_0_group2_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group2_adr), + .adr_d = rt1316_2_group2_adr, + }, + {} }; static const struct snd_soc_acpi_codecs adl_max98357a_amp = { @@ -457,19 +575,9 @@ static const struct snd_soc_acpi_codecs adl_max98357a_amp = { .codecs = {"MX98357A"} }; -static const struct snd_soc_acpi_codecs adl_max98360a_amp = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - static const struct snd_soc_acpi_codecs adl_rt5682_rt5682s_hp = { .num_codecs = 2, - .codecs = {"10EC5682", "RTL5682"}, -}; - -static const struct snd_soc_acpi_codecs adl_rt1015p_amp = { - .num_codecs = 1, - .codecs = {"RTL1015"} + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, }; static const struct snd_soc_acpi_codecs adl_rt1019p_amp = { @@ -477,49 +585,20 @@ static const struct snd_soc_acpi_codecs adl_rt1019p_amp = { .codecs = {"RTL1019"} }; -static const struct snd_soc_acpi_codecs adl_max98390_amp = { - .num_codecs = 1, - .codecs = {"MX98390"} -}; - static const struct snd_soc_acpi_codecs adl_lt6911_hdmi = { .num_codecs = 1, .codecs = {"INTC10B0"} }; -static const struct snd_soc_acpi_codecs adl_nau8318_amp = { - .num_codecs = 1, - .codecs = {"NVTN2012"} -}; - -static struct snd_soc_acpi_codecs adl_rt5650_amp = { - .num_codecs = 1, - .codecs = {"10EC5650"} -}; - struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { { .comp_ids = &adl_rt5682_rt5682s_hp, - .drv_name = "adl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98373_amp, - .sof_tplg_filename = "sof-adl-max98373-rt5682.tplg", - }, - { - .comp_ids = &adl_rt5682_rt5682s_hp, .drv_name = "adl_mx98357_rt5682", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_max98357a_amp, .sof_tplg_filename = "sof-adl-max98357a-rt5682.tplg", }, { - .comp_ids = &adl_rt5682_rt5682s_hp, - .drv_name = "adl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98360a_amp, - .sof_tplg_filename = "sof-adl-max98360a-rt5682.tplg", - }, - { .id = "10508825", .drv_name = "adl_rt1019p_8825", .machine_quirk = snd_soc_acpi_codec_list, @@ -527,53 +606,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .sof_tplg_filename = "sof-adl-rt1019-nau8825.tplg", }, { - .id = "10508825", - .drv_name = "adl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98373_amp, - .sof_tplg_filename = "sof-adl-max98373-nau8825.tplg", - }, - { - .id = "10508825", - .drv_name = "adl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98360a_amp, - .sof_tplg_filename = "sof-adl-max98360a-nau8825.tplg", - }, - { - .comp_ids = &adl_rt5682_rt5682s_hp, - .drv_name = "adl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_rt1019p_amp, - .sof_tplg_filename = "sof-adl-rt1019-rt5682.tplg", - }, - { - .id = "10508825", - .drv_name = "adl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_rt1015p_amp, - .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg", - }, - { - .id = "10508825", - .drv_name = "adl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_nau8318_amp, - .sof_tplg_filename = "sof-adl-nau8318-nau8825.tplg", - }, - { - .id = "10508825", - .drv_name = "sof_nau8825", - .sof_tplg_filename = "sof-adl-nau8825.tplg", - }, - { - .comp_ids = &adl_rt5682_rt5682s_hp, - .drv_name = "adl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98390_amp, - .sof_tplg_filename = "sof-adl-max98390-rt5682.tplg", - }, - { .comp_ids = &adl_rt5682_rt5682s_hp, .drv_name = "adl_rt5682_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, @@ -581,18 +613,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .sof_tplg_filename = "sof-adl-rt5682-ssp1-hdmi-ssp02.tplg", }, { - .comp_ids = &adl_rt5682_rt5682s_hp, - .drv_name = "adl_rt5682_def", - .sof_tplg_filename = "sof-adl-rt5682.tplg", - }, - { - .id = "10134242", - .drv_name = "adl_mx98360a_cs4242", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98360a_amp, - .sof_tplg_filename = "sof-adl-max98360a-cs42l42.tplg", - }, - { .comp_ids = &essx_83x6, .drv_name = "adl_es83x6_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, @@ -607,19 +627,43 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + /* place boards for each headphone codec: sof driver will complete the + * tplg name and machine driver will detect the amp type + */ + { + .id = CS42L42_ACPI_HID, + .drv_name = "adl_cs42l42_def", + .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = DA7219_ACPI_HID, + .drv_name = "adl_da7219_def", + .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, { - .id = "10EC5650", + .id = NAU8825_ACPI_HID, + .drv_name = "adl_nau8825_def", + .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = RT5650_ACPI_HID, .drv_name = "adl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_rt5650_amp, - .sof_tplg_filename = "sof-adl-rt5650.tplg", + .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, }, { - .id = "DLGS7219", - .drv_name = "adl_mx98360_da7219", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &adl_max98360a_amp, - .sof_tplg_filename = "sof-adl-max98360a-da7219.tplg", + .comp_ids = &adl_rt5682_rt5682s_hp, + .drv_name = "adl_rt5682_def", + .sof_tplg_filename = "sof-adl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, }, /* place amp-only boards in the end of table */ { @@ -639,6 +683,12 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines); /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = adl_cs42l43_l0_cs35l56_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-cs42l43-l0-cs35l56-l23.tplg", + }, + { .link_mask = 0xF, /* 4 active links required */ .links = adl_default, .drv_name = "sof_sdw", @@ -722,6 +772,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-adl-sdw-max98373-rt5682.tplg", }, + { + .link_mask = BIT(0) | BIT(2), + .links = adl_sdw_rt1316_link02, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-rt1316-l02.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-arl-match.c b/sound/soc/intel/common/soc-acpi-intel-arl-match.c index e52797aae6e6..73e581e93755 100644 --- a/sound/soc/intel/common/soc-acpi-intel-arl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-arl-match.c @@ -7,6 +7,8 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include <sound/soc-acpi-intel-ssp-common.h> +#include "sof-function-topology-lib.h" static const struct snd_soc_acpi_endpoint single_endpoint = { .num = 0, @@ -15,6 +17,200 @@ static const struct snd_soc_acpi_endpoint single_endpoint = { .group_id = 0, }; +static const struct snd_soc_acpi_endpoint spk_l_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + +/* + * RT722 is a multi-function codec, three endpoints are created for + * its headset, amp and dmic functions. + */ +static const struct snd_soc_acpi_endpoint rt722_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_lr_adr[] = { + { + .adr = 0x00023001FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00023101FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = { + { + .adr = 0x00033001FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00033401FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = { + { + .adr = 0x00023201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00023301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = { + { + .adr = 0x00033001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00033101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_r1_adr[] = { + { + .adr = 0x00023101FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_l3_adr[] = { + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_r3_adr[] = { + { + .adr = 0x00023301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_l1_adr[] = { + { + .adr = 0x00033101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, +}; + +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { + { + .adr = 0x00023001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { .adr = 0x000020025D071100ull, @@ -24,6 +220,136 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + { + .adr = 0x000030025D072201ull, + .num_endpoints = ARRAY_SIZE(rt722_endpoints), + .endpoints = rt722_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_2_single_adr[] = { + { + .adr = 0x000230025D132001ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l2_cs35l56_l3[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_lr_adr), + .adr_d = cs35l56_3_lr_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l2[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_lr_adr), + .adr_d = cs35l56_2_lr_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l23[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_r_adr), + .adr_d = cs35l56_2_r_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_l_adr), + .adr_d = cs35l56_3_l_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_2_l23[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_r1_adr), + .adr_d = cs35l56_2_r1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_l3_adr), + .adr_d = cs35l56_3_l3_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_3_l23[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_r3_adr), + .adr_d = cs35l56_2_r3_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_l1_adr), + .adr_d = cs35l56_3_l1_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr arl_rvp[] = { { .mask = BIT(0), @@ -33,7 +359,73 @@ static const struct snd_soc_acpi_link_adr arl_rvp[] = { {} }; +static const struct snd_soc_acpi_link_adr arl_sdca_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr arl_rt722_l0_rt1320_l2[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1320_2_single_adr), + .adr_d = rt1320_2_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_codecs arl_essx_83x6 = { + .num_codecs = 3, + .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, +}; + +static const struct snd_soc_acpi_codecs arl_rt5682_hp = { + .num_codecs = 2, + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, +}; + +static const struct snd_soc_acpi_codecs arl_lt6911_hdmi = { + .num_codecs = 1, + .codecs = {"INTC10B0"} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[] = { + { + .comp_ids = &arl_essx_83x6, + .drv_name = "arl_es83x6_c1_h02", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &arl_lt6911_hdmi, + .sof_tplg_filename = "sof-arl-es83x6-ssp1-hdmi-ssp02.tplg", + }, + { + .comp_ids = &arl_essx_83x6, + .drv_name = "sof-essx8336", + .sof_tplg_filename = "sof-arl-es8336", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER | + SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | + SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, + }, + { + .comp_ids = &arl_rt5682_hp, + .drv_name = "arl_rt5682_c1_h02", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &arl_lt6911_hdmi, + .sof_tplg_filename = "sof-arl-rt5682-ssp1-hdmi-ssp02.tplg", + }, + /* place amp-only boards in the end of table */ + { + .id = "INTC10B0", + .drv_name = "arl_lt6911_hdmi_ssp", + .sof_tplg_filename = "sof-arl-hdmi-ssp02.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines); @@ -41,11 +433,73 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines); /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = arl_cs42l43_l0_cs35l56_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = arl_cs42l43_l0_cs35l56_2_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = arl_cs42l43_l0_cs35l56_3_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0) | BIT(2), + .links = arl_cs42l43_l0_cs35l56_l2, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0), + .links = arl_cs42l43_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(2), + .links = arl_cs42l43_l2, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(2) | BIT(3), + .links = arl_cs42l43_l2_cs35l56_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { .link_mask = 0x1, /* link0 required */ .links = arl_rvp, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-rt711.tplg", }, + { + .link_mask = 0x1, /* link0 required */ + .links = arl_sdca_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-rt711-l0.tplg", + }, + { + .link_mask = BIT(0) | BIT(2), + .links = arl_rt722_l0_rt1320_l2, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c index 5e2ec60e2954..e4c3492a0c28 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c @@ -84,7 +84,6 @@ static const struct dmi_system_id lenovo_yoga_tab3_x90[] = { /* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), }, }, diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c index 5eab17820532..f79d7558174a 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -42,40 +42,40 @@ static const struct snd_soc_acpi_codecs max98390_spk_codecs = { struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = { { .id = "10EC5682", - .drv_name = "cml_rt1011_rt5682", + .drv_name = "cml_rt5682_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &rt1011_spk_codecs, .sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg", }, { .id = "10EC5682", - .drv_name = "cml_rt1015_rt5682", + .drv_name = "cml_rt5682_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &rt1015_spk_codecs, .sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg", }, { .id = "10EC5682", - .drv_name = "sof_rt5682", + .drv_name = "cml_rt5682_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &max98357a_spk_codecs, .sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg", }, { .id = "10EC5682", - .drv_name = "sof_rt5682", + .drv_name = "cml_rt5682_def", .sof_tplg_filename = "sof-cml-rt5682.tplg", }, { .id = "DLGS7219", - .drv_name = "cml_da7219_mx98357a", + .drv_name = "cml_da7219_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &max98357a_spk_codecs, .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg", }, { .id = "DLGS7219", - .drv_name = "cml_da7219_mx98357a", + .drv_name = "cml_da7219_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &max98390_spk_codecs, .sof_tplg_filename = "sof-cml-da7219-max98390.tplg", diff --git a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c index 3df89e4511da..8bbb1052faf2 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c @@ -8,7 +8,6 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" #include "soc-acpi-intel-sdw-mockup-match.h" static const struct snd_soc_acpi_codecs essx_83x6 = { @@ -16,16 +15,11 @@ static const struct snd_soc_acpi_codecs essx_83x6 = { .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, }; -static struct skl_machine_pdata cnl_pdata = { - .use_tplg_pcm = true, -}; - struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { { .id = "INT34C2", .drv_name = "cnl_rt274", .fw_filename = "intel/dsp_fw_cnl.bin", - .pdata = &cnl_pdata, .sof_tplg_filename = "sof-cnl-rt274.tplg", }, { diff --git a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c index 84639c41a268..78255d56b08c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ehl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ehl-match.c @@ -8,7 +8,6 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[] = { { diff --git a/sound/soc/intel/common/soc-acpi-intel-glk-match.c b/sound/soc/intel/common/soc-acpi-intel-glk-match.c index 8911c90bbaf6..c82c8c93d200 100644 --- a/sound/soc/intel/common/soc-acpi-intel-glk-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-glk-match.c @@ -33,7 +33,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { }, { .id = "DLGS7219", - .drv_name = "glk_da7219_mx98357a", + .drv_name = "glk_da7219_def", .fw_filename = "intel/dsp_fw_glk.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &glk_codecs, @@ -41,7 +41,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = { }, { .comp_ids = &glk_rt5682_rt5682s_hp, - .drv_name = "glk_rt5682_mx98357a", + .drv_name = "glk_rt5682_def", .fw_filename = "intel/dsp_fw_glk.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &glk_codecs, diff --git a/sound/soc/intel/common/soc-acpi-intel-hda-match.c b/sound/soc/intel/common/soc-acpi-intel-hda-match.c index 2017fd0d676f..e93336e27beb 100644 --- a/sound/soc/intel/common/soc-acpi-intel-hda-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-hda-match.c @@ -8,27 +8,13 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" - -static struct skl_machine_pdata hda_pdata = { - .use_tplg_pcm = true, -}; struct snd_soc_acpi_mach snd_soc_acpi_intel_hda_machines[] = { { /* .id is not used in this file */ .drv_name = "skl_hda_dsp_generic", - - /* .fw_filename is dynamically set in skylake driver */ - - .sof_tplg_filename = "sof-hda-generic.tplg", - - /* - * .machine_quirk and .quirk_data are not used here but - * can be used if we need a more complicated machine driver - * combining HDA+other device (e.g. DMIC). - */ - .pdata = &hda_pdata, + .sof_tplg_filename = "sof-hda-generic", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, {}, }; diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c index d0062f2cd256..6ce75fbb842e 100644 --- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c @@ -8,28 +8,22 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" static const struct snd_soc_acpi_codecs essx_83x6 = { .num_codecs = 3, .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, }; -static struct skl_machine_pdata icl_pdata = { - .use_tplg_pcm = true, -}; - struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = { { .id = "INT34C2", .drv_name = "icl_rt274", .fw_filename = "intel/dsp_fw_icl.bin", - .pdata = &icl_pdata, .sof_tplg_filename = "sof-icl-rt274.tplg", }, { .id = "10EC5682", - .drv_name = "sof_rt5682", + .drv_name = "icl_rt5682_def", .sof_tplg_filename = "sof-icl-rt5682.tplg", }, { diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c index a6ac2525df17..d4b397c53bcc 100644 --- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c @@ -52,14 +52,14 @@ static const struct snd_soc_acpi_codecs rt5682_rt5682s_hp = { struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { { .id = "DLGS7219", - .drv_name = "jsl_mx98373_da7219", + .drv_name = "jsl_da7219_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &mx98373_spk, .sof_tplg_filename = "sof-jsl-da7219.tplg", }, { .id = "DLGS7219", - .drv_name = "jsl_mx98360_da7219", + .drv_name = "jsl_da7219_def", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &mx98360a_spk, .sof_tplg_filename = "sof-jsl-da7219-mx98360a.tplg", diff --git a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c index 4e817f559d38..d4c158d8441b 100644 --- a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c @@ -8,9 +8,6 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" - -static struct skl_machine_pdata skl_dmic_data; static const struct snd_soc_acpi_codecs kbl_codecs = { .num_codecs = 1, @@ -54,7 +51,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_codecs, - .pdata = &skl_dmic_data, }, { .id = "MX98357A", @@ -62,7 +58,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_codecs, - .pdata = &skl_dmic_data, }, { .id = "MX98927", @@ -70,7 +65,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_5663_5514_codecs, - .pdata = &skl_dmic_data, }, { .id = "MX98927", @@ -78,7 +72,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_poppy_codecs, - .pdata = &skl_dmic_data, }, { .id = "10EC5663", @@ -91,7 +84,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_7219_98357_codecs, - .pdata = &skl_dmic_data, }, { .id = "DLGS7219", @@ -99,7 +91,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_7219_98927_codecs, - .pdata = &skl_dmic_data }, { .id = "10EC5660", @@ -117,13 +108,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = { .fw_filename = "intel/dsp_fw_kbl.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &kbl_7219_98373_codecs, - .pdata = &skl_dmic_data }, { .id = "MX98373", .drv_name = "kbl_max98373", .fw_filename = "intel/dsp_fw_kbl.bin", - .pdata = &skl_dmic_data }, {}, }; diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c index 74d6dcd7471f..558dc4c91239 100644 --- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c @@ -2,12 +2,14 @@ /* * soc-acpi-intel-lnl-match.c - tables and support for LNL ACPI enumeration. * - * Copyright (c) 2023, Intel Corporation. All rights reserved. + * Copyright (c) 2023, Intel Corporation * */ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include "sof-function-topology-lib.h" +#include "soc-acpi-intel-sdca-quirks.h" #include "soc-acpi-intel-sdw-mockup-match.h" struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[] = { @@ -36,6 +38,48 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint spk_1_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_4_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_5_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_6_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, +}; + static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { { .num = 0, @@ -76,6 +120,206 @@ static const struct snd_soc_acpi_endpoint rt722_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* DMIC Endpoint */ + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* Amp Endpoint, work as spk_l_endpoint */ + { + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + /* DMIC Endpoint */ + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_l_adr[] = { + { + .adr = 0x00023001FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00023101FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_r_adr[] = { + { + .adr = 0x00033201fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = { + { + .adr = 0x00033001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00033101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = { + { + .adr = 0x00013001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_1_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013201fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP3" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_4_endpoint, + .name_prefix = "AMP4" + }, + { + .adr = 0x00033401fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_5_endpoint, + .name_prefix = "AMP5" + }, + { + .adr = 0x00033501fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_6_endpoint, + .name_prefix = "AMP6" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { + { + .adr = 0x00023001fa424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints), + .endpoints = cs42l43_amp_spkagg_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -103,6 +347,15 @@ static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_vb_2_group1_adr[] = { + { + .adr = 0x000230025D071201ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints, + .name_prefix = "rt712" + } +}; + static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { { .adr = 0x000030025d072201ull, @@ -130,6 +383,87 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1318_1_adr[] = { + { + .adr = 0x000133025D131801ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1318-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { + { + .adr = 0x000130025D131801ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1318-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1318_2_group1_adr[] = { + { + .adr = 0x000232025D131801ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1318-2" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_1_group1_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_1_group2_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = { + { + .adr = 0x000330025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-2" + } +}; + +static const struct snd_soc_acpi_adr_device rt713_0_adr[] = { + { + .adr = 0x000031025D071301ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt713" + } +}; + +static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = { + { + .adr = 0x000230025d071301ull, + .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints), + .endpoints = jack_dmic_endpoints, + .name_prefix = "rt713" + } +}; + +static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { + { + .adr = 0x000030025D071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + static const struct snd_soc_acpi_adr_device rt714_1_adr[] = { { .adr = 0x000130025D071401ull, @@ -139,6 +473,67 @@ static const struct snd_soc_acpi_adr_device rt714_1_adr[] = { } }; +static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_lr_adr), + .adr_d = cs35l56_3_lr_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l23[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_l_adr), + .adr_d = cs35l56_2_l_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_r_adr), + .adr_d = cs35l56_3_r_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_cs42l43_l2_cs35l56x6_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr), + .adr_d = cs35l56_1_3amp_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr), + .adr_d = cs35l56_3_3amp_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr lnl_rvp[] = { { .mask = BIT(0), @@ -195,6 +590,73 @@ static const struct snd_soc_acpi_link_adr lnl_3_in_1_sdca[] = { {} }; +static const struct snd_soc_acpi_link_adr lnl_sdw_rt1318_l12_rt714_l0[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_group1_adr), + .adr_d = rt1318_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1318_2_group1_adr), + .adr_d = rt1318_2_group1_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt714_0_adr), + .adr_d = rt714_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_l0_rt1318_l1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt713_0_adr), + .adr_d = rt713_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_adr), + .adr_d = rt1318_1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_vb_l2_rt1320_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt713_vb_2_adr), + .adr_d = rt713_vb_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group2_adr), + .adr_d = rt1320_1_group2_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1320_3_group2_adr), + .adr_d = rt1320_3_group2_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr lnl_sdw_rt712_vb_l2_rt1320_l1[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt712_vb_2_group1_adr), + .adr_d = rt712_vb_2_group1_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group1_adr), + .adr_d = rt1320_1_group1_adr, + }, + {} +}; + +/* this table is used when there is no I2S codec present */ /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { /* mockup tests need to be first */ @@ -217,12 +679,43 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { .sof_tplg_filename = "sof-lnl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = BIT(0), + .links = sdw_mockup_multi_func, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt722-l0.tplg", /* Reuse the existing tplg file */ + }, + { .link_mask = GENMASK(3, 0), .links = lnl_3_in_1_sdca, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-lnl-rt711-l0-rt1316-l23-rt714-l1.tplg", }, { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = lnl_cs42l43_l0_cs35l56_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l23.tplg", + }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = lnl_cs42l43_l2_cs35l56x6_l13, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-cs42l43-l2-cs35l56x6-l13.tplg", + }, + { + .link_mask = BIT(0) | BIT(3), + .links = lnl_cs42l43_l0_cs35l56_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l3.tplg", + }, + { + .link_mask = BIT(0), + .links = lnl_cs42l43_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-cs42l43-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { .link_mask = BIT(0), .links = lnl_rvp, .drv_name = "sof_sdw", @@ -239,6 +732,35 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { .links = lnl_rt722_only, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-lnl-rt722-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = GENMASK(2, 0), + .links = lnl_sdw_rt1318_l12_rt714_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt1318-l12-rt714-l0.tplg" + }, + { + .link_mask = BIT(0) | BIT(1), + .links = lnl_sdw_rt713_l0_rt1318_l1, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt713-l0-rt1318-l1.tplg" + }, + { + .link_mask = BIT(1) | BIT(2), + .links = lnl_sdw_rt712_vb_l2_rt1320_l1, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-lnl-rt712-l2-rt1320-l1.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = lnl_sdw_rt713_vb_l2_rt1320_l13, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-lnl-rt713-l2-rt1320-l13.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, {}, }; diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index e9a5da079089..75dc8935a794 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -6,28 +6,18 @@ * */ +#include <linux/soundwire/sdw_intel.h> +#include <sound/sdca.h> #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include <sound/soc-acpi-intel-ssp-common.h> +#include "sof-function-topology-lib.h" +#include "soc-acpi-intel-sdca-quirks.h" #include "soc-acpi-intel-sdw-mockup-match.h" -static const struct snd_soc_acpi_codecs mtl_max98357a_amp = { - .num_codecs = 1, - .codecs = {"MX98357A"} -}; - -static const struct snd_soc_acpi_codecs mtl_max98360a_amp = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -static const struct snd_soc_acpi_codecs mtl_rt1019p_amp = { - .num_codecs = 1, - .codecs = {"RTL1019"} -}; - static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = { .num_codecs = 2, - .codecs = {"10EC5682", "RTL5682"}, + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, }; static const struct snd_soc_acpi_codecs mtl_essx_83x6 = { @@ -40,34 +30,8 @@ static const struct snd_soc_acpi_codecs mtl_lt6911_hdmi = { .codecs = {"INTC10B0"} }; -static const struct snd_soc_acpi_codecs mtl_rt5650_amp = { - .num_codecs = 1, - .codecs = {"10EC5650"} -}; - struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { { - .comp_ids = &mtl_rt5682_rt5682s_hp, - .drv_name = "mtl_mx98357_rt5682", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &mtl_max98357a_amp, - .sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg", - }, - { - .comp_ids = &mtl_rt5682_rt5682s_hp, - .drv_name = "mtl_mx98360_rt5682", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &mtl_max98360a_amp, - .sof_tplg_filename = "sof-mtl-max98360a-rt5682.tplg", - }, - { - .comp_ids = &mtl_rt5682_rt5682s_hp, - .drv_name = "mtl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &mtl_rt1019p_amp, - .sof_tplg_filename = "sof-mtl-rt1019-rt5682.tplg", - }, - { .comp_ids = &mtl_essx_83x6, .drv_name = "mtl_es83x6_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, @@ -83,11 +47,49 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, { - .id = "10EC5650", - .drv_name = "mtl_rt5682_def", + .comp_ids = &mtl_rt5682_rt5682s_hp, + .drv_name = "mtl_rt5682_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &mtl_rt5650_amp, - .sof_tplg_filename = "sof-mtl-rt5650.tplg", + .quirk_data = &mtl_lt6911_hdmi, + .sof_tplg_filename = "sof-mtl-rt5682-ssp1-hdmi-ssp02.tplg", + }, + /* place boards for each headphone codec: sof driver will complete the + * tplg name and machine driver will detect the amp type + */ + { + .id = CS42L42_ACPI_HID, + .drv_name = "mtl_cs42l42_def", + .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = DA7219_ACPI_HID, + .drv_name = "mtl_da7219_def", + .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = NAU8825_ACPI_HID, + .drv_name = "mtl_nau8825_def", + .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = RT5650_ACPI_HID, + .drv_name = "mtl_rt5682_def", + .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .comp_ids = &mtl_rt5682_rt5682s_hp, + .drv_name = "mtl_rt5682_def", + .sof_tplg_filename = "sof-mtl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, }, /* place amp-only boards in the end of table */ { @@ -135,6 +137,27 @@ static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint rt712_vb_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + /* * RT722 is a multi-function codec, three endpoints are created for * its headset, amp and dmic functions. @@ -192,6 +215,15 @@ static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_vb_0_single_adr[] = { + { + .adr = 0x000030025D071201ull, + .num_endpoints = ARRAY_SIZE(rt712_vb_endpoints), + .endpoints = rt712_vb_endpoints, + .name_prefix = "rt712" + } +}; + static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = { { .adr = 0x000330025D171201ull, @@ -288,6 +320,24 @@ static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_3_single_adr[] = { + { + .adr = 0x000330025D131601ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1316-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1318_1_single_adr[] = { + { + .adr = 0x000130025D131801ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1318-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { { .adr = 0x000130025D131801ull, @@ -324,7 +374,7 @@ static const struct snd_soc_acpi_adr_device rt714_1_adr[] = { } }; -static const struct snd_soc_acpi_link_adr mtl_712_only[] = { +static const struct snd_soc_acpi_link_adr mtl_712_l0_1712_l3[] = { { .mask = BIT(0), .num_adr = ARRAY_SIZE(rt712_0_single_adr), @@ -338,27 +388,245 @@ static const struct snd_soc_acpi_link_adr mtl_712_only[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_712_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_0_single_adr), + .adr_d = rt712_0_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr mtl_712_vb_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_vb_0_single_adr), + .adr_d = rt712_vb_0_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { { .adr = 0x00003001FA424301ull, - .num_endpoints = 1, - .endpoints = &single_endpoint, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, .name_prefix = "cs42l43" } }; +/* CS42L43 - speaker DAI aggregated with 4 amps */ +static const struct snd_soc_acpi_endpoint cs42l43_4amp_spkagg_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 1, + .group_position = 4, + .group_id = 1, + }, +}; + +/* CS42L43 on link3 aggregated with 4 amps */ +static const struct snd_soc_acpi_adr_device cs42l43_l3_4amp_spkagg_adr[] = { + { + .adr = 0x00033001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_4amp_spkagg_endpoints), + .endpoints = cs42l43_4amp_spkagg_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_endpoint cs35l56_l_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_r_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 1, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_2_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 2, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_3_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 3, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_4_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 4, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_5_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 5, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_6_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 6, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_7_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 7, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 7, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_0_adr[] = { + { + .adr = 0x00003301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00003201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + } +}; + static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = { { .adr = 0x00013701FA355601ull, .num_endpoints = 1, .endpoints = &spk_r_endpoint, - .name_prefix = "AMP8" + .name_prefix = "AMP3" }, { .adr = 0x00013601FA355601ull, .num_endpoints = 1, .endpoints = &spk_3_endpoint, - .name_prefix = "AMP7" + .name_prefix = "AMP4" } }; @@ -377,17 +645,71 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device cs35l56_0_fb_adr[] = { + { + .adr = 0x00003301FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints), + .endpoints = cs35l56_l_fb_endpoints, + .name_prefix = "AMP1" + }, + { + .adr = 0x00003201FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints), + .endpoints = cs35l56_2_fb_endpoints, + .name_prefix = "AMP2" + }, + { + .adr = 0x00003101FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_4_fb_endpoints), + .endpoints = cs35l56_4_fb_endpoints, + .name_prefix = "AMP3" + }, + { + .adr = 0x00003001FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_6_fb_endpoints), + .endpoints = cs35l56_6_fb_endpoints, + .name_prefix = "AMP4" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_1_fb_adr[] = { + { + .adr = 0x00013701FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints), + .endpoints = cs35l56_r_fb_endpoints, + .name_prefix = "AMP8" + }, + { + .adr = 0x00013601FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints), + .endpoints = cs35l56_3_fb_endpoints, + .name_prefix = "AMP7" + }, + { + .adr = 0x00013501FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_5_fb_endpoints), + .endpoints = cs35l56_5_fb_endpoints, + .name_prefix = "AMP6" + }, + { + .adr = 0x00013401FA355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_7_fb_endpoints), + .endpoints = cs35l56_7_fb_endpoints, + .name_prefix = "AMP5" + }, +}; + static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = { { .adr = 0x00023201FA355601ull, - .num_endpoints = 1, - .endpoints = &spk_r_endpoint, + .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints), + .endpoints = cs35l56_r_fb_endpoints, .name_prefix = "AMP3" }, { .adr = 0x00023301FA355601ull, - .num_endpoints = 1, - .endpoints = &spk_3_endpoint, + .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints), + .endpoints = cs35l56_3_fb_endpoints, .name_prefix = "AMP4" } @@ -396,18 +718,36 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = { static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = { { .adr = 0x00033001fa355601ull, - .num_endpoints = 1, - .endpoints = &spk_l_endpoint, + .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints), + .endpoints = cs35l56_l_fb_endpoints, .name_prefix = "AMP1" }, { .adr = 0x00033101fa355601ull, - .num_endpoints = 1, - .endpoints = &spk_2_endpoint, + .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints), + .endpoints = cs35l56_2_fb_endpoints, .name_prefix = "AMP2" } }; +static const struct snd_soc_acpi_adr_device cs35l63_1_fb_adr[] = { + { + .adr = 0x00013001FA356301ull, + .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints), + .endpoints = cs35l56_l_fb_endpoints, + .name_prefix = "AMP1" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l63_3_fb_adr[] = { + { + .adr = 0x00033101FA356301ull, + .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints), + .endpoints = cs35l56_r_fb_endpoints, + .name_prefix = "AMP2" + }, +}; + static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = { /* Expected order: jack -> amp */ { @@ -508,6 +848,49 @@ static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12_rt1713_l3[] = {} }; +static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1318_l1_rt1713_l3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt713_0_single_adr), + .adr_d = rt713_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_single_adr), + .adr_d = rt1318_1_single_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1713_3_single_adr), + .adr_d = rt1713_3_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1318_l12_rt1713_l3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt713_0_single_adr), + .adr_d = rt713_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_group1_adr), + .adr_d = rt1318_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1318_2_group1_adr), + .adr_d = rt1318_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1713_3_single_adr), + .adr_d = rt1713_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12[] = { { .mask = BIT(0), @@ -527,6 +910,20 @@ static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_rt711_l0_rt1316_l3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1316_3_single_adr), + .adr_d = rt1316_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = { { .adr = 0x000230019F836300ull, @@ -566,6 +963,15 @@ static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_cs42l43_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr mtl_cs42l43_cs35l56[] = { { .mask = BIT(0), @@ -605,6 +1011,54 @@ static const struct snd_soc_acpi_link_adr cs42l43_link0_cs35l56_link2_link3[] = {} }; +static const struct snd_soc_acpi_link_adr cs42l43_link3_cs35l56_x4_link0_link1_spkagg[] = { + /* Expected order: jack -> amp */ + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs42l43_l3_4amp_spkagg_adr), + .adr_d = cs42l43_l3_4amp_spkagg_adr, + }, + { + .mask = BIT(1), + .num_adr = 2, + .adr_d = cs35l56_1_adr, + }, + { + .mask = BIT(0), + .num_adr = 2, + .adr_d = cs35l56_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr mtl_cs35l56_x8_link0_link1_fb[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_fb_adr), + .adr_d = cs35l56_1_fb_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs35l56_0_fb_adr), + .adr_d = cs35l56_0_fb_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr mtl_cs35l63_x2_link1_link3_fb[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l63_3_fb_adr), + .adr_d = cs35l63_3_fb_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l63_1_fb_adr), + .adr_d = cs35l63_1_fb_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { /* mockup tests need to be first */ @@ -633,6 +1087,18 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt713-l0-rt1316-l12-rt1713-l3.tplg", }, { + .link_mask = GENMASK(3, 0), + .links = mtl_rt713_l0_rt1318_l12_rt1713_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt713-l0-rt1318-l12-rt1713-l3.tplg", + }, + { + .link_mask = BIT(0) | BIT(1) | BIT(3), + .links = mtl_rt713_l0_rt1318_l1_rt1713_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt713-l0-rt1318-l1-rt1713-l3.tplg", + }, + { .link_mask = GENMASK(2, 0), .links = mtl_rt713_l0_rt1316_l12, .drv_name = "sof_sdw", @@ -640,11 +1106,26 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { }, { .link_mask = BIT(3) | BIT(0), - .links = mtl_712_only, + .links = mtl_712_l0_1712_l3, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-rt712-l0-rt1712-l3.tplg", }, { + .link_mask = BIT(0), + .links = mtl_712_vb_l0, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-mtl-rt712-vb-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0), + .links = mtl_712_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt712-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { .link_mask = GENMASK(2, 0), .links = mtl_sdw_rt1318_l12_rt714_l0, .drv_name = "sof_sdw", @@ -655,12 +1136,41 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .links = cs42l43_link0_cs35l56_link2_link3, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0) | BIT(1) | BIT(3), + .links = cs42l43_link3_cs35l56_x4_link0_link1_spkagg, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-cs42l43-l3-cs35l56-l01-spkagg.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = GENMASK(2, 0), .links = mtl_cs42l43_cs35l56, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l12.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0) | BIT(1), + .links = mtl_cs35l56_x8_link0_link1_fb, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-cs35l56-l01-fb8.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0), + .links = mtl_cs42l43_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-cs42l43-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(1) | BIT(3), + .links = mtl_cs35l63_x2_link1_link3_fb, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-cs35l56-l01-fb8.tplg", }, { .link_mask = GENMASK(3, 0), @@ -669,10 +1179,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt711-l0-rt1316-l23-rt714-l1.tplg", }, { + .link_mask = 0x9, /* 2 active links required */ + .links = mtl_rt711_l0_rt1316_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt711-l0-rt1316-l3.tplg", + }, + { .link_mask = BIT(0), .links = mtl_rt722_only, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-rt722-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(0), @@ -695,3 +1212,5 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); + +MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_SDCA_QUIRKS"); diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c new file mode 100644 index 000000000000..eae75f3f0fa4 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -0,0 +1,683 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-acpi-intel-ptl-match.c - tables and support for PTL ACPI enumeration. + * + * Copyright (c) 2024, Intel Corporation. + * + * Order of entries in snd_soc_acpi_intel_ptl_sdw_machines[] matters. + * Check subset of link mask when matching the machine driver, rule is + * superset match should be ordered before subset matches. + */ + +#include <sound/soc-acpi.h> +#include <sound/soc-acpi-intel-match.h> +#include "sof-function-topology-lib.h" +#include "soc-acpi-intel-sdca-quirks.h" +#include "soc-acpi-intel-sdw-mockup-match.h" +#include <sound/soc-acpi-intel-ssp-common.h> + +static const struct snd_soc_acpi_codecs ptl_rt5682_rt5682s_hp = { + .num_codecs = 2, + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, +}; + +struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = { + { + .comp_ids = &ptl_rt5682_rt5682s_hp, + .drv_name = "ptl_rt5682_def", + .sof_tplg_filename = "sof-ptl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_machines); + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, +}; + +static const struct snd_soc_acpi_endpoint spk_l_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_1_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_4_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_5_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_6_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, +}; + +/* + * Multi-function codecs with three endpoints created for + * headset, amp and dmic functions. + */ +static const struct snd_soc_acpi_endpoint rt_mf_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* DMIC Endpoint */ + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* Amp Endpoint, work as spk_l_endpoint */ + { + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + /* DMIC Endpoint */ + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, +}; + +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { + { + .adr = 0x00023001fa424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints), + .endpoints = cs42l43_amp_spkagg_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = { + { + .adr = 0x00013001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_1_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013201fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP3" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_4_endpoint, + .name_prefix = "AMP4" + }, + { + .adr = 0x00033401fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_5_endpoint, + .name_prefix = "AMP5" + }, + { + .adr = 0x00033501fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_6_endpoint, + .name_prefix = "AMP6" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = { + { + .adr = 0x00033001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_adr_device rt712_vb_2_group1_adr[] = { + { + .adr = 0x000230025D071201ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt712_vb_3_group1_adr[] = { + { + .adr = 0x000330025D071201ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = { + { + .adr = 0x000230025d071301ull, + .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints), + .endpoints = jack_dmic_endpoints, + .name_prefix = "rt713" + } +}; + +static const struct snd_soc_acpi_adr_device rt713_vb_3_adr[] = { + { + .adr = 0x000330025D071301ull, + .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints), + .endpoints = jack_dmic_endpoints, + .name_prefix = "rt713" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_3_group1_adr[] = { + { + .adr = 0x000330025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt721_3_single_adr[] = { + { + .adr = 0x000330025d072101ull, + .num_endpoints = ARRAY_SIZE(rt_mf_endpoints), + .endpoints = rt_mf_endpoints, + .name_prefix = "rt721" + } +}; + +static const struct snd_soc_acpi_link_adr ptl_rt721_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt721_3_single_adr), + .adr_d = rt721_3_single_adr, + }, + {}, +}; + +static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + { + .adr = 0x000030025d072201ull, + .num_endpoints = ARRAY_SIZE(rt_mf_endpoints), + .endpoints = rt_mf_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_adr_device rt722_1_single_adr[] = { + { + .adr = 0x000130025d072201ull, + .num_endpoints = ARRAY_SIZE(rt_mf_endpoints), + .endpoints = rt_mf_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_adr_device rt722_3_single_adr[] = { + { + .adr = 0x000330025d072201ull, + .num_endpoints = ARRAY_SIZE(rt_mf_endpoints), + .endpoints = rt_mf_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_1_group1_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_1_group2_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_2_group1_adr[] = { + { + .adr = 0x000230025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_2_group2_adr[] = { + { + .adr = 0x000230025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = { + { + .adr = 0x000330025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-2" + } +}; + +static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr), + .adr_d = cs35l56_1_3amp_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr), + .adr_d = cs35l56_3_3amp_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_cs42l43_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs42l43_3_adr), + .adr_d = cs42l43_3_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_rt722_l1[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt722_1_single_adr), + .adr_d = rt722_1_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_rt722_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt722_3_single_adr), + .adr_d = rt722_3_single_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l2_rt1320_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt713_vb_2_adr), + .adr_d = rt713_vb_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group2_adr), + .adr_d = rt1320_1_group2_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1320_3_group2_adr), + .adr_d = rt1320_3_group2_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l12[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt713_vb_3_adr), + .adr_d = rt713_vb_3_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group2_adr), + .adr_d = rt1320_1_group2_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1320_2_group2_adr), + .adr_d = rt1320_2_group2_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt712_vb_2_group1_adr), + .adr_d = rt712_vb_2_group1_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group1_adr), + .adr_d = rt1320_1_group1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l2[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt712_vb_3_group1_adr), + .adr_d = rt712_vb_3_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1320_2_group1_adr), + .adr_d = rt1320_2_group1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt712_vb_3_group1_adr), + .adr_d = rt712_vb_3_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1320_3_group1_adr), + .adr_d = rt1320_3_group1_adr, + }, + {} +}; + +/* this table is used when there is no I2S codec present */ +struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { +/* Order Priority: mockup > most links > most bit link-mask > alphabetical */ + { + .link_mask = GENMASK(3, 0), + .links = sdw_mockup_headset_2amps_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt711-rt1308-rt715.tplg", + }, + { + .link_mask = BIT(0) | BIT(1) | BIT(3), + .links = sdw_mockup_headset_1amp_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt711-rt1308-mono-rt715.tplg", + }, + { + .link_mask = GENMASK(2, 0), + .links = sdw_mockup_mic_headset_1amp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt715-rt711-rt1308-mono.tplg", + }, + { + .link_mask = BIT(0), + .links = sdw_mockup_multi_func, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt722.tplg", /* Reuse the existing tplg file */ + }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = ptl_sdw_rt713_vb_l2_rt1320_l13, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt713-l2-rt1320-l13.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = ptl_sdw_rt713_vb_l3_rt1320_l12, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt713-l3-rt1320-l12.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = ptl_cs42l43_l2_cs35l56x6_l13, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-cs42l43-l2-cs35l56x6-l13.tplg", + }, + { + .link_mask = BIT(1) | BIT(2), + .links = ptl_sdw_rt712_vb_l2_rt1320_l1, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt712-l2-rt1320-l1.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(2) | BIT(3), + .links = ptl_sdw_rt712_vb_l3_rt1320_l2, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(0), + .links = ptl_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt711.tplg", + }, + { + .link_mask = BIT(0), + .links = ptl_rt722_only, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt722.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(1), + .links = ptl_rt722_l1, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt722.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(3), + .links = ptl_cs42l43_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-cs42l43-l3.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(3), + .links = ptl_sdw_rt712_vb_l3_rt1320_l3, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l3.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(3), + .links = ptl_rt721_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt721.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + { + .link_mask = BIT(3), + .links = ptl_rt722_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt722.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 00a21af210fa..b83ac2e6337c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -7,6 +7,7 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include <sound/soc-acpi-intel-ssp-common.h> static const struct snd_soc_acpi_endpoint single_endpoint = { .num = 0, @@ -29,6 +30,42 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { .adr = 0x000020025D071100ull, @@ -155,6 +192,15 @@ static const struct snd_soc_acpi_adr_device rt714_3_adr[] = { } }; +static const struct snd_soc_acpi_link_adr rpl_cs42l43_l0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { { .mask = BIT(0), @@ -347,7 +393,7 @@ static const struct snd_soc_acpi_link_adr rplp_crb[] = { static const struct snd_soc_acpi_codecs rpl_rt5682_hp = { .num_codecs = 2, - .codecs = {"10EC5682", "RTL5682"}, + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, }; static const struct snd_soc_acpi_codecs rpl_essx_83x6 = { @@ -360,31 +406,11 @@ static const struct snd_soc_acpi_codecs rpl_max98357a_amp = { .codecs = {"MX98357A"} }; -static const struct snd_soc_acpi_codecs rpl_max98360a_amp = { - .num_codecs = 1, - .codecs = {"MX98360A"}, -}; - -static const struct snd_soc_acpi_codecs rpl_max98373_amp = { - .num_codecs = 1, - .codecs = {"MX98373"} -}; - static const struct snd_soc_acpi_codecs rpl_lt6911_hdmi = { .num_codecs = 1, .codecs = {"INTC10B0"} }; -static const struct snd_soc_acpi_codecs rpl_nau8318_amp = { - .num_codecs = 1, - .codecs = {"NVTN2012"} -}; - -static const struct snd_soc_acpi_codecs rpl_rt1019p_amp = { - .num_codecs = 1, - .codecs = {"RTL1019"} -}; - struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { { .comp_ids = &rpl_rt5682_hp, @@ -395,41 +421,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { }, { .comp_ids = &rpl_rt5682_hp, - .drv_name = "rpl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &rpl_max98360a_amp, - .sof_tplg_filename = "sof-rpl-max98360a-rt5682.tplg", - }, - { - .id = "10508825", - .drv_name = "rpl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &rpl_max98373_amp, - .sof_tplg_filename = "sof-rpl-max98373-nau8825.tplg", - }, - { - .id = "10508825", - .drv_name = "rpl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &rpl_max98360a_amp, - .sof_tplg_filename = "sof-rpl-max98360a-nau8825.tplg", - }, - { - .id = "10508825", - .drv_name = "rpl_nau8825_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &rpl_nau8318_amp, - .sof_tplg_filename = "sof-rpl-nau8318-nau8825.tplg", - }, - { - .comp_ids = &rpl_rt5682_hp, - .drv_name = "rpl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &rpl_rt1019p_amp, - .sof_tplg_filename = "sof-rpl-rt1019-rt5682.tplg", - }, - { - .comp_ids = &rpl_rt5682_hp, .drv_name = "rpl_rt5682_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &rpl_lt6911_hdmi, @@ -450,6 +441,45 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + /* place boards for each headphone codec: sof driver will complete the + * tplg name and machine driver will detect the amp type + */ + { + .id = CS42L42_ACPI_HID, + .drv_name = "rpl_cs42l42_def", + .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = DA7219_ACPI_HID, + .drv_name = "rpl_da7219_def", + .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = NAU8825_ACPI_HID, + .drv_name = "rpl_nau8825_def", + .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .id = RT5650_ACPI_HID, + .drv_name = "rpl_rt5682_def", + .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + { + .comp_ids = &rpl_rt5682_hp, + .drv_name = "rpl_rt5682_def", + .sof_tplg_filename = "sof-rpl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + /* place amp-only boards in the end of table */ { .id = "INTC10B0", .drv_name = "rpl_lt6911_hdmi_ssp", @@ -462,6 +492,12 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines); /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { { + .link_mask = BIT(0), + .links = rpl_cs42l43_l0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-cs42l43-l0.tplg", + }, + { .link_mask = 0xF, /* 4 active links required */ .links = rpl_sdca_3_in_1, .drv_name = "sof_sdw", diff --git a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c new file mode 100644 index 000000000000..3eaa058f8460 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-acpi-intel-sdca-quirks.c - tables and support for SDCA quirks + * + * Copyright (c) 2024, Intel Corporation. + * + */ + +#include <linux/soundwire/sdw_intel.h> +#include <sound/sdca.h> +#include <sound/soc-acpi.h> +#include "soc-acpi-intel-sdca-quirks.h" + +/* + * Pretend machine quirk. The argument type is not the traditional + * 'struct snd_soc_acpi_mach' pointer but instead the sdw_intel_ctx + * which contains the peripheral information required for the + * SoundWire/SDCA filter on the SMART_MIC setup and interface + * revision. When the return value is false, the entry in the + * 'snd_soc_acpi_mach' table needs to be skipped. + */ +bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg) +{ + struct sdw_intel_ctx *ctx = arg; + int i; + + if (!ctx) + return false; + + for (i = 0; i < ctx->peripherals->num_peripherals; i++) { + if (sdca_device_quirk_match(ctx->peripherals->array[i], + SDCA_QUIRKS_RT712_VB)) + return true; + } + + return false; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS"); + +MODULE_DESCRIPTION("ASoC ACPI Intel SDCA quirks"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("SND_SOC_SDCA"); diff --git a/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h new file mode 100644 index 000000000000..bead5ec6243f --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-sdca-quirks.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * soc-acpi-intel-sdca-quirks.h - tables and support for SDCA quirks + * + * Copyright (c) 2024, Intel Corporation. + * + */ + +#ifndef _SND_SOC_ACPI_INTEL_SDCA_QUIRKS +#define _SND_SOC_ACPI_INTEL_SDCA_QUIRKS + +bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg); + +#endif diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c index a3d33997736a..d122ce69fa4f 100644 --- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c @@ -31,6 +31,30 @@ static const struct snd_soc_acpi_endpoint sdw_mockup_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* Amp Endpoint, work as spk_l_endpoint */ + { + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + /* DMIC Endpoint */ + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device sdw_mockup_headset_0_adr[] = { { .adr = 0x0000000105AA5500ull, @@ -103,6 +127,15 @@ static const struct snd_soc_acpi_adr_device sdw_mockup_amp_2_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device sdw_mockup_multi_function_adr[] = { + { + .adr = 0x0000000105AAAA01ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints, + .name_prefix = "sdw_mockup_mmulti-function" + } +}; + const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[] = { { .mask = BIT(0), @@ -164,3 +197,12 @@ const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[] = { }, {} }; + +const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(sdw_mockup_multi_function_adr), + .adr_d = sdw_mockup_multi_function_adr, + }, + {} +}; diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h index c99eecd19e03..f7ed5beaca96 100644 --- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h +++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h @@ -13,5 +13,6 @@ extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[]; extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_2amps_mic[]; extern const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[]; +extern const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[]; #endif diff --git a/sound/soc/intel/common/soc-acpi-intel-skl-match.c b/sound/soc/intel/common/soc-acpi-intel-skl-match.c index 75302e956742..ee6463202918 100644 --- a/sound/soc/intel/common/soc-acpi-intel-skl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-skl-match.c @@ -8,9 +8,6 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> -#include "../skylake/skl.h" - -static struct skl_machine_pdata skl_dmic_data; static const struct snd_soc_acpi_codecs skl_codecs = { .num_codecs = 1, @@ -29,7 +26,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = { .fw_filename = "intel/dsp_fw_release.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &skl_codecs, - .pdata = &skl_dmic_data, }, { .id = "MX98357A", @@ -37,7 +33,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[] = { .fw_filename = "intel/dsp_fw_release.bin", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &skl_codecs, - .pdata = &skl_dmic_data, }, {}, }; diff --git a/sound/soc/intel/common/soc-acpi-intel-ssp-common.c b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c new file mode 100644 index 000000000000..f56f4bfa5187 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-ssp-common.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation + +#include <linux/device.h> +#include <sound/soc-acpi.h> +#include <sound/soc-acpi-intel-ssp-common.h> + +/* + * Codec probe function + */ +#define CODEC_MAP_ENTRY(n, s, h, t) \ + { \ + .name = n, \ + .tplg_suffix = s, \ + .acpi_hid = h, \ + .codec_type = t, \ + } + +struct codec_map { + const char *name; + const char *tplg_suffix; + const char *acpi_hid; + enum snd_soc_acpi_intel_codec codec_type; +}; + +static const struct codec_map codecs[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS42L42", "cs42l42", CS42L42_ACPI_HID, CODEC_CS42L42), + + /* Dialog */ + CODEC_MAP_ENTRY("DA7219", "da7219", DA7219_ACPI_HID, CODEC_DA7219), + + /* Everest */ + CODEC_MAP_ENTRY("ES8316", "es8336", ES8316_ACPI_HID, CODEC_ES8316), + CODEC_MAP_ENTRY("ES8326", "es8336", ES8326_ACPI_HID, CODEC_ES8326), + CODEC_MAP_ENTRY("ES8336", "es8336", ES8336_ACPI_HID, CODEC_ES8336), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8825", "nau8825", NAU8825_ACPI_HID, CODEC_NAU8825), + + /* Realtek */ + CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650), + CODEC_MAP_ENTRY("RT5682", "rt5682", RT5682_ACPI_HID, CODEC_RT5682), + CODEC_MAP_ENTRY("RT5682S", "rt5682", RT5682S_ACPI_HID, CODEC_RT5682S), +}; + +static const struct codec_map amps[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS35L41", "cs35l41", CS35L41_ACPI_HID, CODEC_CS35L41), + + /* Maxim */ + CODEC_MAP_ENTRY("MAX98357A", "max98357a", MAX_98357A_ACPI_HID, CODEC_MAX98357A), + CODEC_MAP_ENTRY("MAX98360A", "max98360a", MAX_98360A_ACPI_HID, CODEC_MAX98360A), + CODEC_MAP_ENTRY("MAX98373", "max98373", MAX_98373_ACPI_HID, CODEC_MAX98373), + CODEC_MAP_ENTRY("MAX98390", "max98390", MAX_98390_ACPI_HID, CODEC_MAX98390), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8318", "nau8318", NAU8318_ACPI_HID, CODEC_NAU8318), + + /* Realtek */ + CODEC_MAP_ENTRY("RT1011", "rt1011", RT1011_ACPI_HID, CODEC_RT1011), + CODEC_MAP_ENTRY("RT1015", "rt1015", RT1015_ACPI_HID, CODEC_RT1015), + CODEC_MAP_ENTRY("RT1015P", "rt1015", RT1015P_ACPI_HID, CODEC_RT1015P), + CODEC_MAP_ENTRY("RT1019P", "rt1019", RT1019P_ACPI_HID, CODEC_RT1019P), + CODEC_MAP_ENTRY("RT1308", "rt1308", RT1308_ACPI_HID, CODEC_RT1308), + + /* + * Monolithic components + * + * Only put components that can serve as both the amp and the codec below this line. + * This will ensure that if the part is used just as a codec and there is an amp as well + * then the amp will be selected properly. + */ + CODEC_MAP_ENTRY("RT5650", "rt5650", RT5650_ACPI_HID, CODEC_RT5650), +}; + +enum snd_soc_acpi_intel_codec +snd_soc_acpi_intel_detect_codec_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codecs); i++) { + if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "codec %s found\n", codecs[i].name); + return codecs[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_codec_type, "SND_SOC_ACPI_INTEL_MATCH"); + +enum snd_soc_acpi_intel_codec +snd_soc_acpi_intel_detect_amp_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amps); i++) { + if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "amp %s found\n", amps[i].name); + return amps[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_detect_amp_type, "SND_SOC_ACPI_INTEL_MATCH"); + +const char * +snd_soc_acpi_intel_get_codec_name(enum snd_soc_acpi_intel_codec codec_type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codecs); i++) { + if (codecs[i].codec_type != codec_type) + continue; + + return codecs[i].name; + } + for (i = 0; i < ARRAY_SIZE(amps); i++) { + if (amps[i].codec_type != codec_type) + continue; + + return amps[i].name; + } + + return NULL; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_name, "SND_SOC_ACPI_INTEL_MATCH"); + +const char * +snd_soc_acpi_intel_get_codec_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codecs); i++) { + if (codecs[i].codec_type != codec_type) + continue; + + return codecs[i].tplg_suffix; + } + + return NULL; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_codec_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH"); + +const char * +snd_soc_acpi_intel_get_amp_tplg_suffix(enum snd_soc_acpi_intel_codec codec_type) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amps); i++) { + if (amps[i].codec_type != codec_type) + continue; + + return amps[i].tplg_suffix; + } + + return NULL; +} +EXPORT_SYMBOL_NS(snd_soc_acpi_intel_get_amp_tplg_suffix, "SND_SOC_ACPI_INTEL_MATCH"); + +MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index 0fba0a60d9c7..b77aafb0bfb6 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -8,6 +8,7 @@ #include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> +#include <sound/soc-acpi-intel-ssp-common.h> #include "soc-acpi-intel-sdw-mockup-match.h" static const struct snd_soc_acpi_codecs essx_83x6 = { @@ -15,11 +16,6 @@ static const struct snd_soc_acpi_codecs essx_83x6 = { .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, }; -static const struct snd_soc_acpi_codecs tgl_codecs = { - .num_codecs = 1, - .codecs = {"MX98357A"} -}; - static const struct snd_soc_acpi_endpoint single_endpoint = { .num = 0, .aggregated = 0, @@ -414,11 +410,38 @@ static const struct snd_soc_acpi_link_adr tgl_712_only[] = { {} }; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = { { .adr = 0x00033001FA424301ull, - .num_endpoints = 1, - .endpoints = &single_endpoint, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, .name_prefix = "cs42l43" } }; @@ -443,13 +466,13 @@ static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = { .adr = 0x00013701FA355601ull, .num_endpoints = 1, .endpoints = &spk_l_endpoint, - .name_prefix = "AMP8" + .name_prefix = "AMP3" }, { .adr = 0x00013601FA355601ull, .num_endpoints = 1, .endpoints = &spk_2_endpoint, - .name_prefix = "AMP7" + .name_prefix = "AMP4" } }; @@ -472,19 +495,9 @@ static const struct snd_soc_acpi_link_adr tgl_cs42l43_cs35l56[] = { {} }; -static const struct snd_soc_acpi_codecs tgl_max98373_amp = { - .num_codecs = 1, - .codecs = {"MX98373"} -}; - -static const struct snd_soc_acpi_codecs tgl_rt1011_amp = { - .num_codecs = 1, - .codecs = {"10EC1011"} -}; - static const struct snd_soc_acpi_codecs tgl_rt5682_rt5682s_hp = { .num_codecs = 2, - .codecs = {"10EC5682", "RTL5682"}, + .codecs = {RT5682_ACPI_HID, RT5682S_ACPI_HID}, }; static const struct snd_soc_acpi_codecs tgl_lt6911_hdmi = { @@ -494,27 +507,6 @@ static const struct snd_soc_acpi_codecs tgl_lt6911_hdmi = { struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = { { - .comp_ids = &tgl_rt5682_rt5682s_hp, - .drv_name = "tgl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &tgl_codecs, - .sof_tplg_filename = "sof-tgl-max98357a-rt5682.tplg", - }, - { - .comp_ids = &tgl_rt5682_rt5682s_hp, - .drv_name = "tgl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &tgl_max98373_amp, - .sof_tplg_filename = "sof-tgl-max98373-rt5682.tplg", - }, - { - .comp_ids = &tgl_rt5682_rt5682s_hp, - .drv_name = "tgl_rt5682_def", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &tgl_rt1011_amp, - .sof_tplg_filename = "sof-tgl-rt1011-rt5682.tplg", - }, - { .comp_ids = &essx_83x6, .drv_name = "sof-essx8336", .sof_tplg_filename = "sof-tgl-es8336", /* the tplg suffix is added at run time */ @@ -522,6 +514,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + /* place boards for each headphone codec: sof driver will complete the + * tplg name and machine driver will detect the amp type + */ + { + .comp_ids = &tgl_rt5682_rt5682s_hp, + .drv_name = "tgl_rt5682_def", + .sof_tplg_filename = "sof-tgl", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_AMP_NAME | + SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME, + }, + /* place amp-only boards in the end of table */ { .id = "10EC1308", .drv_name = "tgl_rt1308_hdmi_ssp", @@ -533,6 +536,194 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = { }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines); +static const struct snd_soc_acpi_endpoint cs35l56_l_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_r_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 1, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_2_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 2, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_3_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 3, + .group_id = 2, + }, +}; + +static const struct snd_soc_acpi_endpoint cs35l56_4_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 4, + .group_id = 2, + } +}; + +static const struct snd_soc_acpi_endpoint cs35l56_5_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 5, + .group_id = 2, + } +}; + +static const struct snd_soc_acpi_endpoint cs35l56_6_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 6, + .group_id = 2, + } +}; + +static const struct snd_soc_acpi_endpoint cs35l56_7_fb_endpoints[] = { + { /* Speaker Playback Endpoint */ + .num = 0, + .aggregated = 1, + .group_position = 7, + .group_id = 1, + }, + { /* Feedback Capture Endpoint */ + .num = 1, + .aggregated = 1, + .group_position = 7, + .group_id = 2, + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_sdw_eight_1_4_fb_adr[] = { + { + .adr = 0x00003301fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_l_fb_endpoints), + .endpoints = cs35l56_l_fb_endpoints, + .name_prefix = "AMP1" + }, + { + .adr = 0x00003201fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_2_fb_endpoints), + .endpoints = cs35l56_2_fb_endpoints, + .name_prefix = "AMP2" + }, + { + .adr = 0x00003101fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_4_fb_endpoints), + .endpoints = cs35l56_4_fb_endpoints, + .name_prefix = "AMP3" + }, + { + .adr = 0x00003001fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_6_fb_endpoints), + .endpoints = cs35l56_6_fb_endpoints, + .name_prefix = "AMP4" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_sdw_eight_5_8_fb_adr[] = { + { + .adr = 0x00013701fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_r_fb_endpoints), + .endpoints = cs35l56_r_fb_endpoints, + .name_prefix = "AMP8" + }, + { + .adr = 0x00013601fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_3_fb_endpoints), + .endpoints = cs35l56_3_fb_endpoints, + .name_prefix = "AMP7" + }, + { + .adr = 0x00013501fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_5_fb_endpoints), + .endpoints = cs35l56_5_fb_endpoints, + .name_prefix = "AMP6" + }, + { + .adr = 0x00013401fa355601ull, + .num_endpoints = ARRAY_SIZE(cs35l56_7_fb_endpoints), + .endpoints = cs35l56_7_fb_endpoints, + .name_prefix = "AMP5" + }, +}; + +static const struct snd_soc_acpi_link_adr up_extreme_cs35l56_sdw_eight[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_sdw_eight_5_8_fb_adr), + .adr_d = cs35l56_sdw_eight_5_8_fb_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs35l56_sdw_eight_1_4_fb_adr), + .adr_d = cs35l56_sdw_eight_1_4_fb_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { /* mockup tests need to be first */ @@ -632,6 +823,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-tgl-rt711.tplg", }, + { + .link_mask = BIT(0) | BIT(1), + .links = up_extreme_cs35l56_sdw_eight, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-tgl-cs35l56-l01-fb8.tplg" + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_sdw_machines); diff --git a/sound/soc/intel/common/soc-intel-quirks.h b/sound/soc/intel/common/soc-intel-quirks.h index de4e550c5b34..42bd51456b94 100644 --- a/sound/soc/intel/common/soc-intel-quirks.h +++ b/sound/soc/intel/common/soc-intel-quirks.h @@ -11,7 +11,7 @@ #include <linux/platform_data/x86/soc.h> -#if IS_ENABLED(CONFIG_X86) +#if IS_REACHABLE(CONFIG_IOSF_MBI) #include <linux/dmi.h> #include <asm/iosf_mbi.h> diff --git a/sound/soc/intel/common/sof-function-topology-lib.c b/sound/soc/intel/common/sof-function-topology-lib.c new file mode 100644 index 000000000000..90fe7aa3df1c --- /dev/null +++ b/sound/soc/intel/common/sof-function-topology-lib.c @@ -0,0 +1,135 @@ +// 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) 2025 Intel Corporation. +// + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/firmware.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include "sof-function-topology-lib.h" + +enum tplg_device_id { + TPLG_DEVICE_SDCA_JACK, + TPLG_DEVICE_SDCA_AMP, + TPLG_DEVICE_SDCA_MIC, + TPLG_DEVICE_INTEL_PCH_DMIC, + TPLG_DEVICE_HDMI, + TPLG_DEVICE_MAX +}; + +#define SDCA_DEVICE_MASK (BIT(TPLG_DEVICE_SDCA_JACK) | BIT(TPLG_DEVICE_SDCA_AMP) | \ + BIT(TPLG_DEVICE_SDCA_MIC)) + +#define SOF_INTEL_PLATFORM_NAME_MAX 4 + +int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach, + const char *prefix, const char ***tplg_files) +{ + struct snd_soc_acpi_mach_params mach_params = mach->mach_params; + struct snd_soc_dai_link *dai_link; + const struct firmware *fw; + char platform[SOF_INTEL_PLATFORM_NAME_MAX]; + unsigned long tplg_mask = 0; + int tplg_num = 0; + int tplg_dev; + int ret; + int i; + + ret = sscanf(mach->sof_tplg_filename, "sof-%3s-*.tplg", platform); + if (ret != 1) { + dev_err(card->dev, "Invalid platform name %s of tplg %s\n", + platform, mach->sof_tplg_filename); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + char *tplg_dev_name; + + dev_dbg(card->dev, "dai_link %s id %d\n", dai_link->name, dai_link->id); + if (strstr(dai_link->name, "SimpleJack")) { + tplg_dev = TPLG_DEVICE_SDCA_JACK; + tplg_dev_name = "sdca-jack"; + } else if (strstr(dai_link->name, "SmartAmp")) { + tplg_dev = TPLG_DEVICE_SDCA_AMP; + tplg_dev_name = devm_kasprintf(card->dev, GFP_KERNEL, + "sdca-%damp", dai_link->num_cpus); + if (!tplg_dev_name) + return -ENOMEM; + } else if (strstr(dai_link->name, "SmartMic")) { + tplg_dev = TPLG_DEVICE_SDCA_MIC; + tplg_dev_name = "sdca-mic"; + } else if (strstr(dai_link->name, "dmic")) { + switch (mach_params.dmic_num) { + case 2: + tplg_dev_name = "dmic-2ch"; + break; + case 4: + tplg_dev_name = "dmic-4ch"; + break; + default: + dev_warn(card->dev, + "only -2ch and -4ch are supported for dmic\n"); + continue; + } + tplg_dev = TPLG_DEVICE_INTEL_PCH_DMIC; + } else if (strstr(dai_link->name, "iDisp")) { + tplg_dev = TPLG_DEVICE_HDMI; + tplg_dev_name = "hdmi-pcm5"; + + } else { + /* The dai link is not supported by separated tplg yet */ + dev_dbg(card->dev, + "dai_link %s is not supported by separated tplg yet\n", + dai_link->name); + return 0; + } + if (tplg_mask & BIT(tplg_dev)) + continue; + + tplg_mask |= BIT(tplg_dev); + + /* + * The tplg file naming rule is sof-<platform>-<function>-id<BE id number>.tplg + * where <platform> is only required for the DMIC function as the nhlt blob + * is platform dependent. + */ + switch (tplg_dev) { + case TPLG_DEVICE_INTEL_PCH_DMIC: + (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL, + "%s/sof-%s-%s-id%d.tplg", + prefix, platform, + tplg_dev_name, dai_link->id); + break; + default: + (*tplg_files)[tplg_num] = devm_kasprintf(card->dev, GFP_KERNEL, + "%s/sof-%s-id%d.tplg", + prefix, tplg_dev_name, + dai_link->id); + break; + } + if (!(*tplg_files)[tplg_num]) + return -ENOMEM; + tplg_num++; + } + + dev_dbg(card->dev, "tplg_mask %#lx tplg_num %d\n", tplg_mask, tplg_num); + + /* Check presence of sub-topologies */ + for (i = 0; i < tplg_num; i++) { + ret = firmware_request_nowarn(&fw, (*tplg_files)[i], card->dev); + if (!ret) { + release_firmware(fw); + } else { + dev_dbg(card->dev, "Failed to open topology file: %s\n", (*tplg_files)[i]); + return 0; + } + } + + return tplg_num; +} + diff --git a/sound/soc/intel/common/sof-function-topology-lib.h b/sound/soc/intel/common/sof-function-topology-lib.h new file mode 100644 index 000000000000..e7d0c39d0788 --- /dev/null +++ b/sound/soc/intel/common/sof-function-topology-lib.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * soc-acpi-intel-get-tplg.h - get-tplg-files ops + * + * Copyright (c) 2025, Intel Corporation. + * + */ + +#ifndef _SND_SOC_ACPI_INTEL_GET_TPLG_H +#define _SND_SOC_ACPI_INTEL_GET_TPLG_H + +int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_mach *mach, + const char *prefix, const char ***tplg_files); + +#endif diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h deleted file mode 100644 index de2b44568feb..000000000000 --- a/sound/soc/intel/common/sst-dsp-priv.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel Smart Sound Technology - * - * Copyright (C) 2013, Intel Corporation. All rights reserved. - */ - -#ifndef __SOUND_SOC_SST_DSP_PRIV_H -#define __SOUND_SOC_SST_DSP_PRIV_H - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/firmware.h> - -#include "../skylake/skl-sst-dsp.h" - -/* - * DSP Operations exported by platform Audio DSP driver. - */ -struct sst_ops { - /* Shim IO */ - void (*write)(void __iomem *addr, u32 offset, u32 value); - u32 (*read)(void __iomem *addr, u32 offset); - - /* IRQ handlers */ - irqreturn_t (*irq_handler)(int irq, void *context); - - /* SST init and free */ - int (*init)(struct sst_dsp *sst); - void (*free)(struct sst_dsp *sst); -}; - -/* - * Audio DSP memory offsets and addresses. - */ -struct sst_addr { - u32 sram0_base; - u32 sram1_base; - u32 w0_stat_sz; - u32 w0_up_sz; - void __iomem *lpe; - void __iomem *shim; -}; - -/* - * Audio DSP Mailbox configuration. - */ -struct sst_mailbox { - void __iomem *in_base; - void __iomem *out_base; - size_t in_size; - size_t out_size; -}; - -/* - * Generic SST Shim Interface. - */ -struct sst_dsp { - - /* Shared for all platforms */ - - /* runtime */ - struct sst_dsp_device *sst_dev; - spinlock_t spinlock; /* IPC locking */ - struct mutex mutex; /* DSP FW lock */ - struct device *dev; - void *thread_context; - int irq; - u32 id; - - /* operations */ - struct sst_ops *ops; - - /* debug FS */ - struct dentry *debugfs_root; - - /* base addresses */ - struct sst_addr addr; - - /* mailbox */ - struct sst_mailbox mailbox; - - /* SST FW files loaded and their modules */ - struct list_head module_list; - - /* SKL data */ - - const char *fw_name; - - /* To allocate CL dma buffers */ - struct skl_dsp_loader_ops dsp_ops; - struct skl_dsp_fw_ops fw_ops; - int sst_state; - struct skl_cl_dev cl_dev; - u32 intr_status; - const struct firmware *fw; - struct snd_dma_buffer dmab; -}; - -#endif diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c deleted file mode 100644 index 229d09d61afb..000000000000 --- a/sound/soc/intel/common/sst-dsp.c +++ /dev/null @@ -1,250 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Smart Sound Technology (SST) DSP Core Driver - * - * Copyright (C) 2013, Intel Corporation. All rights reserved. - */ - -#include <linux/slab.h> -#include <linux/export.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/io-64-nonatomic-lo-hi.h> -#include <linux/delay.h> - -#include "sst-dsp.h" -#include "sst-dsp-priv.h" - -#define CREATE_TRACE_POINTS -#include <trace/events/intel-sst.h> - -/* Internal generic low-level SST IO functions - can be overidden */ -void sst_shim32_write(void __iomem *addr, u32 offset, u32 value) -{ - writel(value, addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_write); - -u32 sst_shim32_read(void __iomem *addr, u32 offset) -{ - return readl(addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_read); - -void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value) -{ - writeq(value, addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_write64); - -u64 sst_shim32_read64(void __iomem *addr, u32 offset) -{ - return readq(addr + offset); -} -EXPORT_SYMBOL_GPL(sst_shim32_read64); - -/* Public API */ -void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value) -{ - unsigned long flags; - - spin_lock_irqsave(&sst->spinlock, flags); - sst->ops->write(sst->addr.shim, offset, value); - spin_unlock_irqrestore(&sst->spinlock, flags); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_write); - -u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset) -{ - unsigned long flags; - u32 val; - - spin_lock_irqsave(&sst->spinlock, flags); - val = sst->ops->read(sst->addr.shim, offset); - spin_unlock_irqrestore(&sst->spinlock, flags); - - return val; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_read); - -void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value) -{ - sst->ops->write(sst->addr.shim, offset, value); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_write_unlocked); - -u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset) -{ - return sst->ops->read(sst->addr.shim, offset); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked); - -int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - bool change; - unsigned int old, new; - u32 ret; - - ret = sst_dsp_shim_read_unlocked(sst, offset); - - old = ret; - new = (old & (~mask)) | (value & mask); - - change = (old != new); - if (change) - sst_dsp_shim_write_unlocked(sst, offset, new); - - return change; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked); - -/* This is for registers bits with attribute RWC */ -void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned int old, new; - u32 ret; - - ret = sst_dsp_shim_read_unlocked(sst, offset); - - old = ret; - new = (old & (~mask)) | (value & mask); - - sst_dsp_shim_write_unlocked(sst, offset, new); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced_unlocked); - -int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned long flags; - bool change; - - spin_lock_irqsave(&sst->spinlock, flags); - change = sst_dsp_shim_update_bits_unlocked(sst, offset, mask, value); - spin_unlock_irqrestore(&sst->spinlock, flags); - return change; -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits); - -/* This is for registers bits with attribute RWC */ -void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value) -{ - unsigned long flags; - - spin_lock_irqsave(&sst->spinlock, flags); - sst_dsp_shim_update_bits_forced_unlocked(sst, offset, mask, value); - spin_unlock_irqrestore(&sst->spinlock, flags); -} -EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced); - -int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, - u32 target, u32 time, char *operation) -{ - u32 reg; - unsigned long timeout; - int k = 0, s = 500; - - /* - * split the loop into sleeps of varying resolution. more accurately, - * the range of wakeups are: - * Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms. - * Phase 2:( 5ms to 10ms) : min sleep 0.5ms; max sleep 10ms - * (usleep_range (500, 1000) and usleep_range(5000, 10000) are - * both possible in this phase depending on whether k > 10 or not). - * Phase 3: (beyond 10 ms) min sleep 5ms; max sleep 10ms. - */ - - timeout = jiffies + msecs_to_jiffies(time); - while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target) - && time_before(jiffies, timeout)) { - k++; - if (k > 10) - s = 5000; - - usleep_range(s, 2*s); - } - - if ((reg & mask) == target) { - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n", - reg, operation); - - return 0; - } - - dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s timedout\n", - reg, operation); - return -ETIME; -} -EXPORT_SYMBOL_GPL(sst_dsp_register_poll); - -int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size, - u32 outbox_offset, size_t outbox_size) -{ - sst->mailbox.in_base = sst->addr.lpe + inbox_offset; - sst->mailbox.out_base = sst->addr.lpe + outbox_offset; - sst->mailbox.in_size = inbox_size; - sst->mailbox.out_size = outbox_size; - return 0; -} -EXPORT_SYMBOL_GPL(sst_dsp_mailbox_init); - -void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_outbox_write(bytes); - - memcpy_toio(sst->mailbox.out_base, message, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_outbox_wdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_outbox_write); - -void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_outbox_read(bytes); - - memcpy_fromio(message, sst->mailbox.out_base, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_outbox_rdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_outbox_read); - -void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_inbox_write(bytes); - - memcpy_toio(sst->mailbox.in_base, message, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_inbox_wdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_inbox_write); - -void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes) -{ - u32 i; - - trace_sst_ipc_inbox_read(bytes); - - memcpy_fromio(message, sst->mailbox.in_base, bytes); - - for (i = 0; i < bytes; i += 4) - trace_sst_ipc_inbox_rdata(i, *(u32 *)(message + i)); -} -EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood"); -MODULE_DESCRIPTION("Intel SST Core"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h deleted file mode 100644 index f111fd3f334b..000000000000 --- a/sound/soc/intel/common/sst-dsp.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel Smart Sound Technology (SST) Core - * - * Copyright (C) 2013, Intel Corporation. All rights reserved. - */ - -#ifndef __SOUND_SOC_SST_DSP_H -#define __SOUND_SOC_SST_DSP_H - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/interrupt.h> - -struct sst_dsp; - -/* - * SST Device. - * - * This structure is populated by the SST core driver. - */ -struct sst_dsp_device { - /* Mandatory fields */ - struct sst_ops *ops; - irqreturn_t (*thread)(int irq, void *context); - void *thread_context; -}; - -/* SHIM Read / Write */ -void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value); -u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset); -int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); -void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); - -/* SHIM Read / Write Unlocked for callers already holding sst lock */ -void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value); -u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset); -int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); -void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset, - u32 mask, u32 value); - -/* Internal generic low-level SST IO functions - can be overidden */ -void sst_shim32_write(void __iomem *addr, u32 offset, u32 value); -u32 sst_shim32_read(void __iomem *addr, u32 offset); -void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value); -u64 sst_shim32_read64(void __iomem *addr, u32 offset); - -/* Mailbox management */ -int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, - size_t inbox_size, u32 outbox_offset, size_t outbox_size); -void sst_dsp_inbox_write(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_outbox_write(struct sst_dsp *sst, void *message, size_t bytes); -void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes); -int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, - u32 target, u32 time, char *operation); - -#endif diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c deleted file mode 100644 index 89c10724d2a3..000000000000 --- a/sound/soc/intel/common/sst-ipc.c +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel SST generic IPC Support - * - * Copyright (C) 2015, Intel Corporation. All rights reserved. - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/spinlock.h> -#include <linux/device.h> -#include <linux/slab.h> -#include <linux/workqueue.h> -#include <linux/sched.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <sound/asound.h> - -#include "sst-dsp.h" -#include "sst-dsp-priv.h" -#include "sst-ipc.h" - -/* IPC message timeout (msecs) */ -#define IPC_TIMEOUT_MSECS 300 - -#define IPC_EMPTY_LIST_SIZE 8 - -/* locks held by caller */ -static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc) -{ - struct ipc_message *msg = NULL; - - if (!list_empty(&ipc->empty_list)) { - msg = list_first_entry(&ipc->empty_list, struct ipc_message, - list); - list_del(&msg->list); - } - - return msg; -} - -static int tx_wait_done(struct sst_generic_ipc *ipc, - struct ipc_message *msg, struct sst_ipc_message *reply) -{ - unsigned long flags; - int ret; - - /* wait for DSP completion (in all cases atm inc pending) */ - ret = wait_event_timeout(msg->waitq, msg->complete, - msecs_to_jiffies(IPC_TIMEOUT_MSECS)); - - spin_lock_irqsave(&ipc->dsp->spinlock, flags); - if (ret == 0) { - if (ipc->ops.shim_dbg != NULL) - ipc->ops.shim_dbg(ipc, "message timeout"); - - list_del(&msg->list); - ret = -ETIMEDOUT; - } else { - - /* copy the data returned from DSP */ - if (reply) { - reply->header = msg->rx.header; - if (reply->data) - memcpy(reply->data, msg->rx.data, msg->rx.size); - } - ret = msg->errno; - } - - list_add_tail(&msg->list, &ipc->empty_list); - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - return ret; -} - -static int ipc_tx_message(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, - struct sst_ipc_message *reply, int wait) -{ - struct ipc_message *msg; - unsigned long flags; - - spin_lock_irqsave(&ipc->dsp->spinlock, flags); - - msg = msg_get_empty(ipc); - if (msg == NULL) { - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - return -EBUSY; - } - - msg->tx.header = request.header; - msg->tx.size = request.size; - msg->rx.header = 0; - msg->rx.size = reply ? reply->size : 0; - msg->wait = wait; - msg->errno = 0; - msg->pending = false; - msg->complete = false; - - if ((request.size) && (ipc->ops.tx_data_copy != NULL)) - ipc->ops.tx_data_copy(msg, request.data, request.size); - - list_add_tail(&msg->list, &ipc->tx_list); - schedule_work(&ipc->kwork); - spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); - - if (wait) - return tx_wait_done(ipc, msg, reply); - else - return 0; -} - -static int msg_empty_list_init(struct sst_generic_ipc *ipc) -{ - int i; - - ipc->msg = kcalloc(IPC_EMPTY_LIST_SIZE, sizeof(struct ipc_message), - GFP_KERNEL); - if (ipc->msg == NULL) - return -ENOMEM; - - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { - ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); - if (ipc->msg[i].tx.data == NULL) - goto free_mem; - - ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); - if (ipc->msg[i].rx.data == NULL) { - kfree(ipc->msg[i].tx.data); - goto free_mem; - } - - init_waitqueue_head(&ipc->msg[i].waitq); - list_add(&ipc->msg[i].list, &ipc->empty_list); - } - - return 0; - -free_mem: - while (i > 0) { - kfree(ipc->msg[i-1].tx.data); - kfree(ipc->msg[i-1].rx.data); - --i; - } - kfree(ipc->msg); - - return -ENOMEM; -} - -static void ipc_tx_msgs(struct work_struct *work) -{ - struct sst_generic_ipc *ipc = - container_of(work, struct sst_generic_ipc, kwork); - struct ipc_message *msg; - - spin_lock_irq(&ipc->dsp->spinlock); - - while (!list_empty(&ipc->tx_list) && !ipc->pending) { - /* if the DSP is busy, we will TX messages after IRQ. - * also postpone if we are in the middle of processing - * completion irq - */ - if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { - dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); - break; - } - - msg = list_first_entry(&ipc->tx_list, struct ipc_message, list); - list_move(&msg->list, &ipc->rx_list); - - if (ipc->ops.tx_msg != NULL) - ipc->ops.tx_msg(ipc, msg); - } - - spin_unlock_irq(&ipc->dsp->spinlock); -} - -int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply) -{ - int ret; - - /* - * DSP maybe in lower power active state, so - * check if the DSP supports DSP lp On method - * if so invoke that before sending IPC - */ - if (ipc->ops.check_dsp_lp_on) - if (ipc->ops.check_dsp_lp_on(ipc->dsp, true)) - return -EIO; - - ret = ipc_tx_message(ipc, request, reply, 1); - - if (ipc->ops.check_dsp_lp_on) - if (ipc->ops.check_dsp_lp_on(ipc->dsp, false)) - return -EIO; - - return ret; -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait); - -int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request) -{ - return ipc_tx_message(ipc, request, NULL, 0); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait); - -int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply) -{ - return ipc_tx_message(ipc, request, reply, 1); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm); - -struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, - u64 header) -{ - struct ipc_message *msg; - u64 mask; - - if (ipc->ops.reply_msg_match != NULL) - header = ipc->ops.reply_msg_match(header, &mask); - else - mask = (u64)-1; - - if (list_empty(&ipc->rx_list)) { - dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", - header); - return NULL; - } - - list_for_each_entry(msg, &ipc->rx_list, list) { - if ((msg->tx.header & mask) == header) - return msg; - } - - return NULL; -} -EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg); - -/* locks held by caller */ -void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, - struct ipc_message *msg) -{ - msg->complete = true; - - if (!msg->wait) - list_add_tail(&msg->list, &ipc->empty_list); - else - wake_up(&msg->waitq); -} -EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete); - -int sst_ipc_init(struct sst_generic_ipc *ipc) -{ - int ret; - - INIT_LIST_HEAD(&ipc->tx_list); - INIT_LIST_HEAD(&ipc->rx_list); - INIT_LIST_HEAD(&ipc->empty_list); - init_waitqueue_head(&ipc->wait_txq); - - ret = msg_empty_list_init(ipc); - if (ret < 0) - return -ENOMEM; - - INIT_WORK(&ipc->kwork, ipc_tx_msgs); - return 0; -} -EXPORT_SYMBOL_GPL(sst_ipc_init); - -void sst_ipc_fini(struct sst_generic_ipc *ipc) -{ - int i; - - cancel_work_sync(&ipc->kwork); - - if (ipc->msg) { - for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { - kfree(ipc->msg[i].tx.data); - kfree(ipc->msg[i].rx.data); - } - kfree(ipc->msg); - } -} -EXPORT_SYMBOL_GPL(sst_ipc_fini); - -/* Module information */ -MODULE_AUTHOR("Jin Yao"); -MODULE_DESCRIPTION("Intel SST IPC generic"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h deleted file mode 100644 index 77d651e888f9..000000000000 --- a/sound/soc/intel/common/sst-ipc.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel SST generic IPC Support - * - * Copyright (C) 2015, Intel Corporation. All rights reserved. - */ - -#ifndef __SST_GENERIC_IPC_H -#define __SST_GENERIC_IPC_H - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/wait.h> -#include <linux/list.h> -#include <linux/workqueue.h> -#include <linux/sched.h> - -struct sst_ipc_message { - u64 header; - void *data; - size_t size; -}; - -struct ipc_message { - struct list_head list; - struct sst_ipc_message tx; - struct sst_ipc_message rx; - - wait_queue_head_t waitq; - bool pending; - bool complete; - bool wait; - int errno; -}; - -struct sst_generic_ipc; -struct sst_dsp; - -struct sst_plat_ipc_ops { - void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *); - void (*shim_dbg)(struct sst_generic_ipc *, const char *); - void (*tx_data_copy)(struct ipc_message *, char *, size_t); - u64 (*reply_msg_match)(u64 header, u64 *mask); - bool (*is_dsp_busy)(struct sst_dsp *dsp); - int (*check_dsp_lp_on)(struct sst_dsp *dsp, bool state); -}; - -/* SST generic IPC data */ -struct sst_generic_ipc { - struct device *dev; - struct sst_dsp *dsp; - - /* IPC messaging */ - struct list_head tx_list; - struct list_head rx_list; - struct list_head empty_list; - wait_queue_head_t wait_txq; - struct task_struct *tx_thread; - struct work_struct kwork; - bool pending; - struct ipc_message *msg; - int tx_data_max_size; - int rx_data_max_size; - - struct sst_plat_ipc_ops ops; -}; - -int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply); - -int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, - struct sst_ipc_message request); - -int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, - struct sst_ipc_message request, struct sst_ipc_message *reply); - -struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc, - u64 header); - -void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc, - struct ipc_message *msg); - -int sst_ipc_init(struct sst_generic_ipc *ipc); -void sst_ipc_fini(struct sst_generic_ipc *ipc); - -#endif |