OSDN Git Service

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 99308ed..3f9fa1c 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 7fa4556..50f0191 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 8310fb0..4ab7cd7 100644 (file)
@@ -605,6 +605,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",
                .dais = {
index bc9dfa6..0d7b1be 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 399f28a..623e3be 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;