ASoC: Intel: sof_sdw: add rt712 support
authorBard Liao <yung-chuan.liao@linux.intel.com>
Fri, 2 Jun 2023 20:22:07 +0000 (15:22 -0500)
committerMark Brown <broonie@kernel.org>
Mon, 5 Jun 2023 13:00:17 +0000 (14:00 +0100)
Rt712 is a multi function codec which shpports headset, amp, and dmic
functions. Rt712 has two sdw interfaces and codec drivers, one for jack
and amp, the other for dmic. part id 0x712 is for jack and amp, and 0x1712
is for dmic.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20230602202225.249209-11-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/boards/sof_sdw_common.h
sound/soc/intel/boards/sof_sdw_rt712_sdca.c [new file with mode: 0644]
sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c

index 99308ed85277b8abd85685d0dd33995777ac5762..3f9fa1c786756e6e312dacc0f11e77fee8d61e94 100644 (file)
@@ -667,6 +667,8 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
        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
index 7fa45569cfb1c3b0d5d330497eeb7d3c3f30975c..50f0191076e353e68d38e8a2256f2c5d309f2ac5 100644 (file)
@@ -40,8 +40,9 @@ snd-soc-sof-sdw-objs += sof_sdw.o                             \
                        sof_sdw_max98373.o sof_sdw_rt_amp.o     \
                        sof_sdw_rt5682.o sof_sdw_rt700.o        \
                        sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o   \
-                       sof_sdw_rt715.o sof_sdw_rt715_sdca.o    \
-                       sof_sdw_dmic.o sof_sdw_hdmi.o
+                       sof_sdw_rt712_sdca.o sof_sdw_rt715.o    \
+                       sof_sdw_rt715_sdca.o sof_sdw_dmic.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
index 8310fb094d153a29a88c86b07c26920e1ef64996..4ab7cd7f9178bc0a5caef9117700ae3d4807d18f 100644 (file)
@@ -604,6 +604,42 @@ static struct sof_sdw_codec_info codec_info_list[] = {
                },
                .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 = 0x1308,
                .acpi_id = "10EC1308",
index bc9dfa626c32d2a9a4850fa9b68d7ff4b8268e31..0d7b1be3a2d0ad0baae3f4de6056916b2b653bf5 100644 (file)
@@ -130,6 +130,24 @@ int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
                              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_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,
                       const struct snd_soc_acpi_link_adr *link,
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 (file)
index 0000000..84c8025
--- /dev/null
@@ -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;
+}
index 399f28a7911090fea0c96a3d58b0effbe72f3252..623e3bebb8884a991fd773de46dd55b2bba11b44 100644 (file)
@@ -49,11 +49,15 @@ static const struct snd_soc_dapm_widget rt_sdca_jack_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route rt711_sdca_map[] = {
-       /* Headphones */
        { "Headphone", NULL, "rt711 HP" },
        { "rt711 MIC2", NULL, "Headset Mic" },
 };
 
+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"),
@@ -102,6 +106,9 @@ static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd)
        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;