@@ -564,6 +564,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST
depends on SOUNDWIRE
depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
+ select SND_SOC_MAX98373_SDW
select SND_SOC_RT700_SDW
select SND_SOC_RT711_SDW
select SND_SOC_RT1308_SDW
@@ -573,7 +574,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
select SND_SOC_DMIC
help
Add support for Intel SoundWire-based platforms connected to
- RT700, RT711, RT1308 and RT715
+ MAX98373, RT700, RT711, RT1308 and RT715
If unsure select "N".
endif
@@ -34,9 +34,11 @@ snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
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_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
obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
@@ -11,7 +11,7 @@
#define MAX_98373_PIN_NAME 16
-static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
+const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
/* speaker */
{ "Left Spk", NULL, "Left BE_OUT" },
{ "Right Spk", NULL, "Right BE_OUT" },
@@ -59,7 +59,7 @@ static int max98373_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
+int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai;
@@ -18,7 +18,10 @@
extern struct snd_soc_dai_link_component max_98373_components[2];
extern struct snd_soc_ops max_98373_ops;
+extern const struct snd_soc_dapm_route max_98373_dapm_routes[];
int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd);
void sof_max98373_codec_conf(struct snd_soc_card *card);
+int max98373_trigger(struct snd_pcm_substream *substream, int cmd);
+
#endif /* __SOF_MAXIM_COMMON_H */
@@ -120,7 +120,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
},
- .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC),
+ .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_PCH_DMIC |
+ SOF_SDW_FOUR_SPK),
},
{}
@@ -159,6 +160,15 @@ static struct snd_soc_codec_conf codec_conf[] = {
.dlc = COMP_CODEC_CONF("sdw:3:25d:715:0"),
.name_prefix = "rt715",
},
+ /* two MAX98373s on link1 with different unique id */
+ {
+ .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:3"),
+ .name_prefix = "Right",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:7"),
+ .name_prefix = "Left",
+ },
{
.dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"),
.name_prefix = "rt5682",
@@ -180,12 +190,12 @@ static struct snd_soc_dai_link_component platform_component[] = {
};
/* these wrappers are only needed to avoid typecast compilation errors */
-static int sdw_startup(struct snd_pcm_substream *substream)
+int sdw_startup(struct snd_pcm_substream *substream)
{
return sdw_startup_stream(substream);
}
-static void sdw_shutdown(struct snd_pcm_substream *substream)
+void sdw_shutdown(struct snd_pcm_substream *substream)
{
sdw_shutdown_stream(substream);
}
@@ -222,6 +232,12 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.dai_name = "rt715-aif2",
.init = sof_sdw_rt715_init,
},
+ {
+ .id = 0x8373,
+ .direction = {true, true},
+ .dai_name = "max98373-aif1",
+ .init = sof_sdw_mx8373_init,
+ },
{
.id = 0x5682,
.direction = {true, true},
@@ -71,6 +71,9 @@ struct mc_private {
extern unsigned long sof_sdw_quirk;
+int sdw_startup(struct snd_pcm_substream *substream);
+void sdw_shutdown(struct snd_pcm_substream *substream);
+
/* generic HDMI support */
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd);
@@ -105,6 +108,12 @@ int sof_sdw_rt715_init(const struct snd_soc_acpi_link_adr *link,
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,
+ struct sof_sdw_codec_info *info,
+ bool playback);
+
/* RT5682 support */
int sof_sdw_rt5682_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
new file mode 100644
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2020 Intel Corporation
+//
+// sof_sdw_max98373 - Helpers to handle 2x MAX98373
+// codec devices 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"
+#include "sof_maxim_common.h"
+
+static const struct snd_soc_dapm_widget mx8373_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_kcontrol_new mx8373_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static int 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:mx8373",
+ card->components);
+ if (!card->components)
+ return -ENOMEM;
+
+ ret = snd_soc_add_card_controls(card, mx8373_controls,
+ ARRAY_SIZE(mx8373_controls));
+ if (ret) {
+ dev_err(card->dev, "mx8373 ctrls addition failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_new_controls(&card->dapm, mx8373_widgets,
+ ARRAY_SIZE(mx8373_widgets));
+ if (ret) {
+ dev_err(card->dev, "mx8373 widgets addition failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 2);
+ if (ret)
+ dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret);
+
+ return ret;
+}
+
+static const struct snd_soc_ops max_98373_sdw_ops = {
+ .startup = sdw_startup,
+ .trigger = max98373_trigger,
+ .shutdown = sdw_shutdown,
+};
+
+int sof_sdw_mx8373_init(const struct snd_soc_acpi_link_adr *link,
+ struct snd_soc_dai_link *dai_links,
+ struct sof_sdw_codec_info *info,
+ bool playback)
+{
+ info->amp_num++;
+ if (info->amp_num == 2)
+ dai_links->init = spk_init;
+
+ dai_links->ops = &max_98373_sdw_ops;
+
+ return 0;
+}