[PATCH 00/14] ASoC: Intel: machine driver updates for 5.10
This series updates the tables used to select SoundWire configurations for CometLake and TigerLake, and adds support for SDCA (SoundWire Device Class for Audio) codecs in the common machine driver. These codec drivers are still being tested on early silicon/boards and will be contributed at a later time.
For TigerLake Chromebooks a new DMI quirk is added, as well as a means to override the topology names. A pm_runtime fix is also provided to deal with playback/capture dependencies with an amplifier w/ feedback. I also included a minor codec correction for the TGL amplifier.
Bard Liao (5): ASoC: Intel: modify SoundWire version id in acpi match table ASoC: Intel: sof_sdw: check SoundWire version when matching codec ASoC: Intel: sof_sdw: rename id as part_id ASoC: Intel: sof_sdw: add rt711 rt1316 rt714 SDCA codec support. ASoC: Intel: sof_sdw: clean-up inclusion of header files
Pierre-Louis Bossart (5): ASoC: Intel: soc-acpi: cnl: add support for rt5682 on SoundWire link2 ASoC: Intel: sof-soundwire: add support for rt5682 on link2 ASoC: Intel: soc-acpi: mirror CML and TGL configurations ASoC: Intel: soc-acpi: add support for SDCA boards ASoC: codecs: max98373-sdw: add missing test on resume
Rander Wang (2): ASoC: Intel: tgl_max98373: fix a runtime pm issue in multi-thread case ASoC: Intel: sof_sdw: Add support for product Ripto
Sathyanarayana Nujella (2): ASoC: Intel: sof_rt5682: override quirk data for tgl_max98373_rt5682 ASoC: SOF: Add topology filename override based on dmi data match
sound/soc/codecs/max98373-sdw.c | 3 + sound/soc/intel/boards/Kconfig | 3 + sound/soc/intel/boards/Makefile | 7 +- sound/soc/intel/boards/sof_maxim_common.c | 7 +- sound/soc/intel/boards/sof_rt5682.c | 13 ++ sound/soc/intel/boards/sof_sdw.c | 98 +++++++--- sound/soc/intel/boards/sof_sdw_common.h | 22 ++- sound/soc/intel/boards/sof_sdw_dmic.c | 1 + sound/soc/intel/boards/sof_sdw_max98373.c | 2 + sound/soc/intel/boards/sof_sdw_rt1308.c | 2 + sound/soc/intel/boards/sof_sdw_rt1316.c | 113 ++++++++++++ sound/soc/intel/boards/sof_sdw_rt5682.c | 2 + sound/soc/intel/boards/sof_sdw_rt700.c | 2 + sound/soc/intel/boards/sof_sdw_rt711.c | 2 + sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 174 ++++++++++++++++++ sound/soc/intel/boards/sof_sdw_rt715_sdca.c | 42 +++++ .../intel/common/soc-acpi-intel-cml-match.c | 79 +++++++- .../intel/common/soc-acpi-intel-cnl-match.c | 33 +++- .../intel/common/soc-acpi-intel-icl-match.c | 10 +- .../intel/common/soc-acpi-intel-tgl-match.c | 165 ++++++++++++++++- sound/soc/sof/intel/hda.c | 8 +- sound/soc/sof/sof-pci-dev.c | 24 +++ 22 files changed, 764 insertions(+), 48 deletions(-) create mode 100644 sound/soc/intel/boards/sof_sdw_rt1316.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt711_sdca.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt715_sdca.c
base-commit: fcea8b023a5f06ea0180ae65b01520b0414ee325
From: Bard Liao yung-chuan.liao@linux.intel.com
The SoundWire version id of the existing RT1308, RT711, and RT715 codecs should be 2 (index for SoundWire 1.1), it was mistakenly set as 1 which pointed to the wrong version (SoundWire 1.0).
This off-by-one error had no functional impact so far since the version number was not used, however in future patches this version will be required.
Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/common/soc-acpi-intel-cml-match.c | 10 +++++----- sound/soc/intel/common/soc-acpi-intel-icl-match.c | 10 +++++----- sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-)
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 dee1f0fa998b..51535cd60a0a 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -112,7 +112,7 @@ static const struct snd_soc_acpi_link_adr cml_rvp[] = {
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { - .adr = 0x000010025D071100, + .adr = 0x000020025D071100, .num_endpoints = 1, .endpoints = &single_endpoint, } @@ -120,7 +120,7 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { { - .adr = 0x000110025D130800, + .adr = 0x000120025D130800, .num_endpoints = 1, .endpoints = &single_endpoint, } @@ -128,7 +128,7 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = { { - .adr = 0x000110025D130800, + .adr = 0x000120025D130800, .num_endpoints = 1, .endpoints = &spk_l_endpoint, } @@ -136,7 +136,7 @@ static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = { { - .adr = 0x000210025D130800, + .adr = 0x000220025D130800, .num_endpoints = 1, .endpoints = &spk_r_endpoint, } @@ -144,7 +144,7 @@ static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = {
static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { { - .adr = 0x000310025D071500, + .adr = 0x000320025D071500, .num_endpoints = 1, .endpoints = &single_endpoint, } 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 6927bbbc66fc..ebe13197410f 100644 --- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c @@ -73,7 +73,7 @@ static const struct snd_soc_acpi_link_adr icl_rvp[] = {
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { - .adr = 0x000010025D071100, + .adr = 0x000020025D071100, .num_endpoints = 1, .endpoints = &single_endpoint, } @@ -81,7 +81,7 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { { - .adr = 0x000110025D130800, + .adr = 0x000120025D130800, .num_endpoints = 1, .endpoints = &single_endpoint, } @@ -89,7 +89,7 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = { { - .adr = 0x000110025D130800, + .adr = 0x000120025D130800, .num_endpoints = 1, .endpoints = &spk_l_endpoint, } @@ -97,7 +97,7 @@ static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = { { - .adr = 0x000210025D130800, + .adr = 0x000220025D130800, .num_endpoints = 1, .endpoints = &spk_r_endpoint, } @@ -105,7 +105,7 @@ static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = {
static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { { - .adr = 0x000310025D071500, + .adr = 0x000320025D071500, .num_endpoints = 1, .endpoints = &single_endpoint, } 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 2ffa608d987d..472f58ddda1f 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -37,7 +37,7 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { - .adr = 0x000010025D071100, + .adr = 0x000020025D071100, .num_endpoints = 1, .endpoints = &single_endpoint, }
Add one of the configurations for rt5682 w/ the Up Extreme Advanced Audio mode using the SoundWire link2.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- .../intel/common/soc-acpi-intel-cnl-match.c | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
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 6a0bcc1a8429..7d61e0da808b 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cnl-match.c @@ -27,8 +27,39 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[] = { }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_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_adr_device rt5682_2_adr[] = { + { + .adr = 0x000220025D568200, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + +static const struct snd_soc_acpi_link_adr up_extreme_rt5682_2[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt5682_2_adr), + .adr_d = rt5682_2_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[] = { - {}, + { + .link_mask = BIT(2), + .links = up_extreme_rt5682_2, + .drv_name = "sof_sdw", + .sof_fw_filename = "sof-cnl.ri", + .sof_tplg_filename = "sof-cnl-rt5682-sdw2.tplg" + }, + {} }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cnl_sdw_machines);
The UpExtreme board provides support for SoundWire link2 in 2 of the 3 advanced modes. Let's use it w/ rt5682.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 4bc1ed757009..100c0a83a6ad 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -173,6 +173,11 @@ static struct snd_soc_codec_conf codec_conf[] = { .dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"), .name_prefix = "rt5682", }, + /* rt5682 on link2 */ + { + .dlc = COMP_CODEC_CONF("sdw:2:25d:5682:0"), + .name_prefix = "rt5682", + }, };
static struct snd_soc_dai_link_component dmic_component[] = {
Some TGL devices use the same audio hardware as on CML platforms, with RT711 on link0, RT1308 on link1 and optionally link2, and RT715 on link 3.
To clarify configurations, the rt1308 configurations are split between single amp on link1 and dual amps on link1. The case with two amps on different links is already identified with the group1 attribute.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- .../intel/common/soc-acpi-intel-cml-match.c | 6 +- .../intel/common/soc-acpi-intel-tgl-match.c | 100 +++++++++++++++++- 2 files changed, 100 insertions(+), 6 deletions(-)
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 51535cd60a0a..8ac01a2d5886 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -118,7 +118,7 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { } };
-static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { +static const struct snd_soc_acpi_adr_device rt1308_1_single_adr[] = { { .adr = 0x000120025D130800, .num_endpoints = 1, @@ -182,8 +182,8 @@ static const struct snd_soc_acpi_link_adr cml_3_in_1_mono_amp[] = { }, { .mask = BIT(1), - .num_adr = ARRAY_SIZE(rt1308_1_adr), - .adr_d = rt1308_1_adr, + .num_adr = ARRAY_SIZE(rt1308_1_single_adr), + .adr_d = rt1308_1_single_adr, }, { .mask = BIT(3), 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 472f58ddda1f..aabb49617d37 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -43,7 +43,7 @@ static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { } };
-static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { +static const struct snd_soc_acpi_adr_device rt1308_1_dual_adr[] = { { .adr = 0x000120025D130800, .num_endpoints = 1, @@ -56,6 +56,38 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = { } };
+static const struct snd_soc_acpi_adr_device rt1308_1_single_adr[] = { + { + .adr = 0x000120025D130800, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = { + { + .adr = 0x000120025D130800, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1308_2_group1_adr[] = { + { + .adr = 0x000220025D130800, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { + { + .adr = 0x000320025D071500, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + static const struct snd_soc_acpi_adr_device mx8373_1_adr[] = { { .adr = 0x000123019F837300, @@ -94,8 +126,8 @@ static const struct snd_soc_acpi_link_adr tgl_rvp[] = { }, { .mask = BIT(1), - .num_adr = ARRAY_SIZE(rt1308_1_adr), - .adr_d = rt1308_1_adr, + .num_adr = ARRAY_SIZE(rt1308_1_dual_adr), + .adr_d = rt1308_1_dual_adr, }, {} }; @@ -114,6 +146,49 @@ static const struct snd_soc_acpi_link_adr tgl_chromebook_base[] = { {} };
+static const struct snd_soc_acpi_link_adr tgl_3_in_1_default[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_0_adr), + .adr_d = rt711_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1308_1_group1_adr), + .adr_d = rt1308_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1308_2_group1_adr), + .adr_d = rt1308_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt715_3_adr), + .adr_d = rt715_3_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr tgl_3_in_1_mono_amp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_0_adr), + .adr_d = rt711_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1308_1_single_adr), + .adr_d = rt1308_1_single_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt715_3_adr), + .adr_d = rt715_3_adr, + }, + {} +}; + static struct snd_soc_acpi_codecs tgl_max98373_amp = { .num_codecs = 1, .codecs = {"MX98373"} @@ -150,6 +225,25 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_tgl_machines);
/* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { + { + .link_mask = 0xF, /* 4 active links required */ + .links = tgl_3_in_1_default, + .drv_name = "sof_sdw", + .sof_fw_filename = "sof-tgl.ri", + .sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg", + }, + { + /* + * link_mask should be 0xB, but all links are enabled by BIOS. + * This entry will be selected if there is no rt1308 exposed + * on link2 since it will fail to match the above entry. + */ + .link_mask = 0xF, + .links = tgl_3_in_1_mono_amp, + .drv_name = "sof_sdw", + .sof_fw_filename = "sof-tgl.ri", + .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", + }, { .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ .links = tgl_rvp,
The description and board layout is similar to previous ones for CometLake and TigerLake, except for a bump to SoundWire 1.2 and updates to part numbers to reflect the SDCA (SoundWire Device Class for Audio) hardware support.
Note that one of the RT1316 amplifiers uses a non-zero UniqueID which is not required and will be ignored.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Jaska Uimonen jaska.uimonen@intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- .../intel/common/soc-acpi-intel-cml-match.c | 63 +++++++++++++++++++ .../intel/common/soc-acpi-intel-tgl-match.c | 63 +++++++++++++++++++ 2 files changed, 126 insertions(+)
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 8ac01a2d5886..ec01884ef93d 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -150,6 +150,38 @@ static const struct snd_soc_acpi_adr_device rt715_3_adr[] = { } };
+static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { + { + .adr = 0x000131025D131601, /* unique ID is set for some reason */ + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_2_group1_adr[] = { + { + .adr = 0x000230025D131601, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt714_3_adr[] = { + { + .adr = 0x000330025D071401, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + static const struct snd_soc_acpi_link_adr cml_3_in_1_default[] = { { .mask = BIT(0), @@ -193,6 +225,30 @@ static const struct snd_soc_acpi_link_adr cml_3_in_1_mono_amp[] = { {} };
+static const struct snd_soc_acpi_link_adr cml_3_in_1_sdca[] = { + { + .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, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = { { .link_mask = 0xF, /* 4 active links required */ @@ -201,6 +257,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[] = { .sof_fw_filename = "sof-cml.ri", .sof_tplg_filename = "sof-cml-rt711-rt1308-rt715.tplg", }, + { + .link_mask = 0xF, /* 4 active links required */ + .links = cml_3_in_1_sdca, + .drv_name = "sof_sdw", + .sof_fw_filename = "sof-cml.ri", + .sof_tplg_filename = "sof-cml-rt711-rt1316-rt714.tplg", + }, { /* * link_mask should be 0xB, but all links are enabled by BIOS. 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 aabb49617d37..6816847bee40 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -109,6 +109,38 @@ static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = { } };
+static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { + { + .adr = 0x000131025D131601, /* unique ID is set for some reason */ + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_2_group1_adr[] = { + { + .adr = 0x000230025D131601, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + } +}; + +static const struct snd_soc_acpi_adr_device rt714_3_adr[] = { + { + .adr = 0x000330025D071401, + .num_endpoints = 1, + .endpoints = &single_endpoint, + } +}; + static const struct snd_soc_acpi_link_adr tgl_i2s_rt1308[] = { { .mask = BIT(0), @@ -189,6 +221,30 @@ static const struct snd_soc_acpi_link_adr tgl_3_in_1_mono_amp[] = { {} };
+static const struct snd_soc_acpi_link_adr tgl_3_in_1_sdca[] = { + { + .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 struct snd_soc_acpi_codecs tgl_max98373_amp = { .num_codecs = 1, .codecs = {"MX98373"} @@ -244,6 +300,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .sof_fw_filename = "sof-tgl.ri", .sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg", }, + { + .link_mask = 0xF, /* 4 active links required */ + .links = tgl_3_in_1_sdca, + .drv_name = "sof_sdw", + .sof_fw_filename = "sof-tgl.ri", + .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", + }, { .link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */ .links = tgl_rvp,
From: Rander Wang rander.wang@intel.com
When the playback & capture streams are stopped simultaneously, the SOF PCI device will remain pm_runtime active. The root-cause is a race condition with two threads reaching the trigger function at the same time. They see another stream is active so the dapm pin is not disabled, so the codec remains active as well as the parent PCI device.
For max98373, the capture stream provides feedback when playback is working and it is unused when playback is stopped. So the dapm pin should be set only when playback is active.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Rander Wang rander.wang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_maxim_common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 1a6961592029..b6e63ea13d64 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -66,6 +66,10 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) int j; int ret = 0;
+ /* set spk pin by playback only */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + return 0; + for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_component *component = codec_dai->component; struct snd_soc_dapm_context *dapm = @@ -86,9 +90,6 @@ int max98373_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - /* Make sure no streams are active before disable pin */ - if (snd_soc_dai_active(codec_dai) != 1) - break; ret = snd_soc_dapm_disable_pin(dapm, pin_name); if (!ret) snd_soc_dapm_sync(dapm);
On Fri, Aug 21, 2020 at 02:55:53PM -0500, Pierre-Louis Bossart wrote:
From: Rander Wang rander.wang@intel.com
When the playback & capture streams are stopped simultaneously, the SOF PCI device will remain pm_runtime active. The root-cause is a race condition with two threads reaching the trigger function at the same time. They see another stream is active so the dapm pin is not disabled, so the codec remains active as well as the parent PCI device.
For max98373, the capture stream provides feedback when playback is working and it is unused when playback is stopped. So the dapm pin should be set only when playback is active.
Should this be sent as a fix?
When the playback & capture streams are stopped simultaneously, the SOF PCI device will remain pm_runtime active. The root-cause is a race condition with two threads reaching the trigger function at the same time. They see another stream is active so the dapm pin is not disabled, so the codec remains active as well as the parent PCI device.
For max98373, the capture stream provides feedback when playback is working and it is unused when playback is stopped. So the dapm pin should be set only when playback is active.
Should this be sent as a fix?
Ah yes, good point. I thought it was a SoundWire-only patch but no it also applies to the TDM configuration.
These should be a tag:
Fixes: 94d2d08974746 ('ASoC: Intel: Boards: tgl_max98373: add dai_trigger function')
Do you want me to resend with the tag, or can you apply it directly?
All existing SoundWire codecs follow the same pattern on resume, except for this codec which doesn't test if the hardware is initialized.
Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/codecs/max98373-sdw.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 5fe724728e84..6469612c42cb 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -256,6 +256,9 @@ static __maybe_unused int max98373_resume(struct device *dev) struct max98373_priv *max98373 = dev_get_drvdata(dev); unsigned long time;
+ if (!max98373->hw_init) + return 0; + if (!slave->unattach_request) goto regmap_sync;
From: Bard Liao yung-chuan.liao@linux.intel.com
Some codecs with the same part id but different SoundWire versions have different configurations. So we have to separate them in codec_info_list[].
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 35 ++++++++++++++----------- sound/soc/intel/boards/sof_sdw_common.h | 1 + 2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 100c0a83a6ad..dca981f7c7d3 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -253,18 +253,25 @@ static struct sof_sdw_codec_info codec_info_list[] = { }, };
-static inline int find_codec_info_part(unsigned int part_id) +static inline int find_codec_info_part(u64 adr) { + unsigned int part_id, sdw_version; int i;
+ part_id = SDW_PART_ID(adr); + sdw_version = SDW_VERSION(adr); for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) - if (part_id == codec_info_list[i].id) - break; + /* + * A codec info is for all sdw version with the part id if + * version_id is not specified in the codec info. + */ + if (part_id == codec_info_list[i].id && + (!codec_info_list[i].version_id || + sdw_version == codec_info_list[i].version_id)) + return i;
- if (i == ARRAY_SIZE(codec_info_list)) - return -EINVAL; + return -EINVAL;
- return i; }
static inline int find_codec_info_acpi(const u8 *acpi_id) @@ -310,13 +317,12 @@ static int get_sdw_dailink_info(const struct snd_soc_acpi_link_adr *links,
for (link = links; link->num_adr; link++) { const struct snd_soc_acpi_endpoint *endpoint; - int part_id, codec_index; + int codec_index; int stream; u64 adr;
adr = link->adr_d->adr; - part_id = SDW_PART_ID(adr); - codec_index = find_codec_info_part(part_id); + codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index;
@@ -444,7 +450,7 @@ static int create_codec_dai_name(struct device *dev, if (!codec[comp_index].name) return -ENOMEM;
- codec_index = find_codec_info_part(part_id); + codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index;
@@ -468,11 +474,9 @@ static int set_codec_init_func(const struct snd_soc_acpi_link_adr *link, * same group. */ for (i = 0; i < link->num_adr; i++) { - unsigned int part_id; int codec_index;
- part_id = SDW_PART_ID(link->adr_d[i].adr); - codec_index = find_codec_info_part(part_id); + codec_index = find_codec_info_part(link->adr_d[i].adr);
if (codec_index < 0) return codec_index; @@ -576,7 +580,7 @@ static int create_sdw_dailink(struct device *dev, int *be_index, struct snd_soc_dai_link_component *codecs; int cpu_dai_id[SDW_MAX_CPU_DAIS]; int cpu_dai_num, cpu_dai_index; - unsigned int part_id, group_id; + unsigned int group_id; int codec_idx = 0; int i = 0, j = 0; int codec_index; @@ -618,8 +622,7 @@ static int create_sdw_dailink(struct device *dev, int *be_index, }
/* find codec info to create BE DAI */ - part_id = SDW_PART_ID(link->adr_d[0].adr); - codec_index = find_codec_info_part(part_id); + codec_index = find_codec_info_part(link->adr_d[0].adr); if (codec_index < 0) return codec_index;
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 76d6c0c3839d..cb1320348d0b 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -52,6 +52,7 @@ enum {
struct sof_sdw_codec_info { const int id; + const int version_id; int amp_num; const u8 acpi_id[ACPI_ID_LEN]; const bool direction[2]; // playback & capture support
From: Bard Liao yung-chuan.liao@linux.intel.com
The "id" field in sof_sdw_codec_info struct is actually the "part id". Rename to prevent confusions.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 14 +++++++------- sound/soc/intel/boards/sof_sdw_common.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index dca981f7c7d3..ca231459ac10 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -212,20 +212,20 @@ static const struct snd_soc_ops sdw_ops = {
static struct sof_sdw_codec_info codec_info_list[] = { { - .id = 0x700, + .part_id = 0x700, .direction = {true, true}, .dai_name = "rt700-aif1", .init = sof_sdw_rt700_init, }, { - .id = 0x711, + .part_id = 0x711, .direction = {true, true}, .dai_name = "rt711-aif1", .init = sof_sdw_rt711_init, .exit = sof_sdw_rt711_exit, }, { - .id = 0x1308, + .part_id = 0x1308, .acpi_id = "10EC1308", .direction = {true, false}, .dai_name = "rt1308-aif", @@ -233,20 +233,20 @@ static struct sof_sdw_codec_info codec_info_list[] = { .init = sof_sdw_rt1308_init, }, { - .id = 0x715, + .part_id = 0x715, .direction = {false, true}, .dai_name = "rt715-aif2", .init = sof_sdw_rt715_init, }, { - .id = 0x8373, + .part_id = 0x8373, .direction = {true, true}, .dai_name = "max98373-aif1", .init = sof_sdw_mx8373_init, .codec_card_late_probe = sof_sdw_mx8373_late_probe, }, { - .id = 0x5682, + .part_id = 0x5682, .direction = {true, true}, .dai_name = "rt5682-sdw", .init = sof_sdw_rt5682_init, @@ -265,7 +265,7 @@ static inline int find_codec_info_part(u64 adr) * A codec info is for all sdw version with the part id if * version_id is not specified in the codec info. */ - if (part_id == codec_info_list[i].id && + if (part_id == codec_info_list[i].part_id && (!codec_info_list[i].version_id || sdw_version == codec_info_list[i].version_id)) return i; diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index cb1320348d0b..ce0680a7b180 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -51,7 +51,7 @@ enum { #define SOF_SDW_NO_AGGREGATION BIT(12)
struct sof_sdw_codec_info { - const int id; + const int part_id; const int version_id; int amp_num; const u8 acpi_id[ACPI_ID_LEN];
From: Rander Wang rander.wang@intel.com
Ripto is another product based on TGL with the same audio hardware configuration as Volteer.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Rander Wang rander.wang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ca231459ac10..44d06fa48b24 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -123,6 +123,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | + SOF_SDW_FOUR_SPK), + },
{} };
From: Rander Wang rander.wang@intel.com
Ripto is another product based on TGL with the same audio hardware configuration as Volteer.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Rander Wang rander.wang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ca231459ac10..44d06fa48b24 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -123,6 +123,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC | + SOF_SDW_FOUR_SPK), + },
{} };
From: Sathyanarayana Nujella sathyanarayana.nujella@intel.com
A Chrome System based on tgl_max98373_rt5682 has different SSP interface configurations. Using DMI data of this variant DUT, override quirk data.
Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Signed-off-by: Sathyanarayana Nujella sathyanarayana.nujella@intel.com Signed-off-by: Mac Chiang mac.chiang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_rt5682.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 0129d23694ed..9a6f10ede427 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -119,6 +119,19 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0)), }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Terrador"), + }, + .driver_data = (void *)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_MAX98373_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(2) | + SOF_RT5682_NUM_HDMIDEV(4)), + }, {} };
From: Sathyanarayana Nujella sathyanarayana.nujella@intel.com
Add topology filename override based on system DMI data matching, typically to account for a different hardware layout.
In ACPI based systems, the tplg_filename is pre-defined in an ACPI machine table. When a DMI quirk is detected, the sof_pdata->tplg_filename is not set with the hard-coded ACPI value, and instead is set with the DMI-specific filename.
Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Signed-off-by: Sathyanarayana Nujella sathyanarayana.nujella@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/sof/intel/hda.c | 8 +++++++- sound/soc/sof/sof-pci-dev.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index c0b75d682750..b8157c1f37f3 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1179,7 +1179,13 @@ void hda_machine_select(struct snd_sof_dev *sdev)
mach = snd_soc_acpi_find_machine(desc->machines); if (mach) { - sof_pdata->tplg_filename = mach->sof_tplg_filename; + /* + * If tplg file name is overridden, use it instead of + * the one set in mach table + */ + if (!sof_pdata->tplg_filename) + sof_pdata->tplg_filename = mach->sof_tplg_filename; + sof_pdata->machine = mach;
if (mach->link_mask) { diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index aa3532ba1434..f3a8140773db 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -35,8 +35,28 @@ static int sof_pci_debug; module_param_named(sof_pci_debug, sof_pci_debug, int, 0444); MODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)");
+static const char *sof_override_tplg_name; + #define SOF_PCI_DISABLE_PM_RUNTIME BIT(0)
+static int sof_tplg_cb(const struct dmi_system_id *id) +{ + sof_override_tplg_name = id->driver_data; + return 1; +} + +static const struct dmi_system_id sof_tplg_table[] = { + { + .callback = sof_tplg_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Terrador"), + }, + .driver_data = "sof-tgl-rt5682-ssp0-max98373-ssp2.tplg", + }, + {} +}; + static const struct dmi_system_id community_key_platforms[] = { { .ident = "Up Squared", @@ -347,6 +367,10 @@ static int sof_pci_probe(struct pci_dev *pci, sof_pdata->tplg_filename_prefix = sof_pdata->desc->default_tplg_path;
+ dmi_check_system(sof_tplg_table); + if (sof_override_tplg_name) + sof_pdata->tplg_filename = sof_override_tplg_name; + #if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE) /* set callback to enable runtime_pm */ sof_pdata->sof_probe_complete = sof_pci_probe_complete;
From: Bard Liao yung-chuan.liao@linux.intel.com
Add rt711, rt1316, and rt714 SDCA codecs support in sof_sdw machine driver.
Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/Kconfig | 3 + sound/soc/intel/boards/Makefile | 7 +- sound/soc/intel/boards/sof_sdw.c | 37 +++++ sound/soc/intel/boards/sof_sdw_common.h | 19 +++ sound/soc/intel/boards/sof_sdw_rt1316.c | 113 +++++++++++++ sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 174 ++++++++++++++++++++ sound/soc/intel/boards/sof_sdw_rt715_sdca.c | 42 +++++ 7 files changed, 392 insertions(+), 3 deletions(-) create mode 100644 sound/soc/intel/boards/sof_sdw_rt1316.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt711_sdca.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt715_sdca.c
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index d96fc1313434..12dd41796e82 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -569,9 +569,12 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_MAX98373_SDW select SND_SOC_RT700_SDW select SND_SOC_RT711_SDW + select SND_SOC_RT711_SDCA_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 + select SND_SOC_RT1316_SDW select SND_SOC_RT715_SDW + select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW select SND_SOC_DMIC help diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index dc04acb911b6..de7cc9b86354 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -35,9 +35,10 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o hda_dsp_common.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o hda_dsp_common.o snd-soc-sof-sdw-objs += sof_sdw.o \ sof_sdw_max98373.o \ - sof_sdw_rt711.o sof_sdw_rt700.o \ - sof_sdw_rt1308.o sof_sdw_rt715.o \ - sof_sdw_rt5682.o \ + sof_sdw_rt1308.o sof_sdw_rt1316.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_maxim_common.o \ sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 44d06fa48b24..00d10e83872a 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -141,6 +141,10 @@ static struct snd_soc_codec_conf codec_conf[] = { .dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"), .name_prefix = "rt711", }, + { + .dlc = COMP_CODEC_CONF("sdw:0:25d:711:1"), + .name_prefix = "rt711", + }, /* rt1308 w/ I2S connection */ { .dlc = COMP_CODEC_CONF("i2c-10EC1308:00"), @@ -187,6 +191,18 @@ static struct snd_soc_codec_conf codec_conf[] = { .dlc = COMP_CODEC_CONF("sdw:2:25d:5682:0"), .name_prefix = "rt5682", }, + { + .dlc = COMP_CODEC_CONF("sdw:1:25d:1316:1"), + .name_prefix = "rt1316-1", + }, + { + .dlc = COMP_CODEC_CONF("sdw:2:25d:1316:1"), + .name_prefix = "rt1316-2", + }, + { + .dlc = COMP_CODEC_CONF("sdw:3:25d:714:1"), + .name_prefix = "rt714", + }, };
static struct snd_soc_dai_link_component dmic_component[] = { @@ -228,6 +244,15 @@ static struct sof_sdw_codec_info codec_info_list[] = { }, { .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, + }, + { + .part_id = 0x711, + .version_id = 2, .direction = {true, true}, .dai_name = "rt711-aif1", .init = sof_sdw_rt711_init, @@ -241,6 +266,18 @@ static struct sof_sdw_codec_info codec_info_list[] = { .ops = &sof_sdw_rt1308_i2s_ops, .init = sof_sdw_rt1308_init, }, + { + .part_id = 0x1316, + .direction = {true, true}, + .dai_name = "rt1316-aif", + .init = sof_sdw_rt1316_init, + }, + { + .part_id = 0x714, + .direction = {false, true}, + .dai_name = "rt715-aif2", + .init = sof_sdw_rt715_sdca_init, + }, { .part_id = 0x715, .direction = {false, true}, diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index ce0680a7b180..6a5d46589baf 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -96,6 +96,13 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, bool playback); int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link);
+/* RT711-SDCA support */ +int sof_sdw_rt711_sdca_init(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 device *dev, struct snd_soc_dai_link *dai_link); + /* RT700 support */ int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, @@ -110,12 +117,24 @@ int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link, struct sof_sdw_codec_info *info, bool playback);
+/* RT1316 support */ +int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* RT715 support */ int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback);
+/* RT715-SDCA support */ +int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* MAX98373 support */ int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c new file mode 100644 index 000000000000..2c566330f236 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt1316.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt1316 - Helpers to handle RT1316 from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.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 rt1316_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt1316 will be registered dynamically according + * to the number of rt1316 used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two 1316s are used. + */ +static const struct snd_soc_dapm_route rt1316_map[] = { + { "Speaker", NULL, "rt1316-1 SPOL" }, + { "Speaker", NULL, "rt1316-1 SPOR" }, + { "Speaker", NULL, "rt1316-2 SPOL" }, + { "Speaker", NULL, "rt1316-2 SPOR" }, +}; + +static const struct snd_kcontrol_new rt1316_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int first_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_add_card_controls(card, rt1316_controls, + ARRAY_SIZE(rt1316_controls)); + if (ret) { + dev_err(card->dev, "rt1316 controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt1316_widgets, + ARRAY_SIZE(rt1316_widgets)); + if (ret) { + dev_err(card->dev, "rt1316 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map, 2); + if (ret) + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); + + return ret; +} + +static int second_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map + 2, 2); + if (ret) + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); + + return ret; +} + +static int all_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = first_spk_init(rtd); + if (ret) + return ret; + + return second_spk_init(rtd); +} + +int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + if (info->amp_num == 1) + dai_links->init = first_spk_init; + + if (info->amp_num == 2) { + /* + * if two 1316s are in one dai link, the init function + * in this dai link will be first set for the first speaker, + * and it should be reset to initialize all speakers when + * the second speaker is found. + */ + if (dai_links->init) + dai_links->init = all_spk_init; + else + dai_links->init = second_spk_init; + } + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c new file mode 100644 index 000000000000..19496f0f9110 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt711_sdca - Helpers to handle RT711-SDCA 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" + +/* + * 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(const char *sdw_dev_name) +{ + struct property_entry props[MAX_NO_PROPS] = {}; + struct device *sdw_dev; + int ret; + + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name); + if (!sdw_dev) + return -EPROBE_DEFER; + + if (SOF_RT711_JDSRC(sof_sdw_quirk)) { + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", + SOF_RT711_JDSRC(sof_sdw_quirk)); + } + + ret = device_add_properties(sdw_dev, props); + put_device(sdw_dev); + + return ret; +} + +static const struct snd_soc_dapm_widget rt711_sdca_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[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int rt711_sdca_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:rt711-sdca", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt711_sdca_controls, + ARRAY_SIZE(rt711_sdca_controls)); + if (ret) { + dev_err(card->dev, "rt711-sdca controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt711_sdca_widgets, + ARRAY_SIZE(rt711_sdca_widgets)); + if (ret) { + dev_err(card->dev, "rt711-sdca 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 (ret) { + dev_err(card->dev, "rt711-sdca map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new(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, + rt711_sdca_jack_pins, + ARRAY_SIZE(rt711_sdca_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_rt711_sdca_exit(struct device *dev, struct snd_soc_dai_link *dai_link) +{ + struct device *sdw_dev; + + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, + dai_link->codecs[0].name); + if (!sdw_dev) + return -EINVAL; + + device_remove_properties(sdw_dev); + put_device(sdw_dev); + + return 0; +} + +int sof_sdw_rt711_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + int ret; + + /* + * headset should be initialized once. + * Do it with dai link for playback. + */ + if (!playback) + return 0; + + ret = rt711_sdca_add_codec_device_props(dai_links->codecs[0].name); + if (ret < 0) + return ret; + + dai_links->init = rt711_sdca_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c new file mode 100644 index 000000000000..c056e56a139b --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt715_sdca - Helpers to handle RT715-SDCA from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include "sof_sdw_common.h" + +static int rt715_sdca_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:rt715-sdca", + card->components); + if (!card->components) + return -ENOMEM; + + return 0; +} + +int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * DAI ID is fixed at SDW_DMIC_DAI_ID for 715-SDCA to + * keep sdw DMIC and HDMI setting static in UCM + */ + if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX) + dai_links->id = SDW_DMIC_DAI_ID; + + dai_links->init = rt715_sdca_rtd_init; + + return 0; +}
From: Bard Liao yung-chuan.liao@linux.intel.com
Add rt711, rt1316, and rt714 SDCA codecs support in sof_sdw machine driver.
Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/Kconfig | 3 + sound/soc/intel/boards/Makefile | 7 +- sound/soc/intel/boards/sof_sdw.c | 37 +++++ sound/soc/intel/boards/sof_sdw_common.h | 19 +++ sound/soc/intel/boards/sof_sdw_rt1316.c | 113 +++++++++++++ sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 174 ++++++++++++++++++++ sound/soc/intel/boards/sof_sdw_rt715_sdca.c | 42 +++++ 7 files changed, 392 insertions(+), 3 deletions(-) create mode 100644 sound/soc/intel/boards/sof_sdw_rt1316.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt711_sdca.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt715_sdca.c
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index d96fc1313434..12dd41796e82 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -569,9 +569,12 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_MAX98373_SDW select SND_SOC_RT700_SDW select SND_SOC_RT711_SDW + select SND_SOC_RT711_SDCA_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 + select SND_SOC_RT1316_SDW select SND_SOC_RT715_SDW + select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW select SND_SOC_DMIC help diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index dc04acb911b6..de7cc9b86354 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -35,9 +35,10 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o hda_dsp_common.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o hda_dsp_common.o snd-soc-sof-sdw-objs += sof_sdw.o \ sof_sdw_max98373.o \ - sof_sdw_rt711.o sof_sdw_rt700.o \ - sof_sdw_rt1308.o sof_sdw_rt715.o \ - sof_sdw_rt5682.o \ + sof_sdw_rt1308.o sof_sdw_rt1316.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_maxim_common.o \ sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 44d06fa48b24..00d10e83872a 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -141,6 +141,10 @@ static struct snd_soc_codec_conf codec_conf[] = { .dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"), .name_prefix = "rt711", }, + { + .dlc = COMP_CODEC_CONF("sdw:0:25d:711:1"), + .name_prefix = "rt711", + }, /* rt1308 w/ I2S connection */ { .dlc = COMP_CODEC_CONF("i2c-10EC1308:00"), @@ -187,6 +191,18 @@ static struct snd_soc_codec_conf codec_conf[] = { .dlc = COMP_CODEC_CONF("sdw:2:25d:5682:0"), .name_prefix = "rt5682", }, + { + .dlc = COMP_CODEC_CONF("sdw:1:25d:1316:1"), + .name_prefix = "rt1316-1", + }, + { + .dlc = COMP_CODEC_CONF("sdw:2:25d:1316:1"), + .name_prefix = "rt1316-2", + }, + { + .dlc = COMP_CODEC_CONF("sdw:3:25d:714:1"), + .name_prefix = "rt714", + }, };
static struct snd_soc_dai_link_component dmic_component[] = { @@ -228,6 +244,15 @@ static struct sof_sdw_codec_info codec_info_list[] = { }, { .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, + }, + { + .part_id = 0x711, + .version_id = 2, .direction = {true, true}, .dai_name = "rt711-aif1", .init = sof_sdw_rt711_init, @@ -241,6 +266,18 @@ static struct sof_sdw_codec_info codec_info_list[] = { .ops = &sof_sdw_rt1308_i2s_ops, .init = sof_sdw_rt1308_init, }, + { + .part_id = 0x1316, + .direction = {true, true}, + .dai_name = "rt1316-aif", + .init = sof_sdw_rt1316_init, + }, + { + .part_id = 0x714, + .direction = {false, true}, + .dai_name = "rt715-aif2", + .init = sof_sdw_rt715_sdca_init, + }, { .part_id = 0x715, .direction = {false, true}, diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index ce0680a7b180..6a5d46589baf 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -96,6 +96,13 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, bool playback); int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link);
+/* RT711-SDCA support */ +int sof_sdw_rt711_sdca_init(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 device *dev, struct snd_soc_dai_link *dai_link); + /* RT700 support */ int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, @@ -110,12 +117,24 @@ int sof_sdw_rt1308_init(const struct snd_soc_acpi_link_adr *link, struct sof_sdw_codec_info *info, bool playback);
+/* RT1316 support */ +int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* RT715 support */ int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback);
+/* RT715-SDCA support */ +int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* MAX98373 support */ int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c new file mode 100644 index 000000000000..2c566330f236 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt1316.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt1316 - Helpers to handle RT1316 from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.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 rt1316_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt1316 will be registered dynamically according + * to the number of rt1316 used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two 1316s are used. + */ +static const struct snd_soc_dapm_route rt1316_map[] = { + { "Speaker", NULL, "rt1316-1 SPOL" }, + { "Speaker", NULL, "rt1316-1 SPOR" }, + { "Speaker", NULL, "rt1316-2 SPOL" }, + { "Speaker", NULL, "rt1316-2 SPOR" }, +}; + +static const struct snd_kcontrol_new rt1316_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int first_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_add_card_controls(card, rt1316_controls, + ARRAY_SIZE(rt1316_controls)); + if (ret) { + dev_err(card->dev, "rt1316 controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt1316_widgets, + ARRAY_SIZE(rt1316_widgets)); + if (ret) { + dev_err(card->dev, "rt1316 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map, 2); + if (ret) + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); + + return ret; +} + +static int second_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map + 2, 2); + if (ret) + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); + + return ret; +} + +static int all_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = first_spk_init(rtd); + if (ret) + return ret; + + return second_spk_init(rtd); +} + +int sof_sdw_rt1316_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + if (info->amp_num == 1) + dai_links->init = first_spk_init; + + if (info->amp_num == 2) { + /* + * if two 1316s are in one dai link, the init function + * in this dai link will be first set for the first speaker, + * and it should be reset to initialize all speakers when + * the second speaker is found. + */ + if (dai_links->init) + dai_links->init = all_spk_init; + else + dai_links->init = second_spk_init; + } + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c new file mode 100644 index 000000000000..19496f0f9110 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt711_sdca - Helpers to handle RT711-SDCA 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" + +/* + * 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(const char *sdw_dev_name) +{ + struct property_entry props[MAX_NO_PROPS] = {}; + struct device *sdw_dev; + int ret; + + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name); + if (!sdw_dev) + return -EPROBE_DEFER; + + if (SOF_RT711_JDSRC(sof_sdw_quirk)) { + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", + SOF_RT711_JDSRC(sof_sdw_quirk)); + } + + ret = device_add_properties(sdw_dev, props); + put_device(sdw_dev); + + return ret; +} + +static const struct snd_soc_dapm_widget rt711_sdca_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[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int rt711_sdca_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:rt711-sdca", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt711_sdca_controls, + ARRAY_SIZE(rt711_sdca_controls)); + if (ret) { + dev_err(card->dev, "rt711-sdca controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt711_sdca_widgets, + ARRAY_SIZE(rt711_sdca_widgets)); + if (ret) { + dev_err(card->dev, "rt711-sdca 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 (ret) { + dev_err(card->dev, "rt711-sdca map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new(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, + rt711_sdca_jack_pins, + ARRAY_SIZE(rt711_sdca_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_rt711_sdca_exit(struct device *dev, struct snd_soc_dai_link *dai_link) +{ + struct device *sdw_dev; + + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, + dai_link->codecs[0].name); + if (!sdw_dev) + return -EINVAL; + + device_remove_properties(sdw_dev); + put_device(sdw_dev); + + return 0; +} + +int sof_sdw_rt711_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + int ret; + + /* + * headset should be initialized once. + * Do it with dai link for playback. + */ + if (!playback) + return 0; + + ret = rt711_sdca_add_codec_device_props(dai_links->codecs[0].name); + if (ret < 0) + return ret; + + dai_links->init = rt711_sdca_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt715_sdca.c b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c new file mode 100644 index 000000000000..c056e56a139b --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt715_sdca.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020 Intel Corporation + +/* + * sof_sdw_rt715_sdca - Helpers to handle RT715-SDCA from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include "sof_sdw_common.h" + +static int rt715_sdca_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:rt715-sdca", + card->components); + if (!card->components) + return -ENOMEM; + + return 0; +} + +int sof_sdw_rt715_sdca_init(const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * DAI ID is fixed at SDW_DMIC_DAI_ID for 715-SDCA to + * keep sdw DMIC and HDMI setting static in UCM + */ + if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX) + dai_links->id = SDW_DMIC_DAI_ID; + + dai_links->init = rt715_sdca_rtd_init; + + return 0; +}
From: Bard Liao yung-chuan.liao@linux.intel.com
"struct snd_soc_dapm_widget" and "struct snd_kcontrol_new" are used in most of these .c files. Adding the header files to prevent from depending on <sound/soc.h>
Reported-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Reviewed-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_sdw_dmic.c | 1 + sound/soc/intel/boards/sof_sdw_max98373.c | 2 ++ sound/soc/intel/boards/sof_sdw_rt1308.c | 2 ++ sound/soc/intel/boards/sof_sdw_rt5682.c | 2 ++ sound/soc/intel/boards/sof_sdw_rt700.c | 2 ++ sound/soc/intel/boards/sof_sdw_rt711.c | 2 ++ 6 files changed, 11 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw_dmic.c b/sound/soc/intel/boards/sof_sdw_dmic.c index 89b0824b2381..19df0f7a1d85 100644 --- a/sound/soc/intel/boards/sof_sdw_dmic.c +++ b/sound/soc/intel/boards/sof_sdw_dmic.c @@ -7,6 +7,7 @@
#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 dmic_widgets[] = { diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_max98373.c index 6437872a9b3d..905582aaf58c 100644 --- a/sound/soc/intel/boards/sof_sdw_max98373.c +++ b/sound/soc/intel/boards/sof_sdw_max98373.c @@ -6,8 +6,10 @@
#include <linux/device.h> #include <linux/errno.h> +#include <sound/control.h> #include <sound/soc.h> #include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> #include "sof_sdw_common.h" #include "sof_maxim_common.h"
diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c index 3655e890acec..dba2fd28d77f 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1308.c +++ b/sound/soc/intel/boards/sof_sdw_rt1308.c @@ -7,8 +7,10 @@
#include <linux/device.h> #include <linux/errno.h> +#include <sound/control.h> #include <sound/soc.h> #include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> #include "sof_sdw_common.h" #include "../../codecs/rt1308.h"
diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/intel/boards/sof_sdw_rt5682.c index da354ba83939..5fa1a59615b6 100644 --- a/sound/soc/intel/boards/sof_sdw_rt5682.c +++ b/sound/soc/intel/boards/sof_sdw_rt5682.c @@ -10,8 +10,10 @@ #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"
diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/intel/boards/sof_sdw_rt700.c index 5f50491ba5ee..bff69cfe27f4 100644 --- a/sound/soc/intel/boards/sof_sdw_rt700.c +++ b/sound/soc/intel/boards/sof_sdw_rt700.c @@ -8,8 +8,10 @@ #include <linux/device.h> #include <linux/errno.h> #include <linux/input.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"
diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 606009fa3901..04074c09dded 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -10,8 +10,10 @@ #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"
On Fri, 21 Aug 2020 14:55:47 -0500, Pierre-Louis Bossart wrote:
This series updates the tables used to select SoundWire configurations for CometLake and TigerLake, and adds support for SDCA (SoundWire Device Class for Audio) codecs in the common machine driver. These codec drivers are still being tested on early silicon/boards and will be contributed at a later time.
For TigerLake Chromebooks a new DMI quirk is added, as well as a means to override the topology names. A pm_runtime fix is also provided to deal with playback/capture dependencies with an amplifier w/ feedback. I also included a minor codec correction for the TGL amplifier.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/14] ASoC: Intel: modify SoundWire version id in acpi match table commit: 69a785da525e8bdfaa8a9c000fb3af714f0d719b [02/14] ASoC: Intel: soc-acpi: cnl: add support for rt5682 on SoundWire link2 commit: 6f7cf9125ed43daaf4c5dd34ebcd96c978fcd2b2 [03/14] ASoC: Intel: sof-soundwire: add support for rt5682 on link2 commit: b161a12192f4b88cede8a563a6ebd2336d905d18 [04/14] ASoC: Intel: soc-acpi: mirror CML and TGL configurations commit: 6cb8bd60ba5ca9eb8f05f3f8351bbbcb6b92c525 [05/14] ASoC: Intel: soc-acpi: add support for SDCA boards commit: 44751fc5f0de07b0a1ab57e9beab9789638d76d2 [06/14] ASoC: Intel: tgl_max98373: fix a runtime pm issue in multi-thread case commit: e300486ad94d2608ebc3aaed4e03e86eeeb97084 [07/14] ASoC: codecs: max98373-sdw: add missing test on resume commit: 65fae64d79d2cbad43819c1ab83390594fac7fcb [08/14] ASoC: Intel: sof_sdw: check SoundWire version when matching codec commit: 2e2d287bbe613be4848e83be9aa8e99e8b9f7dc0 [09/14] ASoC: Intel: sof_sdw: rename id as part_id commit: 535df653f75583a25c6bbb2eaaa0b121b47460c4 [10/14] SoC: Intel: sof_sdw: Add support for product Ripto commit: 626200df2498ff3044170d0f02b463ac0ec899c5 [11/14] ASoC: Intel: sof_rt5682: override quirk data for tgl_max98373_rt5682 commit: 3e1734b64ce786c54dc98adcfe67941e6011d735 [12/14] ASoC: SOF: Add topology filename override based on dmi data match commit: 5253a73d567dcd75e62834ff5f502ea9470e5722 [13/14] ASoC: intel: sof_sdw: add rt711 rt1316 rt714 SDCA codec support. commit: b75bea4b8834c1253b00d5f8df2dd3ce09d2e305 [14/14] ASoC: Intel: sof_sdw: clean-up inclusion of header files commit: 3f2c656491af6698cb3f18d5bd34afa1b54096d2
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
On Fri, 21 Aug 2020 14:55:47 -0500, Pierre-Louis Bossart wrote:
This series updates the tables used to select SoundWire configurations for CometLake and TigerLake, and adds support for SDCA (SoundWire Device Class for Audio) codecs in the common machine driver. These codec drivers are still being tested on early silicon/boards and will be contributed at a later time.
For TigerLake Chromebooks a new DMI quirk is added, as well as a means to override the topology names. A pm_runtime fix is also provided to deal with playback/capture dependencies with an amplifier w/ feedback. I also included a minor codec correction for the TGL amplifier.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/1] ASoC: Intel: tgl_max98373: fix a runtime pm issue in multi-thread case commit: e300486ad94d2608ebc3aaed4e03e86eeeb97084
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Pierre-Louis Bossart