diff options
-rw-r--r-- | sound/soc/intel/boards/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/intel/boards/Makefile | 10 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_rt5682.c | 11 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw.c | 542 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_common.h | 84 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_cs42l42.c | 131 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_maxim.c (renamed from sound/soc/intel/boards/sof_sdw_max98373.c) | 58 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt711.c | 4 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt712_sdca.c | 102 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c (renamed from sound/soc/intel/boards/sof_sdw_rt711_sdca.c) | 73 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_ssp_amp.c | 11 | ||||
-rw-r--r-- | sound/soc/intel/common/soc-acpi-intel-adl-match.c | 46 | ||||
-rw-r--r-- | sound/soc/intel/common/soc-acpi-intel-mtl-match.c | 98 | ||||
-rw-r--r-- | sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 42 | ||||
-rw-r--r-- | sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 53 |
15 files changed, 1044 insertions, 225 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 99308ed85277..f472f603ab75 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -662,11 +662,14 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST depends on SOUNDWIRE + select SND_SOC_MAX98363 select SND_SOC_MAX98373_I2C select SND_SOC_MAX98373_SDW select SND_SOC_RT700_SDW select SND_SOC_RT711_SDW select SND_SOC_RT711_SDCA_SDW + select SND_SOC_RT712_SDCA_SDW + select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW @@ -674,6 +677,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW + select SND_SOC_CS42L42_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_INTEL_SOF_MAXIM_COMMON diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index d1fd7a2b32db..931415d9cf6f 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,11 +37,13 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o sof_sdw_rt_amp.o \ + sof_sdw_maxim.o sof_sdw_rt_amp.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ - sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ - sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ - sof_sdw_dmic.o sof_sdw_hdmi.o + sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \ + sof_sdw_rt712_sdca.o sof_sdw_rt715.o \ + sof_sdw_rt715_sdca.o sof_sdw_dmic.o \ + sof_sdw_cs42l42.o \ + sof_sdw_hdmi.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o obj-$(CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH) += snd-soc-sof_es8336.o diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 7f4783592668..86bbc1fea6ff 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -1120,6 +1120,17 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, { + .name = "rpl_rt1019_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1019_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { .name = "mtl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index d16ceef702a7..d942696b36cd 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -22,11 +22,16 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override"); #define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) +#define SDW_MAX_LINKS 4 + +/* To store SDW Pin index for each SoundWire link */ +static unsigned int sdw_pin_index[SDW_MAX_LINKS]; + static void log_quirks(struct device *dev) { - if (SOF_RT711_JDSRC(sof_sdw_quirk)) + if (SOF_JACK_JDSRC(sof_sdw_quirk)) dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n", - SOF_RT711_JDSRC(sof_sdw_quirk)); + SOF_JACK_JDSRC(sof_sdw_quirk)); if (sof_sdw_quirk & SOF_SDW_FOUR_SPK) dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n"); if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) @@ -374,6 +379,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B34"), + }, + /* No Jack */ + .driver_data = (void *)SOF_SDW_TGL_HDMI, + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), }, @@ -385,6 +399,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), }, /* No Jack */ @@ -437,6 +461,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { }, .driver_data = (void *)(RT711_JD2_100K), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), + }, + .driver_data = (void *)(SOF_SDW_PCH_DMIC), + }, /* LunarLake devices */ { .callback = sof_sdw_quirk_cb, @@ -563,134 +595,323 @@ static const struct snd_soc_ops sdw_ops = { static struct sof_sdw_codec_info codec_info_list[] = { { .part_id = 0x700, - .direction = {true, true}, - .dai_name = "rt700-aif1", - .init = sof_sdw_rt700_init, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt700-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt700_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x711, .version_id = 3, - .direction = {true, true}, - .dai_name = "rt711-sdca-aif1", - .init = sof_sdw_rt711_sdca_init, - .exit = sof_sdw_rt711_sdca_exit, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt711-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x711, .version_id = 2, - .direction = {true, true}, - .dai_name = "rt711-aif1", - .init = sof_sdw_rt711_init, - .exit = sof_sdw_rt711_exit, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt711-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt711_init, + .exit = sof_sdw_rt711_exit, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x712, + .version_id = 3, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt712-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + { + .direction = {true, false}, + .dai_name = "rt712-sdca-aif2", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_rt712_spk_init, + }, + }, + .dai_num = 2, + }, + { + .part_id = 0x1712, + .version_id = 3, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt712-sdca-dmic-aif1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt712_sdca_dmic_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x713, + .version_id = 3, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt712-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x1713, + .version_id = 3, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt712-sdca-dmic-aif1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt712_sdca_dmic_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x1308, .acpi_id = "10EC1308", - .direction = {true, false}, - .dai_name = "rt1308-aif", + .dais = { + { + .direction = {true, false}, + .dai_name = "rt1308-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, .ops = &sof_sdw_rt1308_i2s_ops, - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1316, - .direction = {true, true}, - .dai_name = "rt1316-aif", - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt1316-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x1318, - .direction = {true, true}, - .dai_name = "rt1318-aif", - .init = sof_sdw_rt_amp_init, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt1318-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x714, .version_id = 3, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_sdca_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_sdca_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x715, .version_id = 3, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_sdca_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_sdca_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x714, .version_id = 2, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x715, .version_id = 2, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x8373, - .direction = {true, true}, - .dai_name = "max98373-aif1", - .init = sof_sdw_mx8373_init, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "max98373-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_maxim_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x8363, + .dais = { + { + .direction = {true, false}, + .dai_name = "max98363-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_maxim_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x5682, - .direction = {true, true}, - .dai_name = "rt5682-sdw", - .init = sof_sdw_rt5682_init, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt5682-sdw", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt5682_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x4242, + .dais = { + { + .direction = {true, true}, + .dai_name = "cs42l42-sdw", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_cs42l42_init, + }, + }, + .dai_num = 1, }, { .part_id = 0xaaaa, /* generic codec mockup */ .version_id = 0, - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0xaa55, /* headset codec mockup */ .version_id = 0, - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0x55aa, /* amplifier mockup */ .version_id = 0, - .direction = {true, false}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, false}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0x5555, .version_id = 0, - .direction = {false, true}, - .dai_name = "sdw-mockup-aif1", - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .dai_name = "sdw-mockup-aif1", + .direction = {false, true}, + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, }; @@ -742,10 +963,10 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li int *sdw_be_num, int *sdw_cpu_dai_num) { const struct snd_soc_acpi_link_adr *link; - int _codec_type = SOF_SDW_CODEC_TYPE_JACK; bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; int i; + int j; no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; *sdw_cpu_dai_num = 0; @@ -759,6 +980,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li for (link = links; link->num_adr; link++) { const struct snd_soc_acpi_endpoint *endpoint; + struct sof_sdw_codec_info *codec_info; int codec_index; int stream; u64 adr; @@ -768,26 +990,23 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index; - - if (codec_info_list[codec_index].codec_type < _codec_type) - dev_warn(dev, - "Unexpected address table ordering. Expected order: jack -> amp -> mic\n"); - - _codec_type = codec_info_list[codec_index].codec_type; + codec_info = &codec_info_list[codec_index]; endpoint = link->adr_d[i].endpoints; - /* count DAI number for playback and capture */ - for_each_pcm_streams(stream) { - if (!codec_info_list[codec_index].direction[stream]) - continue; + for (j = 0; j < codec_info->dai_num; j++) { + /* count DAI number for playback and capture */ + for_each_pcm_streams(stream) { + if (!codec_info->dais[j].direction[stream]) + continue; - (*sdw_cpu_dai_num)++; + (*sdw_cpu_dai_num)++; - /* count BE for each non-aggregated slave or group */ - if (!endpoint->aggregated || no_aggregation || - !group_visited[endpoint->group_id]) - (*sdw_be_num)++; + /* count BE for each non-aggregated slave or group */ + if (!endpoint->aggregated || no_aggregation || + !group_visited[endpoint->group_id]) + (*sdw_be_num)++; + } } if (endpoint->aggregated) @@ -863,7 +1082,8 @@ static int create_codec_dai_name(struct device *dev, struct snd_soc_codec_conf *codec_conf, int codec_count, int *codec_conf_index, - int adr_index) + int adr_index, + int dai_index) { int _codec_index = -1; int i; @@ -919,7 +1139,7 @@ static int create_codec_dai_name(struct device *dev, _codec_index = codec_index; codec[comp_index].dai_name = - codec_info_list[codec_index].dai_name; + codec_info_list[codec_index].dais[dai_index].dai_name; codec_conf[*codec_conf_index].dlc = codec[comp_index]; codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix; @@ -933,7 +1153,7 @@ static int create_codec_dai_name(struct device *dev, static int set_codec_init_func(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, - bool playback, int group_id, int adr_index) + bool playback, int group_id, int adr_index, int dai_index) { int i = adr_index; @@ -953,11 +1173,13 @@ static int set_codec_init_func(struct snd_soc_card *card, if (codec_index < 0) return codec_index; + /* The group_id is > 0 iff the codec is aggregated */ if (link->adr_d[i].endpoints->group_id != group_id) continue; - if (codec_info_list[codec_index].init) - codec_info_list[codec_index].init(card, + + if (codec_info_list[codec_index].dais[dai_index].init) + codec_info_list[codec_index].dais[dai_index].init(card, link, dai_links, &codec_info_list[codec_index], @@ -1072,19 +1294,21 @@ static int create_sdw_dailink(struct snd_soc_card *card, int codec_count, int *link_id, int *codec_conf_index, bool *ignore_pch_dmic, - bool append_codec_type, - int adr_index) + bool append_dai_type, + int adr_index, + int dai_index) { const struct snd_soc_acpi_link_adr *link_next; struct snd_soc_dai_link_component *codecs; + struct sof_sdw_codec_info *codec_info; int cpu_dai_id[SDW_MAX_CPU_DAIS]; int cpu_dai_num, cpu_dai_index; unsigned int group_id; int codec_idx = 0; - int i = 0, j = 0; int codec_index; int codec_num; int stream; + int i = 0; int ret; int k; @@ -1112,7 +1336,8 @@ static int create_sdw_dailink(struct snd_soc_card *card, continue; ret = create_codec_dai_name(dev, link_next, codecs, codec_idx, - codec_conf, codec_count, codec_conf_index, adr_index); + codec_conf, codec_count, codec_conf_index, + adr_index, dai_index); if (ret < 0) return ret; @@ -1125,23 +1350,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, codec_index = find_codec_info_part(link->adr_d[adr_index].adr); if (codec_index < 0) return codec_index; + codec_info = &codec_info_list[codec_index]; - if (codec_info_list[codec_index].ignore_pch_dmic) + if (codec_info->ignore_pch_dmic) *ignore_pch_dmic = true; - /* Shift the first amplifier's *link_id to SDW_AMP_DAI_ID */ - if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_AMP && - *link_id < SDW_AMP_DAI_ID) - *link_id = SDW_AMP_DAI_ID; - - /* - * DAI ID is fixed at SDW_DMIC_DAI_ID for MICs to - * keep sdw DMIC and HDMI setting static in UCM - */ - if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_MIC && - *link_id < SDW_DMIC_DAI_ID) - *link_id = SDW_DMIC_DAI_ID; - cpu_dai_index = *cpu_id; for_each_pcm_streams(stream) { char *name, *cpu_name; @@ -1153,14 +1366,20 @@ static int create_sdw_dailink(struct snd_soc_card *card, "SDW%d-Capture-%s", }; - if (!codec_info_list[codec_index].direction[stream]) + if (!codec_info->dais[dai_index].direction[stream]) continue; + *link_id = codec_info->dais[dai_index].dailink[stream]; + if (*link_id < 0) { + dev_err(dev, "Invalid dailink id %d\n", *link_id); + return -EINVAL; + } + /* create stream name according to first link id */ - if (append_codec_type) { + if (append_dai_type) { name = devm_kasprintf(dev, GFP_KERNEL, sdw_stream_name[stream + 2], cpu_dai_id[0], - type_strings[codec_info_list[codec_index].codec_type]); + type_strings[codec_info->dais[dai_index].dai_type]); } else { name = devm_kasprintf(dev, GFP_KERNEL, sdw_stream_name[stream], cpu_dai_id[0]); @@ -1175,7 +1394,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, for (k = 0; k < cpu_dai_num; k++) { cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SDW%d Pin%d", cpu_dai_id[k], - j + SDW_INTEL_BIDIR_PDI_BASE); + sdw_pin_index[cpu_dai_id[k]]++); if (!cpu_name) return -ENOMEM; @@ -1217,14 +1436,13 @@ static int create_sdw_dailink(struct snd_soc_card *card, dai_links[*link_index].nonatomic = true; ret = set_codec_init_func(card, link, dai_links + (*link_index)++, - playback, group_id, adr_index); + playback, group_id, adr_index, dai_index); if (ret < 0) { dev_err(dev, "failed to init codec %d", codec_index); return ret; } *cpu_id += cpu_dai_num; - j++; } return 0; @@ -1240,6 +1458,7 @@ static int sof_card_codec_conf_alloc(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link; struct snd_soc_codec_conf *c_conf; int num_codecs = 0; + int codec_index; int i; adr_link = mach_params->links; @@ -1254,8 +1473,11 @@ static int sof_card_codec_conf_alloc(struct device *dev, adr_link->adr_d[i].adr); return -EINVAL; } + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + num_codecs += codec_info_list[codec_index].dai_num; } - num_codecs += adr_link->num_adr; } c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL); @@ -1280,7 +1502,7 @@ static int sof_card_dai_links_create(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link; struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; - bool append_codec_type = false; + bool append_dai_type = false; bool ignore_pch_dmic = false; int codec_conf_count; int codec_conf_index = 0; @@ -1292,6 +1514,7 @@ static int sof_card_dai_links_create(struct device *dev, int total_cpu_dai_num; int sdw_cpu_dai_num; int i, j, be_id = 0; + int codec_index; int cpu_id = 0; int comp_num; int ret; @@ -1372,6 +1595,9 @@ static int sof_card_dai_links_create(struct device *dev, for (i = 0; i < SDW_MAX_GROUPS; i++) group_generated[i] = false; + for (i = 0; i < SDW_MAX_LINKS; i++) + sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; + for (; adr_link->num_adr; adr_link++) { /* * If there are two or more different devices on the same sdw link, we have to @@ -1380,12 +1606,20 @@ static int sof_card_dai_links_create(struct device *dev, * snd_soc_acpi_adr_device array. They won't be described in different adr_links. */ for (i = 0; i < adr_link->num_adr; i++) { + /* find codec info to get dai_num */ + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + if (codec_info_list[codec_index].dai_num > 1) { + append_dai_type = true; + goto out; + } for (j = 0; j < i; j++) { if ((SDW_PART_ID(adr_link->adr_d[i].adr) != SDW_PART_ID(adr_link->adr_d[j].adr)) || (SDW_MFG_ID(adr_link->adr_d[i].adr) != SDW_MFG_ID(adr_link->adr_d[i].adr))) { - append_codec_type = true; + append_dai_type = true; goto out; } } @@ -1410,15 +1644,22 @@ out: group_generated[endpoint->group_id]) continue; - ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, - sdw_cpu_dai_num, cpus, adr_link, - &cpu_id, group_generated, - codec_conf, codec_conf_count, - &be_id, &codec_conf_index, - &ignore_pch_dmic, append_codec_type, i); - if (ret < 0) { - dev_err(dev, "failed to create dai link %d", link_index); - return ret; + /* find codec info to get dai_num */ + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + + for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { + ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, + sdw_cpu_dai_num, cpus, adr_link, + &cpu_id, group_generated, + codec_conf, codec_conf_count, + &be_id, &codec_conf_index, + &ignore_pch_dmic, append_dai_type, i, j); + if (ret < 0) { + dev_err(dev, "failed to create dai link %d", link_index); + return ret; + } } } } @@ -1457,18 +1698,19 @@ SSP: return -ENOMEM; ssp_components->name = codec_name; - ssp_components->dai_name = info->dai_name; + /* TODO: support multi codec dai on SSP when it is needed */ + ssp_components->dai_name = info->dais[0].dai_name; cpus[cpu_id].dai_name = cpu_name; - playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; - capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; + playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; + capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; init_dai_link(dev, links + link_index, be_id, name, playback, capture, cpus + cpu_id, 1, ssp_components, 1, NULL, info->ops); - ret = info->init(card, NULL, links + link_index, info, 0); + ret = info->dais[0].init(card, NULL, links + link_index, info, 0); if (ret < 0) return ret; @@ -1598,6 +1840,24 @@ static struct snd_soc_card card_sof_sdw = { .late_probe = sof_sdw_card_late_probe, }; +/* helper to get the link that the codec DAI is used */ +static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, + const char *dai_name) +{ + struct snd_soc_dai_link *link; + int i; + int j; + + for_each_card_prelinks(card, i, link) { + for (j = 0; j < link->num_codecs; j++) { + /* Check each codec in a link */ + if (!strcmp(link->codecs[j].dai_name, dai_name)) + return link; + } + } + return NULL; +} + static void mc_dailink_exit_loop(struct snd_soc_card *card) { struct snd_soc_dai_link *link; @@ -1605,16 +1865,18 @@ static void mc_dailink_exit_loop(struct snd_soc_card *card) int i, j; for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - if (!codec_info_list[i].exit) - continue; - /* - * We don't need to call .exit function if there is no matched - * dai link found. - */ - for_each_card_prelinks(card, j, link) { - if (!strcmp(link->codecs[0].dai_name, - codec_info_list[i].dai_name)) { - ret = codec_info_list[i].exit(card, link); + for (j = 0; j < codec_info_list[i].dai_num; j++) { + /* Check each dai in codec_info_lis to see if it is used in the link */ + if (!codec_info_list[i].dais[j].exit) + continue; + /* + * We don't need to call .exit function if there is no matched + * dai link found. + */ + link = mc_find_codec_dai_used(card, codec_info_list[i].dais[j].dai_name); + if (link) { + /* Do the .exit function if the codec dai is used in the link */ + ret = codec_info_list[i].dais[j].exit(card, link); if (ret) dev_warn(card->dev, "codec exit failed %d\n", diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 081ab7eac5b6..64cfa5d1aceb 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -15,7 +15,11 @@ #define MAX_NO_PROPS 2 #define MAX_HDMI_NUM 4 -#define SDW_AMP_DAI_ID 2 +#define SDW_UNUSED_DAI_ID -1 +#define SDW_JACK_OUT_DAI_ID 0 +#define SDW_JACK_IN_DAI_ID 1 +#define SDW_AMP_OUT_DAI_ID 2 +#define SDW_AMP_IN_DAI_ID 3 #define SDW_DMIC_DAI_ID 4 #define SDW_MAX_CPU_DAIS 16 #define SDW_INTEL_BIDIR_PDI_BASE 2 @@ -37,7 +41,7 @@ enum { SOF_I2S_SSP5 = BIT(5), }; -#define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) +#define SOF_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define SOF_SDW_FOUR_SPK BIT(4) #define SOF_SDW_TGL_HDMI BIT(5) #define SOF_SDW_PCH_DMIC BIT(6) @@ -52,28 +56,37 @@ enum { (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(18) -#define SOF_SDW_CODEC_TYPE_JACK 0 -#define SOF_SDW_CODEC_TYPE_AMP 1 -#define SOF_SDW_CODEC_TYPE_MIC 2 +#define SOF_SDW_DAI_TYPE_JACK 0 +#define SOF_SDW_DAI_TYPE_AMP 1 +#define SOF_SDW_DAI_TYPE_MIC 2 + +#define SOF_SDW_MAX_DAI_NUM 3 + +struct sof_sdw_codec_info; + +struct sof_sdw_dai_info { + const bool direction[2]; /* playback & capture support */ + const char *dai_name; + const int dai_type; + const int dailink[2]; /* dailink id for each direction */ + int (*init)(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +}; struct sof_sdw_codec_info { const int part_id; const int version_id; - const int codec_type; int amp_num; const u8 acpi_id[ACPI_ID_LEN]; - const bool direction[2]; // playback & capture support const bool ignore_pch_dmic; - const char *dai_name; const struct snd_soc_ops *ops; + struct sof_sdw_dai_info dais[SOF_SDW_MAX_DAI_NUM]; + const int dai_num; - int (*init)(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); - - int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); int (*codec_card_late_probe)(struct snd_soc_card *card); }; @@ -110,12 +123,30 @@ int sof_sdw_rt711_init(struct snd_soc_card *card, int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT711-SDCA support */ -int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, +int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); +int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); + +/* RT712-SDCA support */ +int sof_sdw_rt712_sdca_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); -int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt712_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt712_spk_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); +int sof_sdw_rt712_sdca_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); /* RT700 support */ int sof_sdw_rt700_init(struct snd_soc_card *card, @@ -151,12 +182,12 @@ int sof_sdw_rt715_sdca_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); -/* MAX98373 support */ -int sof_sdw_mx8373_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); +/* MAXIM codec support */ +int sof_sdw_maxim_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); /* RT5682 support */ int sof_sdw_rt5682_init(struct snd_soc_card *card, @@ -165,4 +196,11 @@ int sof_sdw_rt5682_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); +/* CS42L42 support */ +int sof_sdw_cs42l42_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + #endif diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/intel/boards/sof_sdw_cs42l42.c new file mode 100644 index 000000000000..c4a16e4c9f69 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_cs42l42.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_cs42l42 - Helpers to handle CS42L42 from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/input.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget cs42l42_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route cs42l42_map[] = { + /* HP jack connectors - unknown if we have jack detection */ + {"Headphone", NULL, "cs42l42 HP"}, + + /* other jacks */ + {"cs42l42 HS", NULL, "Headset Mic"}, +}; + +static const struct snd_kcontrol_new cs42l42_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static struct snd_soc_jack_pin cs42l42_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = codec_dai->component; + struct snd_soc_jack *jack; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s hs:cs42l42", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, cs42l42_controls, + ARRAY_SIZE(cs42l42_controls)); + if (ret) { + dev_err(card->dev, "cs42l42 control addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l42_widgets, + ARRAY_SIZE(cs42l42_widgets)); + if (ret) { + dev_err(card->dev, "cs42l42 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l42_map, + ARRAY_SIZE(cs42l42_map)); + + if (ret) { + dev_err(card->dev, "cs42l42 map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + &ctx->sdw_headset, + cs42l42_jack_pins, + ARRAY_SIZE(cs42l42_jack_pins)); + if (ret) { + dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", + ret); + return ret; + } + + jack = &ctx->sdw_headset; + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(component, jack, NULL); + + if (ret) + dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", + ret); + + return ret; +} + +int sof_sdw_cs42l42_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * headset should be initialized once. + * Do it with dai link for playback. + */ + if (!playback) + return 0; + + dai_links->init = cs42l42_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_maxim.c index 3d7df58c0f1d..8d40a83ad98e 100644 --- a/sound/soc/intel/boards/sof_sdw_max98373.c +++ b/sound/soc/intel/boards/sof_sdw_maxim.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright (c) 2020 Intel Corporation // -// sof_sdw_max98373 - Helpers to handle 2x MAX98373 +// sof_sdw_maxim - Helpers to handle maxim codecs // codec devices from generic machine driver #include <linux/device.h> @@ -13,12 +13,16 @@ #include "sof_sdw_common.h" #include "sof_maxim_common.h" -static const struct snd_soc_dapm_widget mx8373_widgets[] = { +static int maxim_part_id; +#define SOF_SDW_PART_ID_MAX98363 0x8363 +#define SOF_SDW_PART_ID_MAX98373 0x8373 + +static const struct snd_soc_dapm_widget maxim_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_kcontrol_new mx8373_controls[] = { +static const struct snd_kcontrol_new maxim_controls[] = { SOC_DAPM_PIN_SWITCH("Left Spk"), SOC_DAPM_PIN_SWITCH("Right Spk"), }; @@ -29,22 +33,25 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd) int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:mx8373", - card->components); + "%s spk:mx%04x", + card->components, maxim_part_id); if (!card->components) return -ENOMEM; - ret = snd_soc_add_card_controls(card, mx8373_controls, - ARRAY_SIZE(mx8373_controls)); + dev_dbg(card->dev, "soundwire maxim card components assigned : %s\n", + card->components); + + ret = snd_soc_add_card_controls(card, maxim_controls, + ARRAY_SIZE(maxim_controls)); if (ret) { - dev_err(card->dev, "mx8373 ctrls addition failed: %d\n", ret); + dev_err(card->dev, "mx%04x ctrls addition failed: %d\n", maxim_part_id, ret); return ret; } - ret = snd_soc_dapm_new_controls(&card->dapm, mx8373_widgets, - ARRAY_SIZE(mx8373_widgets)); + ret = snd_soc_dapm_new_controls(&card->dapm, maxim_widgets, + ARRAY_SIZE(maxim_widgets)); if (ret) { - dev_err(card->dev, "mx8373 widgets addition failed: %d\n", ret); + dev_err(card->dev, "mx%04x widgets addition failed: %d\n", maxim_part_id, ret); return ret; } @@ -130,19 +137,30 @@ static int mx8373_sdw_late_probe(struct snd_soc_card *card) return snd_soc_dapm_sync(dapm); } -int sof_sdw_mx8373_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) +int sof_sdw_maxim_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) { info->amp_num++; if (info->amp_num == 2) dai_links->init = spk_init; - info->codec_card_late_probe = mx8373_sdw_late_probe; - - dai_links->ops = &max_98373_sdw_ops; - + maxim_part_id = info->part_id; + switch (maxim_part_id) { + case SOF_SDW_PART_ID_MAX98363: + /* Default ops are set in function init_dai_link. + * called as part of function create_sdw_dailink + */ + break; + case SOF_SDW_PART_ID_MAX98373: + info->codec_card_late_probe = mx8373_sdw_late_probe; + dai_links->ops = &max_98373_sdw_ops; + break; + default: + dev_err(card->dev, "Invalid maxim_part_id %#x\n", maxim_part_id); + return -EINVAL; + } return 0; } diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 8291967f23f3..2b05e2a707de 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -27,9 +27,9 @@ static int rt711_add_codec_device_props(struct device *sdw_dev) struct fwnode_handle *fwnode; int ret; - if (!SOF_RT711_JDSRC(sof_sdw_quirk)) + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) return 0; - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk)); + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); fwnode = fwnode_create_software_node(props, NULL); if (IS_ERR(fwnode)) diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c new file mode 100644 index 000000000000..84c8025d24e3 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_rt712_sdca - Helpers to handle RT712-SDCA from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget rt712_spk_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt712 spk will be registered dynamically according + * to the number of rt712 spk used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two rt712s are used. + */ +static const struct snd_soc_dapm_route rt712_spk_map[] = { + { "Speaker", NULL, "rt712 SPOL" }, + { "Speaker", NULL, "rt712 SPOR" }, +}; + +static const struct snd_kcontrol_new rt712_spk_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int rt712_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:rt712", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt712_spk_controls, + ARRAY_SIZE(rt712_spk_controls)); + if (ret) { + dev_err(card->dev, "rt712 spk controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt712_spk_widgets, + ARRAY_SIZE(rt712_spk_widgets)); + if (ret) { + dev_err(card->dev, "rt712 spk widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt712_spk_map, ARRAY_SIZE(rt712_spk_map)); + if (ret) + dev_err(rtd->dev, "failed to add SPK map: %d\n", ret); + + return ret; +} + +int sof_sdw_rt712_spk_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = rt712_spk_init; + + return 0; +} + +static int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s mic:rt712-sdca-dmic", + card->components); + if (!card->components) + return -ENOMEM; + + return 0; +} + +int sof_sdw_rt712_sdca_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = rt712_sdca_dmic_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c index 7f16304d025b..623e3bebb888 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c +++ b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c @@ -21,16 +21,16 @@ * Note this MUST be called before snd_soc_register_card(), so that the props * are in place before the codec component driver's probe function parses them. */ -static int rt711_sdca_add_codec_device_props(struct device *sdw_dev) +static int rt_sdca_jack_add_codec_device_props(struct device *sdw_dev) { struct property_entry props[MAX_NO_PROPS] = {}; struct fwnode_handle *fwnode; int ret; - if (!SOF_RT711_JDSRC(sof_sdw_quirk)) + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) return 0; - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk)); + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); fwnode = fwnode_create_software_node(props, NULL); if (IS_ERR(fwnode)) @@ -43,23 +43,27 @@ static int rt711_sdca_add_codec_device_props(struct device *sdw_dev) return ret; } -static const struct snd_soc_dapm_widget rt711_sdca_widgets[] = { +static const struct snd_soc_dapm_widget rt_sdca_jack_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), }; static const struct snd_soc_dapm_route rt711_sdca_map[] = { - /* Headphones */ { "Headphone", NULL, "rt711 HP" }, { "rt711 MIC2", NULL, "Headset Mic" }, }; -static const struct snd_kcontrol_new rt711_sdca_controls[] = { +static const struct snd_soc_dapm_route rt712_sdca_map[] = { + { "Headphone", NULL, "rt712 HP" }, + { "rt712 MIC2", NULL, "Headset Mic" }, +}; + +static const struct snd_kcontrol_new rt_sdca_jack_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), }; -static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { +static struct snd_soc_jack_pin rt_sdca_jack_pins[] = { { .pin = "Headphone", .mask = SND_JACK_HEADPHONE, @@ -70,7 +74,7 @@ static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { }, }; -static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) +static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); @@ -80,30 +84,38 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:rt711-sdca", - card->components); + "%s hs:%s-sdca", + card->components, component->name_prefix); if (!card->components) return -ENOMEM; - ret = snd_soc_add_card_controls(card, rt711_sdca_controls, - ARRAY_SIZE(rt711_sdca_controls)); + ret = snd_soc_add_card_controls(card, rt_sdca_jack_controls, + ARRAY_SIZE(rt_sdca_jack_controls)); if (ret) { - dev_err(card->dev, "rt711-sdca controls addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack controls addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_new_controls(&card->dapm, rt711_sdca_widgets, - ARRAY_SIZE(rt711_sdca_widgets)); + ret = snd_soc_dapm_new_controls(&card->dapm, rt_sdca_jack_widgets, + ARRAY_SIZE(rt_sdca_jack_widgets)); if (ret) { - dev_err(card->dev, "rt711-sdca widgets addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack widgets addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, - ARRAY_SIZE(rt711_sdca_map)); + if (strstr(component->name_prefix, "rt711")) { + ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, + ARRAY_SIZE(rt711_sdca_map)); + } else if (strstr(component->name_prefix, "rt712")) { + ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map, + ARRAY_SIZE(rt712_sdca_map)); + } else { + dev_err(card->dev, "%s is not supported\n", component->name_prefix); + return -EINVAL; + } if (ret) { - dev_err(card->dev, "rt711-sdca map addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack map addition failed: %d\n", ret); return ret; } @@ -112,8 +124,8 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->sdw_headset, - rt711_sdca_jack_pins, - ARRAY_SIZE(rt711_sdca_jack_pins)); + rt_sdca_jack_pins, + ARRAY_SIZE(rt_sdca_jack_pins)); if (ret) { dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", ret); @@ -136,24 +148,27 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) return ret; } -int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); if (!ctx->headset_codec_dev) return 0; + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) + return 0; + device_remove_software_node(ctx->headset_codec_dev); put_device(ctx->headset_codec_dev); return 0; } -int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) +int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct device *sdw_dev; @@ -170,14 +185,14 @@ int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, if (!sdw_dev) return -EPROBE_DEFER; - ret = rt711_sdca_add_codec_device_props(sdw_dev); + ret = rt_sdca_jack_add_codec_device_props(sdw_dev); if (ret < 0) { put_device(sdw_dev); return ret; } ctx->headset_codec_dev = sdw_dev; - dai_links->init = rt711_sdca_rtd_init; + dai_links->init = rt_sdca_jack_rtd_init; return 0; } diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index b33f720b3e6d..0aef718e82b2 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -463,6 +463,15 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT | SOF_CS35L41_SPEAKER_AMP_PRESENT), }, + { + .name = "adl_lt6911_hdmi_ssp", + .driver_data = (kernel_ulong_t)(SOF_NO_OF_HDMI_CAPTURE_SSP(2) | + SOF_HDMI_CAPTURE_1_SSP(0) | + SOF_HDMI_CAPTURE_2_SSP(2) | + SOF_SSP_HDMI_CAPTURE_PRESENT | + SOF_NO_OF_HDMI_PLAYBACK(3) | + SOF_HDMI_PLAYBACK_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -478,7 +487,7 @@ static struct platform_driver sof_ssp_amp_driver = { module_platform_driver(sof_ssp_amp_driver); MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver"); -MODULE_AUTHOR("balamurugan.c <[email protected]>"); +MODULE_AUTHOR("Balamurugan C <[email protected]>"); MODULE_AUTHOR("Brent Lu <[email protected]>"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); 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 d8c80041388a..bcd66e0094b4 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -133,6 +133,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { + { + .adr = 0x000130025D131601ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1316-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_2_single_adr[] = { { .adr = 0x000230025D131601ull, @@ -312,6 +321,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link12_rt714_link0[] = {} }; +static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link1_rt714_link0[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_single_adr), + .adr_d = rt1316_1_single_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt714_0_adr), + .adr_d = rt714_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link3[] = { { .mask = BIT(2), @@ -557,12 +580,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .quirk_data = &adl_max98360a_amp, .sof_tplg_filename = "sof-adl-max98360a-cs42l42.tplg", }, - /* place amp-only boards in the end of table */ - { - .id = "CSC3541", - .drv_name = "adl_cs35l41", - .sof_tplg_filename = "sof-adl-cs35l41.tplg", - }, { .comp_ids = &essx_83x6, .drv_name = "adl_es83x6_c1_h02", @@ -578,6 +595,17 @@ 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 amp-only boards in the end of table */ + { + .id = "CSC3541", + .drv_name = "adl_cs35l41", + .sof_tplg_filename = "sof-adl-cs35l41.tplg", + }, + { + .id = "INTC10B0", + .drv_name = "adl_lt6911_hdmi_ssp", + .sof_tplg_filename = "sof-adl-nocodec-hdmi-ssp02.tplg" + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines); @@ -621,6 +649,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .sof_tplg_filename = "sof-adl-rt1316-l2-mono-rt714-l3.tplg", }, { + .link_mask = 0x3, /* rt1316 on link1 & rt714 on link0 */ + .links = adl_sdw_rt1316_link1_rt714_link0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-rt1316-l1-mono-rt714-l0.tplg", + }, + { .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ .links = adl_sdw_rt1316_link12_rt714_link0, .drv_name = "sof_sdw", 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 8fd4d0db201e..3d5cf8867926 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -65,6 +65,21 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -74,6 +89,24 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = { + { + .adr = 0x000030025D071201ull, + .num_endpoints = ARRAY_SIZE(rt712_endpoints), + .endpoints = rt712_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = { + { + .adr = 0x000330025D171201ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt712-dmic" + } +}; + static const struct snd_soc_acpi_adr_device mx8373_0_adr[] = { { .adr = 0x000023019F837300ull, @@ -125,6 +158,20 @@ static const struct snd_soc_acpi_adr_device rt714_1_adr[] = { } }; +static const struct snd_soc_acpi_link_adr mtl_712_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_0_single_adr), + .adr_d = rt712_0_single_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1712_3_single_adr), + .adr_d = rt1712_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = { /* Expected order: jack -> amp */ { @@ -173,6 +220,45 @@ static const struct snd_soc_acpi_link_adr mtl_3_in_1_sdca[] = { {} }; +static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = { + { + .adr = 0x000230019F836300ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "Left" + }, + { + .adr = 0x000231019F836300ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "Right" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l42_0_adr[] = { + { + .adr = 0x00001001FA424200ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "cs42l42" + } +}; + +static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = { + /* Expected order: jack -> amp */ + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l42_0_adr), + .adr_d = cs42l42_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(mx8363_2_adr), + .adr_d = mx8363_2_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 */ @@ -195,6 +281,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = BIT(3) | BIT(0), + .links = mtl_712_only, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt712-l0-rt1712-l3.tplg", + }, + { .link_mask = GENMASK(3, 0), .links = mtl_3_in_1_sdca, .drv_name = "sof_sdw", @@ -212,6 +304,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-sdw-rt5682-l2-max98373-l0.tplg", }, + { + .link_mask = BIT(0) | BIT(2), + .links = cs42l42_link0_max98363_link2, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-sdw-cs42l42-l0-max98363-l2.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_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 c61d654eb1e2..302a08018572 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -179,6 +179,30 @@ static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1316_link12_rt714_link3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group1_adr), + .adr_d = rt1316_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group1_adr), + .adr_d = rt1316_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt714_3_adr), + .adr_d = rt714_3_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01_rt714_link3[] = { { .mask = BIT(2), @@ -308,6 +332,11 @@ static const struct snd_soc_acpi_codecs rpl_max98373_amp = { .codecs = {"MX98373"} }; +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, @@ -323,6 +352,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { .quirk_data = &rpl_max98373_amp, .sof_tplg_filename = "sof-rpl-max98373-nau8825.tplg", }, + { + .comp_ids = &rpl_rt5682_hp, + .drv_name = "rpl_rt1019_rt5682", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_rt1019p_amp, + .sof_tplg_filename = "sof-rpl-rt1019-rt5682.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines); @@ -343,6 +379,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { }, { .link_mask = 0xF, /* 4 active links required */ + .links = rpl_sdw_rt711_link0_rt1316_link12_rt714_link3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l12-rt714-l3.tplg", + }, + { + .link_mask = 0xF, /* 4 active links required */ .links = rpl_sdw_rt711_link0_rt1318_link12_rt714_link3, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg", 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 ef19150e7b2e..5804926c8b56 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -41,6 +41,21 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { .adr = 0x000020025D071100ull, @@ -170,6 +185,24 @@ static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = { + { + .adr = 0x000030025D071201ull, + .num_endpoints = ARRAY_SIZE(rt712_endpoints), + .endpoints = rt712_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt1712_1_single_adr[] = { + { + .adr = 0x000130025D171201ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt712-dmic" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { { .adr = 0x000131025D131601ull, /* unique ID is set for some reason */ @@ -353,6 +386,20 @@ static const struct snd_soc_acpi_link_adr tgl_3_in_1_sdca_mono[] = { {} }; +static const struct snd_soc_acpi_link_adr tgl_712_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_0_single_adr), + .adr_d = rt712_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1712_1_single_adr), + .adr_d = rt1712_1_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_codecs tgl_max98373_amp = { .num_codecs = 1, .codecs = {"MX98373"} @@ -436,6 +483,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = 0xF, /* 4 active links required */ + .links = tgl_712_only, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-tgl-rt712.tplg", + }, + { .link_mask = 0x7, .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, .drv_name = "sof_sdw", |