ASoC: Intel: sof_sdw: Add support for cs42l43 optional speaker output
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Tue, 26 Mar 2024 16:04:29 +0000 (11:04 -0500)
committerMark Brown <broonie@kernel.org>
Tue, 26 Mar 2024 16:13:51 +0000 (16:13 +0000)
Add support for the optional speaker output on the cs42l43, this uses
the new SOF_CODEC_SPKR quirk to conditional include the speaker DAI
link. It is worth noting that currently no systems are included that
utilise this feature, but the feature is added as several systems are on
the horizon. As part of this SOF_SDW_MAX_DAI_NUM must be increased, it
is currently 3 but cs42l43 will now have 4 DAI links. This value is
increased to 8 to give some head room for future devices.

Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240326160429.13560-35-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/boards/sof_sdw_common.h
sound/soc/intel/boards/sof_sdw_cs42l43.c
sound/soc/intel/common/soc-acpi-intel-mtl-match.c
sound/soc/intel/common/soc-acpi-intel-tgl-match.c

index 4fc15f597e286cffeb3211a6d230c2a3ac575791..b94835448b1b429dec53b128781318afa674b4d8 100644 (file)
@@ -1016,8 +1016,17 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                                .dai_type = SOF_SDW_DAI_TYPE_JACK,
                                .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID},
                        },
+                       {
+                               .direction = {true, false},
+                               .dai_name = "cs42l43-dp6",
+                               .dai_type = SOF_SDW_DAI_TYPE_AMP,
+                               .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
+                               .init = sof_sdw_cs42l43_spk_init,
+                               .rtd_init = cs42l43_spk_rtd_init,
+                               .quirk = SOF_CODEC_SPKR,
+                       },
                },
-               .dai_num = 3,
+               .dai_num = 4,
        },
        {
                .part_id = 0xaaaa, /* generic codec mockup */
index 81181627b4060a2d9dc10b5bf2d12fbc9f8237bb..8468487a6bd6d9e7155a05ce352009c866ebb25b 100644 (file)
@@ -66,7 +66,7 @@ enum {
 #define SOF_SDW_DAI_TYPE_AMP           1
 #define SOF_SDW_DAI_TYPE_MIC           2
 
-#define SOF_SDW_MAX_DAI_NUM            3
+#define SOF_SDW_MAX_DAI_NUM            8
 
 struct sof_sdw_codec_info;
 
@@ -162,6 +162,12 @@ int sof_sdw_maxim_init(struct snd_soc_card *card,
                       struct sof_sdw_codec_info *info,
                       bool playback);
 
+/* CS42L43 support */
+int sof_sdw_cs42l43_spk_init(struct snd_soc_card *card,
+                            struct snd_soc_dai_link *dai_links,
+                            struct sof_sdw_codec_info *info,
+                            bool playback);
+
 /* CS AMP support */
 int sof_sdw_cs_amp_init(struct snd_soc_card *card,
                        struct snd_soc_dai_link *dai_links,
@@ -172,6 +178,7 @@ int sof_sdw_cs_amp_init(struct snd_soc_card *card,
 
 int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd);
 int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd);
+int cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd);
 int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd);
 int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd);
 int maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd);
index a9b6edac2ecd537bbebff2e166a46df25058ebd4..5361249f0f53607654f594bd489abbd878505ddc 100644 (file)
@@ -30,6 +30,17 @@ static const struct snd_soc_dapm_route cs42l43_hs_map[] = {
        { "cs42l43 ADC1_IN1_N", NULL, "Headset Mic" },
 };
 
+static const struct snd_soc_dapm_widget cs42l43_spk_widgets[] = {
+       SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_soc_dapm_route cs42l43_spk_map[] = {
+       { "Speaker", NULL, "cs42l43 AMP1_OUT_P", },
+       { "Speaker", NULL, "cs42l43 AMP1_OUT_N", },
+       { "Speaker", NULL, "cs42l43 AMP2_OUT_P", },
+       { "Speaker", NULL, "cs42l43 AMP2_OUT_N", },
+};
+
 static const struct snd_soc_dapm_widget cs42l43_dmic_widgets[] = {
        SND_SOC_DAPM_MIC("DMIC", NULL),
 };
@@ -108,6 +119,45 @@ int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd)
        return ret;
 }
 
+int cs42l43_spk_rtd_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:cs42l43-spk",
+                                         card->components);
+       if (!card->components)
+               return -ENOMEM;
+
+       ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_spk_widgets,
+                                       ARRAY_SIZE(cs42l43_spk_widgets));
+       if (ret) {
+               dev_err(card->dev, "cs42l43 speaker widgets addition failed: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_spk_map,
+                                     ARRAY_SIZE(cs42l43_spk_map));
+       if (ret)
+               dev_err(card->dev, "cs42l43 speaker map addition failed: %d\n", ret);
+
+       return ret;
+}
+
+int sof_sdw_cs42l43_spk_init(struct snd_soc_card *card,
+                            struct snd_soc_dai_link *dai_links,
+                            struct sof_sdw_codec_info *info,
+                            bool playback)
+{
+       /* Do init on playback link only. */
+       if (!playback)
+               return 0;
+
+       info->amp_num++;
+
+       return 0;
+}
+
 int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_card *card = rtd->card;
index 7e53266d831d8ac205b0f54baab71ade0d3e1cd2..27d1313e66865fb774c82b4fab8f8927471823d0 100644 (file)
@@ -357,6 +357,12 @@ static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
                .group_position = 0,
                .group_id = 0,
        },
+       { /* Speaker Playback Endpoint */
+               .num = 3,
+               .aggregated = 0,
+               .group_position = 0,
+               .group_id = 0,
+       },
 };
 
 static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
index 0cef3d788a5b0186d119495bed7ec55b6d0e7ce7..77226d1eb1cf5355d59028d3d612dbe83a0e2d58 100644 (file)
@@ -433,6 +433,12 @@ static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
                .group_position = 0,
                .group_id = 0,
        },
+       { /* Speaker Playback Endpoint */
+               .num = 3,
+               .aggregated = 0,
+               .group_position = 0,
+               .group_id = 0,
+       },
 };
 
 static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = {