summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-08-06 14:27:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-06 14:27:31 -0700
commit3f9df56480fc8ce492fc9e988d67bdea884ed15c (patch)
tree6e1c5ed1e28b72435995b8bcd191daa7dfdf770e /sound/soc/intel/boards
parent921d2597abfc05e303f08baa6ead8f9ab8a723e1 (diff)
parentc7fabbc51352f50cc58242a6dc3b9c1a3599849b (diff)
Merge tag 'sound-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This became wide and scattered updates all over the sound tree as diffstat shows: lots of (still ongoing) refactoring works in ASoC, fixes and cleanups caught by static analysis, inclusive term conversions as well as lots of new drivers. Below are highlights: ASoC core: - API cleanups and conversions to the unified mute_stream() call - Simplify I/O helper functions - Use helper macros to retrieve RTD from substreams ASoC drivers: - Lots of fixes and cleanups in Intel ASoC drivers - Lots of new stuff: Freescale MQS and i.MX6sx, Intel KeemBay I2S, Maxim MAX98360A and MAX98373 SoundWire, various Mediatek boards, nVidia Tegra 186 and 210, RealTek RL6231, Samsung Midas and Aries boards, TI J721e EVM ALSA core: - Minor code refacotring for SG-buffer handling HD-audio: - Generalization of mute-LED handling with LED classdev - Intel silent stream support for HDMI - Device-specific fixes: CA0132, Loongson-3 Others: - Usual USB- and HD-audio quirks for various devices - Fixes for echoaudio DMA position handling - Various documents and trivial fixes for sparse warnings - Conversion to adopt inclusive terms" * tag 'sound-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (479 commits) ALSA: pci: delete repeated words in comments ALSA: isa: delete repeated words in comments ALSA: hda/tegra: Add 100us dma stop delay ALSA: hda: Add dma stop delay variable ASoC: hda/tegra: Set buffer alignment to 128 bytes ALSA: seq: oss: Serialize ioctls ALSA: hda/hdmi: Add quirk to force connectivity ALSA: usb-audio: add startech usb audio dock name ALSA: usb-audio: Add support for Lenovo ThinkStation P620 Revert "ALSA: hda: call runtime_allow() for all hda controllers" ALSA: hda/ca0132 - Fix AE-5 microphone selection commands. ALSA: hda/ca0132 - Add new quirk ID for Recon3D. ALSA: hda/ca0132 - Fix ZxR Headphone gain control get value. ALSA: hda/realtek: Add alc269/alc662 pin-tables for Loongson-3 laptops ALSA: docs: fix typo ALSA: doc: use correct config variable name ASoC: core: Two step component registration ASoC: core: Simplify snd_soc_component_initialize declaration ASoC: core: Relocate and expose snd_soc_component_initialize ASoC: sh: Replace 'select' DMADEVICES 'with depends on' ...
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r--sound/soc/intel/boards/Kconfig15
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bdw-rt5650.c14
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c34
-rw-r--r--sound/soc/intel/boards/broadwell.c14
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c117
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c4
-rw-r--r--sound/soc/intel/boards/byt-rt5640.c2
-rw-r--r--sound/soc/intel/boards/bytcht_cx2072x.c12
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c16
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c17
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c18
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c18
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_nau8824.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c19
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c32
-rw-r--r--sound/soc/intel/boards/cml_rt1011_rt5682.c102
-rw-r--r--sound/soc/intel/boards/ehl_rt5660.c2
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c2
-rw-r--r--sound/soc/intel/boards/haswell.c2
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98927.c8
-rw-r--r--sound/soc/intel/boards/kbl_rt5660.c19
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c4
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c45
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_common.h1
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_generic.c17
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c2
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c2
-rw-r--r--sound/soc/intel/boards/skl_rt286.c2
-rw-r--r--sound/soc/intel/boards/sof_da7219_max98373.c2
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.c57
-rw-r--r--sound/soc/intel/boards/sof_maxim_common.h3
-rw-r--r--sound/soc/intel/boards/sof_pcm512x.c4
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c69
-rw-r--r--sound/soc/intel/boards/sof_sdw.c103
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h17
-rw-r--r--sound/soc/intel/boards/sof_sdw_hdmi.c6
-rw-r--r--sound/soc/intel/boards/sof_sdw_max98373.c86
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1308.c2
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt711.c17
-rw-r--r--sound/soc/intel/boards/sof_wm8804.c2
42 files changed, 741 insertions, 197 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 5dc489a79454..d96fc1313434 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -288,6 +288,7 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
tristate
select SND_SOC_DA7219
select SND_SOC_MAX98357A
+ select SND_SOC_MAX98390
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
@@ -298,14 +299,14 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
if SND_SOC_INTEL_APL
config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
- tristate "Broxton with DA7219 and MAX98357A in I2S Mode"
+ tristate "Broxton with DA7219 and MAX98357A/MAX98390 in I2S Mode"
depends on I2C && ACPI && GPIOLIB
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_HDA_CODEC_HDMI
select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
help
This adds support for ASoC machine driver for Broxton-P platforms
- with DA7219 + MAX98357A I2S audio codec.
+ with DA7219 + MAX98357A/MAX98390 I2S audio codec.
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
@@ -389,7 +390,7 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH
depends on MFD_INTEL_LPSS || COMPILE_TEST
select SND_SOC_DA7219
select SND_SOC_MAX98927
- select SND_SOC_MAX98373
+ select SND_SOC_MAX98373_I2C
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
@@ -466,7 +467,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
depends on ((SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC) &&\
(MFD_INTEL_LPSS || COMPILE_TEST)) ||\
(SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST))
- select SND_SOC_MAX98373
+ select SND_SOC_MAX98373_I2C
select SND_SOC_RT1015
select SND_SOC_RT5682_I2C
select SND_SOC_DMIC
@@ -530,7 +531,7 @@ config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
select SND_SOC_DA7219
- select SND_SOC_MAX98373
+ select SND_SOC_MAX98373_I2C
select SND_SOC_DMIC
help
This adds support for ASoC machine driver for SOF platforms
@@ -564,6 +565,8 @@ 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_I2C
+ select SND_SOC_MAX98373_SDW
select SND_SOC_RT700_SDW
select SND_SOC_RT711_SDW
select SND_SOC_RT1308_SDW
@@ -573,7 +576,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
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 15684610f8c6..dc04acb911b6 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -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
diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c
index a97e912adf4b..ce7320916b22 100644
--- a/sound/soc/intel/boards/bdw-rt5650.c
+++ b/sound/soc/intel/boards/bdw-rt5650.c
@@ -106,7 +106,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
static int bdw_rt5650_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -297,9 +297,19 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bdw rt5650" /* card name will be 'sof-bdw rt5650' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bdw-rt5650"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* ASoC machine driver for Broadwell DSP + RT5650 */
static struct snd_soc_card bdw_rt5650_card = {
- .name = "bdw-rt5650",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = bdw_rt5650_dais,
.num_links = ARRAY_SIZE(bdw_rt5650_dais),
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index bed4d5f73d9c..86e427e3822f 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -156,7 +156,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -173,7 +173,7 @@ static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -272,8 +272,8 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
RT5677_CLK_SEL_SYS2);
/* Request rt5677 GPIO for headphone amp control */
- bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
- GPIOD_OUT_LOW);
+ bdw_rt5677->gpio_hp_en = gpiod_get(component->dev, "headphone-enable",
+ GPIOD_OUT_LOW);
if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
dev_err(component->dev, "Can't find HP_AMP_SHDN_L gpio\n");
return PTR_ERR(bdw_rt5677->gpio_hp_en);
@@ -307,6 +307,19 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static void bdw_rt5677_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct bdw_rt5677_priv *bdw_rt5677 =
+ snd_soc_card_get_drvdata(rtd->card);
+
+ /*
+ * The .exit() can be reached without going through the .init()
+ * so explicitly test if the gpiod is valid
+ */
+ if (!IS_ERR_OR_NULL(bdw_rt5677->gpio_hp_en))
+ gpiod_put(bdw_rt5677->gpio_hp_en);
+}
+
/* broadwell digital audio interface glue - connects codec <--> CPU */
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
@@ -373,6 +386,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = bdw_rt5677_init,
+ .exit = bdw_rt5677_exit,
#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
SND_SOC_DAILINK_REG(dummy, be, dummy),
#else
@@ -405,9 +419,19 @@ static int bdw_rt5677_resume_post(struct snd_soc_card *card)
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bdw rt5677" /* card name will be 'sof-bdw rt5677' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bdw-rt5677"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* ASoC machine driver for Broadwell DSP + RT5677 */
static struct snd_soc_card bdw_rt5677_card = {
- .name = "bdw-rt5677",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = bdw_rt5677_dais,
.num_links = ARRAY_SIZE(bdw_rt5677_dais),
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 42f8723beef2..f6399077d291 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -103,7 +103,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
static int broadwell_rt286_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -291,9 +291,19 @@ static int broadwell_resume(struct snd_soc_card *card){
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bdw rt286" /* card name will be 'sof-bdw rt286' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "broadwell-rt286"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* broadwell audio machine driver for WPT + RT286S */
static struct snd_soc_card broadwell_rt286 = {
- .name = "broadwell-rt286",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = broadwell_rt286_dais,
.num_links = ARRAY_SIZE(broadwell_rt286_dais),
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 44016c16f25e..0c0a717823c4 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -25,9 +25,14 @@
#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
#define BXT_MAXIM_CODEC_DAI "HiFi"
+#define MAX98390_DEV0_NAME "i2c-MX98390:00"
+#define MAX98390_DEV1_NAME "i2c-MX98390:01"
#define DUAL_CHANNEL 2
#define QUAD_CHANNEL 4
+#define SPKAMP_MAX98357A 1
+#define SPKAMP_MAX98390 2
+
static struct snd_soc_jack broxton_headset;
static struct snd_soc_jack broxton_hdmi[3];
@@ -40,6 +45,7 @@ struct bxt_hdmi_pcm {
struct bxt_card_private {
struct list_head hdmi_pcm_list;
bool common_hdmi_codec_drv;
+ int spkamp;
};
enum {
@@ -85,13 +91,20 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
static const struct snd_kcontrol_new broxton_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_kcontrol_new max98357a_controls[] = {
SOC_DAPM_PIN_SWITCH("Spk"),
};
+static const struct snd_kcontrol_new max98390_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
static const struct snd_soc_dapm_widget broxton_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_SPK("Spk", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
SND_SOC_DAPM_SPK("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI2", NULL),
@@ -100,14 +113,20 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = {
platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
};
+static const struct snd_soc_dapm_widget max98357a_widgets[] = {
+ SND_SOC_DAPM_SPK("Spk", NULL),
+};
+
+static const struct snd_soc_dapm_widget max98390_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
static const struct snd_soc_dapm_route audio_map[] = {
/* HP jack connectors - unknown if we have jack detection */
{"Headphone Jack", NULL, "HPL"},
{"Headphone Jack", NULL, "HPR"},
- /* speaker */
- {"Spk", NULL, "Speaker"},
-
/* other jacks */
{"MIC", NULL, "Headset Mic"},
@@ -134,6 +153,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
{ "Headset Mic", NULL, "Platform Clock" },
};
+static const struct snd_soc_dapm_route max98357a_routes[] = {
+ /* speaker */
+ {"Spk", NULL, "Speaker"},
+};
+
+static const struct snd_soc_dapm_route max98390_routes[] = {
+ /* Speaker */
+ {"Left Spk", NULL, "Left BE_OUT"},
+ {"Right Spk", NULL, "Right BE_OUT"},
+};
+
static const struct snd_soc_dapm_route broxton_map[] = {
{"HiFi Playback", NULL, "ssp5 Tx"},
{"ssp5 Tx", NULL, "codec0_out"},
@@ -404,6 +434,10 @@ SND_SOC_DAILINK_DEF(ssp5_pin,
SND_SOC_DAILINK_DEF(ssp5_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
BXT_MAXIM_CODEC_DAI)));
+SND_SOC_DAILINK_DEF(max98390_codec,
+ DAILINK_COMP_ARRAY(
+ /* Left */ COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"),
+ /* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1")));
SND_SOC_DAILINK_DEF(ssp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
@@ -601,15 +635,69 @@ static struct snd_soc_dai_link broxton_dais[] = {
},
};
+static struct snd_soc_codec_conf max98390_codec_confs[] = {
+ {
+ .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME),
+ .name_prefix = "Left",
+ },
+ {
+ .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME),
+ .name_prefix = "Right",
+ },
+};
+
#define NAME_SIZE 32
static int bxt_card_late_probe(struct snd_soc_card *card)
{
struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
struct bxt_hdmi_pcm *pcm;
struct snd_soc_component *component = NULL;
- int err, i = 0;
+ const struct snd_kcontrol_new *controls;
+ const struct snd_soc_dapm_widget *widgets;
+ const struct snd_soc_dapm_route *routes;
+ int num_controls, num_widgets, num_routes, err, i = 0;
char jack_name[NAME_SIZE];
+ switch (ctx->spkamp) {
+ case SPKAMP_MAX98357A:
+ controls = max98357a_controls;
+ num_controls = ARRAY_SIZE(max98357a_controls);
+ widgets = max98357a_widgets;
+ num_widgets = ARRAY_SIZE(max98357a_widgets);
+ routes = max98357a_routes;
+ num_routes = ARRAY_SIZE(max98357a_routes);
+ break;
+ case SPKAMP_MAX98390:
+ controls = max98390_controls;
+ num_controls = ARRAY_SIZE(max98390_controls);
+ widgets = max98390_widgets;
+ num_widgets = ARRAY_SIZE(max98390_widgets);
+ routes = max98390_routes;
+ num_routes = ARRAY_SIZE(max98390_routes);
+ break;
+ default:
+ dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp);
+ return -EINVAL;
+ }
+
+ err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets);
+ if (err) {
+ dev_err(card->dev, "Fail to new widgets\n");
+ return err;
+ }
+
+ err = snd_soc_add_card_controls(card, controls, num_controls);
+ if (err) {
+ dev_err(card->dev, "Fail to add controls\n");
+ return err;
+ }
+
+ err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes);
+ if (err) {
+ dev_err(card->dev, "Fail to add routes\n");
+ return err;
+ }
+
if (soc_intel_is_glk())
snd_soc_dapm_add_routes(&card->dapm, gemini_map,
ARRAY_SIZE(gemini_map));
@@ -678,6 +766,11 @@ static int broxton_audio_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+ if (acpi_dev_present("MX98390", NULL, -1))
+ ctx->spkamp = SPKAMP_MAX98390;
+ else
+ ctx->spkamp = SPKAMP_MAX98357A;
+
broxton_audio_card.dev = &pdev->dev;
snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
if (soc_intel_is_glk()) {
@@ -702,7 +795,13 @@ static int broxton_audio_probe(struct platform_device *pdev)
} else if (soc_intel_is_cml()) {
unsigned int i;
- broxton_audio_card.name = "cmlda7219max";
+ if (ctx->spkamp == SPKAMP_MAX98390) {
+ broxton_audio_card.name = "cml_max98390_da7219";
+
+ broxton_audio_card.codec_conf = max98390_codec_confs;
+ broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs);
+ } else
+ broxton_audio_card.name = "cmlda7219max";
for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
/* MAXIM_CODEC is connected to SSP1. */
@@ -710,6 +809,11 @@ static int broxton_audio_probe(struct platform_device *pdev)
BXT_MAXIM_CODEC_DAI)) {
broxton_dais[i].name = "SSP1-Codec";
broxton_dais[i].cpus->dai_name = "SSP1 Pin";
+
+ if (ctx->spkamp == SPKAMP_MAX98390) {
+ broxton_dais[i].codecs = max98390_codec;
+ broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec);
+ }
}
/* DIALOG_CODEC is connected to SSP0 */
else if (!strcmp(broxton_dais[i].codecs->dai_name,
@@ -759,6 +863,7 @@ MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
+MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bxt_da7219_max98357a");
MODULE_ALIAS("platform:glk_da7219_max98357a");
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 7a4decf34191..0f3157dfa838 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -224,7 +224,7 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd,
static int broxton_rt298_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -565,6 +565,7 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
/* broxton audio machine driver for SPT + RT298S */
static struct snd_soc_card broxton_rt298 = {
.name = "broxton-rt298",
+ .owner = THIS_MODULE,
.dai_link = broxton_rt298_dais,
.num_links = ARRAY_SIZE(broxton_rt298_dais),
.controls = broxton_controls,
@@ -580,6 +581,7 @@ static struct snd_soc_card broxton_rt298 = {
static struct snd_soc_card geminilake_rt298 = {
.name = "geminilake-rt298",
+ .owner = THIS_MODULE,
.dai_link = broxton_rt298_dais,
.num_links = ARRAY_SIZE(broxton_rt298_dais),
.controls = broxton_controls,
diff --git a/sound/soc/intel/boards/byt-rt5640.c b/sound/soc/intel/boards/byt-rt5640.c
index ace232f8aed6..8851949f38e2 100644
--- a/sound/soc/intel/boards/byt-rt5640.c
+++ b/sound/soc/intel/boards/byt-rt5640.c
@@ -72,7 +72,7 @@ static const struct snd_kcontrol_new byt_rt5640_controls[] = {
static int byt_rt5640_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c
index fad937610494..9cb42ba40c07 100644
--- a/sound/soc/intel/boards/bytcht_cx2072x.c
+++ b/sound/soc/intel/boards/bytcht_cx2072x.c
@@ -205,9 +205,19 @@ static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht cx2072x" /* card name will be 'sof-bytcht cx2072x' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bytcht-cx2072x"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card byt_cht_cx2072x_card = {
- .name = "bytcht-cx2072x",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = byt_cht_cx2072x_dais,
.num_links = ARRAY_SIZE(byt_cht_cx2072x_dais),
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c
index f3791ff2bad1..e1e46b4bbac5 100644
--- a/sound/soc/intel/boards/bytcht_da7213.c
+++ b/sound/soc/intel/boards/bytcht_da7213.c
@@ -105,7 +105,7 @@ static int aif1_startup(struct snd_pcm_substream *substream)
static int aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -126,7 +126,7 @@ static int aif1_hw_params(struct snd_pcm_substream *substream,
static int aif1_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -205,9 +205,19 @@ static struct snd_soc_dai_link dailink[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht da7213" /* card name will be 'sof-bytcht da7213' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bytcht-da7213"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card bytcht_da7213_card = {
- .name = "bytcht-da7213",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = dailink,
.num_links = ARRAY_SIZE(dailink),
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index ecbc58e8a37f..414ae4bb5224 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -407,8 +407,18 @@ static int byt_cht_es8316_resume(struct snd_soc_card *card)
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht es8316" /* card name will be 'sof-bytcht es8316' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bytcht-es8316"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
static struct snd_soc_card byt_cht_es8316_card = {
- .name = "bytcht-es8316",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = byt_cht_es8316_dais,
.num_links = ARRAY_SIZE(byt_cht_es8316_dais),
@@ -515,9 +525,8 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
BYT_CHT_ES8316_MONO_SPEAKER;
}
if (quirk_override != -1) {
- dev_info(dev, "Overriding quirk 0x%x => 0x%x\n",
- (unsigned int)quirk,
- quirk_override);
+ dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
+ quirk, quirk_override);
quirk = quirk_override;
}
log_quirks(dev);
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 1fdb70b9e478..479992f4e97a 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -380,7 +380,7 @@ static struct snd_soc_jack_pin rt5640_pins[] = {
static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
@@ -1127,8 +1127,18 @@ static int byt_rt5640_resume(struct snd_soc_card *card)
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bytcr-rt5640"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
static struct snd_soc_card byt_rt5640_card = {
- .name = "bytcr-rt5640",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = byt_rt5640_dais,
.num_links = ARRAY_SIZE(byt_rt5640_dais),
@@ -1255,8 +1265,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
if (dmi_id)
byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
if (quirk_override != -1) {
- dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
- (unsigned int)byt_rt5640_quirk, quirk_override);
+ dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
+ byt_rt5640_quirk, quirk_override);
byt_rt5640_quirk = quirk_override;
}
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 520e916e329c..4e2897596cea 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -347,7 +347,7 @@ static struct snd_soc_jack_pin bytcr_jack_pins[] = {
static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
snd_pcm_format_t format = params_format(params);
int rate = params_rate(params);
@@ -827,8 +827,18 @@ static int byt_rt5651_resume(struct snd_soc_card *card)
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht rt5651" /* card name will be 'sof-bytcht rt5651' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bytcr-rt5651"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
static struct snd_soc_card byt_rt5651_card = {
- .name = "bytcr-rt5651",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = byt_rt5651_dais,
.num_links = ARRAY_SIZE(byt_rt5651_dais),
@@ -967,8 +977,8 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
dmi_check_system(byt_rt5651_quirk_table);
if (quirk_override != -1) {
- dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
- (unsigned int)byt_rt5651_quirk, quirk_override);
+ dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
+ byt_rt5651_quirk, quirk_override);
byt_rt5651_quirk = quirk_override;
}
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 767ac2ae03e2..835e9bd6b52d 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -112,7 +112,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = {
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -382,9 +382,19 @@ static struct snd_soc_dai_link cht_dailink[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht max98090" /* card name will be 'sof-bytcht max98090 */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "chtmax98090"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
- .name = "chtmax98090",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c
index 2f7c94d335c1..3e12bff15fed 100644
--- a/sound/soc/intel/boards/cht_bsw_nau8824.c
+++ b/sound/soc/intel/boards/cht_bsw_nau8824.c
@@ -72,7 +72,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = {
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -231,9 +231,19 @@ static struct snd_soc_dai_link cht_dailink[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht nau8824" /* card name will be 'sof-bytcht nau8824 */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "chtnau8824"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
- .name = "chtnau8824",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 22de138ffa33..b53c02481749 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -207,7 +207,7 @@ static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -479,9 +479,21 @@ static struct snd_soc_dai_link cht_dailink[] = {
},
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_RT5645_NAME "bytcht rt5645" /* card name 'sof-bytcht rt5645' */
+#define CARD_RT5650_NAME "bytcht rt5650" /* card name 'sof-bytcht rt5650' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_RT5645_NAME "chtrt5645"
+#define CARD_RT5650_NAME "chtrt5650"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card snd_soc_card_chtrt5645 = {
- .name = "chtrt5645",
+ .name = CARD_RT5645_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
@@ -494,7 +506,8 @@ static struct snd_soc_card snd_soc_card_chtrt5645 = {
};
static struct snd_soc_card snd_soc_card_chtrt5650 = {
- .name = "chtrt5650",
+ .name = CARD_RT5650_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 22e432768edb..8442be93eb1c 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = {
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -253,13 +253,17 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
/*
- * Default mode for SSP configuration is TDM 4 slot. One board/design,
- * the Lenovo Miix 2 10 uses not 1 but 2 codecs connected to SSP2. The
- * second piggy-backed, output-only codec is inside the keyboard-dock
- * (which has extra speakers). Unlike the main rt5672 codec, we cannot
- * configure this codec, it is hard coded to use 2 channel 24 bit I2S.
- * Since we only support 2 channels anyways, there is no need for TDM
- * on any cht-bsw-rt5672 designs. So we simply use I2S 2ch everywhere.
+ * The default mode for the cpu-dai is TDM 4 slot. The default mode
+ * for the codec-dai is I2S. So we need to either set the cpu-dai to
+ * I2S mode to match the codec-dai, or set the codec-dai to TDM 4 slot
+ * (or program both to yet another mode).
+ * One board, the Lenovo Miix 2 10, uses not 1 but 2 codecs connected
+ * to SSP2. The second piggy-backed, output-only codec is inside the
+ * keyboard-dock (which has extra speakers). Unlike the main rt5672
+ * codec, we cannot configure this codec, it is hard coded to use
+ * 2 channel 24 bit I2S. For this to work we must use I2S mode on this
+ * board. Since we only support 2 channels anyways, there is no need
+ * for TDM on any cht-bsw-rt5672 designs. So we use I2S 2ch everywhere.
*/
ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
SND_SOC_DAIFMT_I2S |
@@ -378,9 +382,19 @@ static int cht_resume_post(struct snd_soc_card *card)
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht rt5672" /* card name will be 'sof-bytcht rt5672' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "cht-bsw-rt5672"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
- .name = "cht-bsw-rt5672",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c
index 68eff29daf8f..14813beb33d1 100644
--- a/sound/soc/intel/boards/cml_rt1011_rt5682.c
+++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c
@@ -34,7 +34,6 @@
#define SOF_RT1011_SPEAKER_WR BIT(1)
#define SOF_RT1011_SPEAKER_TL BIT(2)
#define SOF_RT1011_SPEAKER_TR BIT(3)
-#define SPK_CH 4
/* Default: Woofer speakers */
static unsigned long sof_rt1011_quirk = SOF_RT1011_SPEAKER_WL |
@@ -161,6 +160,13 @@ static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
};
+static void cml_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+
+ snd_soc_component_set_jack(component, NULL, NULL);
+}
+
static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -193,7 +199,7 @@ static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd)
static int cml_rt5682_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int clk_id, clk_freq, pll_out, ret;
@@ -226,7 +232,7 @@ static int cml_rt5682_hw_params(struct snd_pcm_substream *substream,
static int cml_rt1011_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
struct snd_soc_card *card = rtd->card;
int srate, i, ret = 0;
@@ -376,10 +382,17 @@ SND_SOC_DAILINK_DEF(ssp0_codec,
SND_SOC_DAILINK_DEF(ssp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
-SND_SOC_DAILINK_DEF(ssp1_codec,
+SND_SOC_DAILINK_DEF(ssp1_codec_2spk,
DAILINK_COMP_ARRAY(
/* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
/* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI)));
+SND_SOC_DAILINK_DEF(ssp1_codec_4spk,
+ DAILINK_COMP_ARRAY(
+ /* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
+ /* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI),
+ /* TL */ COMP_CODEC("i2c-10EC1011:02", CML_RT1011_CODEC_DAI),
+ /* TR */ COMP_CODEC("i2c-10EC1011:03", CML_RT1011_CODEC_DAI)));
+
SND_SOC_DAILINK_DEF(dmic_pin,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
@@ -415,6 +428,7 @@ static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = {
.name = "SSP0-Codec",
.id = 0,
.init = cml_rt5682_codec_init,
+ .exit = cml_rt5682_codec_exit,
.ignore_pmdown_time = 1,
.ops = &cml_rt5682_ops,
.dpcm_playback = 1,
@@ -475,7 +489,7 @@ static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = {
.no_pcm = 1,
.init = cml_rt1011_spk_init,
.ops = &cml_rt1011_ops,
- SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
+ SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec_2spk, platform),
},
};
@@ -488,11 +502,21 @@ static struct snd_soc_codec_conf rt1011_conf[] = {
.dlc = COMP_CODEC_CONF("i2c-10EC1011:01"),
.name_prefix = "WR",
},
+ /* single configuration structure for 2 and 4 channels */
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:02"),
+ .name_prefix = "TL",
+ },
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1011:03"),
+ .name_prefix = "TR",
+ },
};
/* Cometlake audio machine driver for RT1011 and RT5682 */
static struct snd_soc_card snd_soc_card_cml = {
.name = "cml_rt1011_rt5682",
+ .owner = THIS_MODULE,
.dai_link = cml_rt1011_rt5682_dailink,
.num_links = ARRAY_SIZE(cml_rt1011_rt5682_dailink),
.codec_conf = rt1011_conf,
@@ -509,8 +533,7 @@ static struct snd_soc_card snd_soc_card_cml = {
static int snd_cml_rt1011_probe(struct platform_device *pdev)
{
- struct snd_soc_dai_link_component *rt1011_dais_components;
- struct snd_soc_codec_conf *rt1011_dais_confs;
+ struct snd_soc_dai_link *dai_link;
struct card_private *ctx;
struct snd_soc_acpi_mach *mach;
const char *platform_name;
@@ -527,67 +550,16 @@ static int snd_cml_rt1011_probe(struct platform_device *pdev)
dmi_check_system(sof_rt1011_quirk_table);
- dev_info(&pdev->dev, "sof_rt1011_quirk = %lx\n", sof_rt1011_quirk);
+ dev_dbg(&pdev->dev, "sof_rt1011_quirk = %lx\n", sof_rt1011_quirk);
+ /* when 4 speaker is available, update codec config */
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL |
SOF_RT1011_SPEAKER_TR)) {
- rt1011_dais_confs = devm_kzalloc(&pdev->dev,
- sizeof(struct snd_soc_codec_conf) *
- SPK_CH, GFP_KERNEL);
-
- if (!rt1011_dais_confs)
- return -ENOMEM;
-
- rt1011_dais_components = devm_kzalloc(&pdev->dev,
- sizeof(struct snd_soc_dai_link_component) *
- SPK_CH, GFP_KERNEL);
-
- if (!rt1011_dais_components)
- return -ENOMEM;
-
- for (i = 0; i < SPK_CH; i++) {
- rt1011_dais_confs[i].dlc.name = devm_kasprintf(&pdev->dev,
- GFP_KERNEL,
- "i2c-10EC1011:0%d",
- i);
-
- if (!rt1011_dais_confs[i].dlc.name)
- return -ENOMEM;
-
- switch (i) {
- case 0:
- rt1011_dais_confs[i].name_prefix = "WL";
- break;
- case 1:
- rt1011_dais_confs[i].name_prefix = "WR";
- break;
- case 2:
- rt1011_dais_confs[i].name_prefix = "TL";
- break;
- case 3:
- rt1011_dais_confs[i].name_prefix = "TR";
- break;
- default:
- return -EINVAL;
- }
- rt1011_dais_components[i].name = devm_kasprintf(&pdev->dev,
- GFP_KERNEL,
- "i2c-10EC1011:0%d",
- i);
- if (!rt1011_dais_components[i].name)
- return -ENOMEM;
-
- rt1011_dais_components[i].dai_name = CML_RT1011_CODEC_DAI;
- }
-
- snd_soc_card_cml.codec_conf = rt1011_dais_confs;
- snd_soc_card_cml.num_configs = SPK_CH;
-
- for (i = 0; i < ARRAY_SIZE(cml_rt1011_rt5682_dailink); i++) {
- if (!strcmp(cml_rt1011_rt5682_dailink[i].codecs->dai_name,
- CML_RT1011_CODEC_DAI)) {
- cml_rt1011_rt5682_dailink[i].codecs = rt1011_dais_components;
- cml_rt1011_rt5682_dailink[i].num_codecs = SPK_CH;
+ for_each_card_prelinks(&snd_soc_card_cml, i, dai_link) {
+ if (!strcmp(dai_link->codecs[0].dai_name,
+ CML_RT1011_CODEC_DAI)) {
+ dai_link->codecs = ssp1_codec_4spk;
+ dai_link->num_codecs = ARRAY_SIZE(ssp1_codec_4spk);
}
}
}
diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c
index 78160e3b1615..7c0d4e915406 100644
--- a/sound/soc/intel/boards/ehl_rt5660.c
+++ b/sound/soc/intel/boards/ehl_rt5660.c
@@ -109,7 +109,7 @@ static int card_late_probe(struct snd_soc_card *card)
static int rt5660_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
index 954ab01f695b..62cca511522e 100644
--- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
+++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
@@ -187,7 +187,7 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 74af090f2657..744b7b5b8106 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -55,7 +55,7 @@ static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
index e29c31ffd241..cc9a2509ace2 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
@@ -175,7 +175,7 @@ static const struct snd_soc_dapm_route kabylake_ssp1_map[] = {
static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *runtime = substream->private_data;
+ struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
int ret, j;
@@ -220,7 +220,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
static int kabylake_ssp0_trigger(struct snd_pcm_substream *substream, int cmd)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
int j, ret;
@@ -455,7 +455,7 @@ static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
static int kbl_fe_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_rt = substream->private_data;
+ struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
/*
* On this platform for PCM device we support,
@@ -512,7 +512,7 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_rt = substream->private_data;
+ struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
index d2a078454784..3a9f91b58e11 100644
--- a/sound/soc/intel/boards/kbl_rt5660.c
+++ b/sound/soc/intel/boards/kbl_rt5660.c
@@ -165,8 +165,8 @@ static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
dev_warn(component->dev, "Failed to add driver gpios\n");
/* Request rt5660 GPIO for lineout mute control, return if fails */
- ctx->gpio_lo_mute = devm_gpiod_get(component->dev, "lineout-mute",
- GPIOD_OUT_HIGH);
+ ctx->gpio_lo_mute = gpiod_get(component->dev, "lineout-mute",
+ GPIOD_OUT_HIGH);
if (IS_ERR(ctx->gpio_lo_mute)) {
dev_err(component->dev, "Can't find GPIO_MUTE# gpio\n");
return PTR_ERR(ctx->gpio_lo_mute);
@@ -207,6 +207,18 @@ static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static void kabylake_rt5660_codec_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+
+ /*
+ * The .exit() can be reached without going through the .init()
+ * so explicitly test if the gpiod is valid
+ */
+ if (!IS_ERR_OR_NULL(ctx->gpio_lo_mute))
+ gpiod_put(ctx->gpio_lo_mute);
+}
+
static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
@@ -243,7 +255,7 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -421,6 +433,7 @@ static struct snd_soc_dai_link kabylake_rt5660_dais[] = {
.id = 0,
.no_pcm = 1,
.init = kabylake_rt5660_codec_init,
+ .exit = kabylake_rt5660_codec_exit,
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index 09ba55fc36d5..3ea4602dfb3e 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -430,7 +430,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -468,7 +468,7 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
int ret = 0, j;
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index b34cf6cf1139..922cd0176e1f 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -336,22 +336,45 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_interval *chan = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_soc_dpcm *dpcm = container_of(
- params, struct snd_soc_dpcm, hw_params);
- struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
- struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
+ struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL;
+
+ /*
+ * The following loop will be called only for playback stream
+ * In this platform, there is only one playback device on every SSP
+ */
+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) {
+ rtd_dpcm = dpcm;
+ break;
+ }
+
+ /*
+ * This following loop will be called only for capture stream
+ * In this platform, there is only one capture device on every SSP
+ */
+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) {
+ rtd_dpcm = dpcm;
+ break;
+ }
+
+ if (!rtd_dpcm)
+ return -EINVAL;
+
+ /*
+ * The above 2 loops are mutually exclusive based on the stream direction,
+ * thus rtd_dpcm variable will never be overwritten
+ */
/*
* The ADSP will convert the FE rate to 48k, stereo, 24 bit
*/
- if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
- !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
- !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
+ if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") ||
+ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") ||
+ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
chan->min = chan->max = 2;
snd_mask_none(fmt);
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
- } else if (!strcmp(fe_dai_link->name, "Kbl Audio DMIC cap")) {
+ } else if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio DMIC cap")) {
if (params_channels(params) == 2 ||
DMIC_CH(dmic_constraints) == 2)
chan->min = chan->max = 2;
@@ -362,7 +385,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
* The speaker on the SSP0 supports S16_LE and not S24_LE.
* thus changing the mask here
*/
- if (!strcmp(be_dai_link->name, "SSP0-Codec"))
+ if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec"))
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
return 0;
@@ -371,7 +394,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
@@ -395,7 +418,7 @@ static struct snd_soc_ops kabylake_rt5663_ops = {
static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
int ret = 0, j;
diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.h b/sound/soc/intel/boards/skl_hda_dsp_common.h
index 507750ef67f3..4b0b3959182e 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_common.h
+++ b/sound/soc/intel/boards/skl_hda_dsp_common.h
@@ -33,6 +33,7 @@ struct skl_hda_private {
int dai_index;
const char *platform_name;
bool common_hdmi_codec_drv;
+ bool idisp_codec;
};
extern struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS];
diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c
index 79c8947f840b..ca4900036ead 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_generic.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c
@@ -79,6 +79,9 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
link->platforms->name = ctx->platform_name;
link->nonatomic = 1;
+ if (!ctx->idisp_codec)
+ return 0;
+
if (strstr(link->name, "HDMI")) {
ret = skl_hda_hdmi_add_pcm(card, ctx->pcm_count);
@@ -118,19 +121,20 @@ static char hda_soc_components[30];
static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
{
struct snd_soc_card *card = &hda_soc_card;
+ struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_dai_link *dai_link;
- u32 codec_count, codec_mask, idisp_mask;
+ u32 codec_count, codec_mask;
int i, num_links, num_route;
codec_mask = mach_params->codec_mask;
codec_count = hweight_long(codec_mask);
- idisp_mask = codec_mask & IDISP_CODEC_MASK;
+ ctx->idisp_codec = !!(codec_mask & IDISP_CODEC_MASK);
if (!codec_count || codec_count > 2 ||
- (codec_count == 2 && !idisp_mask))
+ (codec_count == 2 && !ctx->idisp_codec))
return -EINVAL;
- if (codec_mask == idisp_mask) {
+ if (codec_mask == IDISP_CODEC_MASK) {
/* topology with iDisp as the only HDA codec */
num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT;
num_route = IDISP_ROUTE_COUNT;
@@ -152,7 +156,7 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
num_route = ARRAY_SIZE(skl_hda_map);
card->dapm_widgets = skl_hda_widgets;
card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
- if (!idisp_mask) {
+ if (!ctx->idisp_codec) {
for (i = 0; i < IDISP_DAI_COUNT; i++) {
skl_hda_be_dai_links[i].codecs = dummy_codec;
skl_hda_be_dai_links[i].num_codecs =
@@ -211,6 +215,8 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
if (!mach)
return -EINVAL;
+ snd_soc_card_set_drvdata(&hda_soc_card, ctx);
+
ret = skl_hda_fill_card_info(&mach->mach_params);
if (ret < 0) {
dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n");
@@ -223,7 +229,6 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
hda_soc_card.dev = &pdev->dev;
- snd_soc_card_set_drvdata(&hda_soc_card, ctx);
if (mach->mach_params.dmic_num > 0) {
snprintf(hda_soc_components, sizeof(hda_soc_components),
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index d7b8154c43a4..55802900069a 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -295,7 +295,7 @@ static const struct snd_soc_ops skylake_nau8825_fe_ops = {
static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 4b317bcf6ea0..0c734f3a9364 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -347,7 +347,7 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 903ae1b28ec9..5a0c64a83146 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -228,7 +228,7 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
static int skylake_rt286_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219_max98373.c
index 703703858595..f3cb0773e70e 100644
--- a/sound/soc/intel/boards/sof_da7219_max98373.c
+++ b/sound/soc/intel/boards/sof_da7219_max98373.c
@@ -179,7 +179,7 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
static int ssp1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *runtime = substream->private_data;
+ struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream);
int ret, j;
for (j = 0; j < runtime->num_codecs; j++) {
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c
index 1a549b32d1c9..1a6961592029 100644
--- a/sound/soc/intel/boards/sof_maxim_common.c
+++ b/sound/soc/intel/boards/sof_maxim_common.c
@@ -9,7 +9,9 @@
#include <uapi/sound/asound.h>
#include "sof_maxim_common.h"
-static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
+#define MAX_98373_PIN_NAME 16
+
+const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
/* speaker */
{ "Left Spk", NULL, "Left BE_OUT" },
{ "Right Spk", NULL, "Right BE_OUT" },
@@ -27,11 +29,11 @@ static struct snd_soc_codec_conf max_98373_codec_conf[] = {
};
struct snd_soc_dai_link_component max_98373_components[] = {
- { /* For Left */
+ { /* For Right */
.name = MAX_98373_DEV0_NAME,
.dai_name = MAX_98373_CODEC_DAI,
},
- { /* For Right */
+ { /* For Left */
.name = MAX_98373_DEV1_NAME,
.dai_name = MAX_98373_CODEC_DAI,
},
@@ -40,25 +42,68 @@ struct snd_soc_dai_link_component max_98373_components[] = {
static int max98373_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
int j;
for_each_rtd_codec_dais(rtd, j, codec_dai) {
if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) {
/* DEV0 tdm slot configuration */
- snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16);
+ snd_soc_dai_set_tdm_slot(codec_dai, 0x03, 3, 8, 24);
}
if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) {
/* DEV1 tdm slot configuration */
- snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16);
+ snd_soc_dai_set_tdm_slot(codec_dai, 0x0C, 3, 8, 24);
}
}
return 0;
}
+int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai;
+ int j;
+ int ret = 0;
+
+ for_each_rtd_codec_dais(rtd, j, codec_dai) {
+ struct snd_soc_component *component = codec_dai->component;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_component_get_dapm(component);
+ char pin_name[MAX_98373_PIN_NAME];
+
+ snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
+ codec_dai->component->name_prefix);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = snd_soc_dapm_enable_pin(dapm, pin_name);
+ if (!ret)
+ snd_soc_dapm_sync(dapm);
+ break;
+ 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);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return ret;
+}
+
struct snd_soc_ops max_98373_ops = {
.hw_params = max98373_hw_params,
+ .trigger = max98373_trigger,
};
int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
diff --git a/sound/soc/intel/boards/sof_maxim_common.h b/sound/soc/intel/boards/sof_maxim_common.h
index 785b34335368..5240b1c9d379 100644
--- a/sound/soc/intel/boards/sof_maxim_common.h
+++ b/sound/soc/intel/boards/sof_maxim_common.h
@@ -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 */
diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c
index 9fa8a4911276..d2b0456236c7 100644
--- a/sound/soc/intel/boards/sof_pcm512x.c
+++ b/sound/soc/intel/boards/sof_pcm512x.c
@@ -96,7 +96,7 @@ static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd)
static int aif1_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component;
snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1,
@@ -107,7 +107,7 @@ static int aif1_startup(struct snd_pcm_substream *substream)
static void aif1_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component;
snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1,
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index 13a48b0c35ae..0129d23694ed 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -43,6 +43,7 @@
((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK)
#define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(13)
#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(14)
+#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(15)
/* Default: MCLK on, MCLK 19.2M, SSP0 */
static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
@@ -206,10 +207,17 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
};
+static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+
+ snd_soc_component_set_jack(component, NULL, NULL);
+}
+
static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int clk_id, clk_freq, pll_out, ret;
@@ -267,7 +275,7 @@ static struct snd_soc_ops sof_rt5682_ops = {
static int sof_rt1015_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct snd_soc_dai *codec_dai;
int i, ret;
@@ -276,8 +284,15 @@ static int sof_rt1015_hw_params(struct snd_pcm_substream *substream,
return 0;
for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ /* Set tdm/i2s1 master bclk ratio */
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
+ if (ret < 0) {
+ dev_err(card->dev, "failed to set bclk ratio\n");
+ return ret;
+ }
+
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
- params_rate(params) * 50,
+ params_rate(params) * 64,
params_rate(params) * 256);
if (ret < 0) {
dev_err(card->dev, "failed to set pll\n");
@@ -311,6 +326,7 @@ static int sof_card_late_probe(struct snd_soc_card *card)
{
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component = NULL;
+ struct snd_soc_dapm_context *dapm = &card->dapm;
char jack_name[NAME_SIZE];
struct sof_hdmi_pcm *pcm;
int err;
@@ -349,6 +365,14 @@ static int sof_card_late_probe(struct snd_soc_card *card)
i++;
}
+ if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
+ /* Disable Left and Right Spk pin after boot */
+ snd_soc_dapm_disable_pin(dapm, "Left Spk");
+ snd_soc_dapm_disable_pin(dapm, "Right Spk");
+ err = snd_soc_dapm_sync(dapm);
+ if (err < 0)
+ return err;
+ }
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
@@ -484,6 +508,13 @@ static struct snd_soc_dai_link_component max98357a_component[] = {
}
};
+static struct snd_soc_dai_link_component max98360a_component[] = {
+ {
+ .name = "MX98360A:00",
+ .dai_name = "HiFi",
+ }
+};
+
static struct snd_soc_dai_link_component rt1015_components[] = {
{
.name = "i2c-10EC1015:00",
@@ -525,6 +556,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].init = sof_rt5682_codec_init;
+ links[id].exit = sof_rt5682_codec_exit;
links[id].ops = &sof_rt5682_ops;
links[id].nonatomic = true;
links[id].dpcm_playback = 1;
@@ -645,6 +677,11 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(max_98373_components);
links[id].init = max98373_spk_codec_init;
links[id].ops = &max_98373_ops;
+ } else if (sof_rt5682_quirk &
+ SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
+ links[id].codecs = max98360a_component;
+ links[id].num_codecs = ARRAY_SIZE(max98360a_component);
+ links[id].init = speaker_codec_init;
} else {
links[id].codecs = max98357a_component;
links[id].num_codecs = ARRAY_SIZE(max98357a_component);
@@ -786,21 +823,6 @@ static int sof_audio_probe(struct platform_device *pdev)
&sof_audio_card_rt5682);
}
-static int sof_rt5682_remove(struct platform_device *pdev)
-{
- struct snd_soc_card *card = platform_get_drvdata(pdev);
- struct snd_soc_component *component = NULL;
-
- for_each_card_components(card, component) {
- if (!strcmp(component->name, rt5682_component[0].name)) {
- snd_soc_component_set_jack(component, NULL, NULL);
- break;
- }
- }
-
- return 0;
-}
-
static const struct platform_device_id board_ids[] = {
{
.name = "sof_rt5682",
@@ -831,12 +853,20 @@ static const struct platform_device_id board_ids[] = {
SOF_RT5682_SSP_AMP(1) |
SOF_RT5682_NUM_HDMIDEV(4)),
},
+ {
+ .name = "jsl_rt5682_max98360a",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_MCLK_24MHZ |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_MAX98360A_SPEAKER_AMP_PRESENT |
+ SOF_RT5682_SSP_AMP(1)),
+ },
{ }
};
static struct platform_driver sof_audio = {
.probe = sof_audio_probe,
- .remove = sof_rt5682_remove,
.driver = {
.name = "sof_rt5682",
.pm = &snd_soc_pm_ops,
@@ -854,3 +884,4 @@ MODULE_ALIAS("platform:sof_rt5682");
MODULE_ALIAS("platform:tgl_max98357a_rt5682");
MODULE_ALIAS("platform:jsl_rt5682_rt1015");
MODULE_ALIAS("platform:tgl_max98373_rt5682");
+MODULE_ALIAS("platform:jsl_rt5682_max98360a");
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index e1c1a8ba78e6..2463d432bf4d 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -15,9 +15,32 @@
#include "sof_sdw_common.h"
unsigned long sof_sdw_quirk = SOF_RT711_JD_SRC_JD1;
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
#define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0)
+static void log_quirks(struct device *dev)
+{
+ if (SOF_RT711_JDSRC(sof_sdw_quirk))
+ dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
+ SOF_RT711_JDSRC(sof_sdw_quirk));
+ if (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
+ dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n");
+ if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
+ dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n");
+ if (sof_sdw_quirk & SOF_SDW_PCH_DMIC)
+ dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n");
+ if (SOF_SSP_GET_PORT(sof_sdw_quirk))
+ dev_dbg(dev, "SSP port %ld\n",
+ SOF_SSP_GET_PORT(sof_sdw_quirk));
+ if (sof_sdw_quirk & SOF_RT715_DAI_ID_FIX)
+ dev_dbg(dev, "quirk SOF_RT715_DAI_ID_FIX enabled\n");
+ if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION)
+ dev_dbg(dev, "quirk SOF_SDW_NO_AGGREGATION enabled\n");
+}
+
static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
{
sof_sdw_quirk = (unsigned long)id->driver_data;
@@ -97,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),
},
{}
@@ -136,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",
@@ -157,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);
}
@@ -184,6 +217,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.direction = {true, true},
.dai_name = "rt711-aif1",
.init = sof_sdw_rt711_init,
+ .exit = sof_sdw_rt711_exit,
},
{
.id = 0x1308,
@@ -200,6 +234,13 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.init = sof_sdw_rt715_init,
},
{
+ .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,
.direction = {true, true},
.dai_name = "rt5682-sdw",
@@ -658,11 +699,14 @@ static inline int get_next_be_id(struct snd_soc_dai_link *links,
return links[be_id - 1].id + 1;
}
+#define IDISP_CODEC_MASK 0x4
+
static int sof_card_dai_links_create(struct device *dev,
struct snd_soc_acpi_mach *mach,
struct snd_soc_card *card)
{
int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num;
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_dai_link_component *idisp_components;
struct snd_soc_dai_link_component *ssp_components;
struct snd_soc_acpi_mach_params *mach_params;
@@ -706,12 +750,15 @@ static int sof_card_dai_links_create(struct device *dev,
return ret;
}
+ if (mach_params->codec_mask & IDISP_CODEC_MASK)
+ ctx->idisp_codec = true;
+
/* enable dmic01 & dmic16k */
dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0;
comp_num += dmic_num;
dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num,
- dmic_num, hdmi_num);
+ dmic_num, ctx->idisp_codec ? hdmi_num : 0);
/* allocate BE dailinks */
num_links = comp_num + sdw_be_num;
@@ -860,13 +907,18 @@ DMIC:
if (!name)
return -ENOMEM;
- idisp_components[i].name = "ehdaudio0D2";
- idisp_components[i].dai_name = devm_kasprintf(dev,
- GFP_KERNEL,
- "intel-hdmi-hifi%d",
- i + 1);
- if (!idisp_components[i].dai_name)
- return -ENOMEM;
+ if (ctx->idisp_codec) {
+ idisp_components[i].name = "ehdaudio0D2";
+ idisp_components[i].dai_name = devm_kasprintf(dev,
+ GFP_KERNEL,
+ "intel-hdmi-hifi%d",
+ i + 1);
+ if (!idisp_components[i].dai_name)
+ return -ENOMEM;
+ } else {
+ idisp_components[i].name = "snd-soc-dummy";
+ idisp_components[i].dai_name = "snd-soc-dummy-dai";
+ }
cpu_name = devm_kasprintf(dev, GFP_KERNEL,
"iDisp%d Pin", i + 1);
@@ -888,12 +940,29 @@ DMIC:
return 0;
}
+static int sof_sdw_card_late_probe(struct snd_soc_card *card)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ if (!codec_info_list[i].late_probe)
+ continue;
+
+ ret = codec_info_list[i].codec_card_late_probe(card);
+ if (ret < 0)
+ return ret;
+ }
+
+ return sof_sdw_hdmi_card_late_probe(card);
+}
+
/* SoC card */
static const char sdw_card_long_name[] = "Intel Soundwire SOF";
static struct snd_soc_card card_sof_sdw = {
.name = "soundwire",
- .late_probe = sof_sdw_hdmi_card_late_probe,
+ .owner = THIS_MODULE,
+ .late_probe = sof_sdw_card_late_probe,
.codec_conf = codec_conf,
.num_configs = ARRAY_SIZE(codec_conf),
};
@@ -914,9 +983,17 @@ static int mc_probe(struct platform_device *pdev)
dmi_check_system(sof_sdw_quirk_table);
+ if (quirk_override != -1) {
+ dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
+ sof_sdw_quirk, quirk_override);
+ sof_sdw_quirk = quirk_override;
+ }
+ log_quirks(&pdev->dev);
+
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
card->dev = &pdev->dev;
+ snd_soc_card_set_drvdata(card, ctx);
mach = pdev->dev.platform_data;
ret = sof_card_dai_links_create(&pdev->dev, mach,
@@ -926,8 +1003,6 @@ static int mc_probe(struct platform_device *pdev)
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
- snd_soc_card_set_drvdata(card, ctx);
-
/*
* the default amp_num is zero for each codec and
* amp_num will only be increased for active amp
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index 69b363b8a686..12e32439ba46 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -11,6 +11,7 @@
#include <linux/bits.h>
#include <linux/types.h>
+#include <sound/soc.h>
#define MAX_NO_PROPS 2
#define MAX_HDMI_NUM 4
@@ -61,16 +62,23 @@ struct sof_sdw_codec_info {
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback);
+
+ bool late_probe;
+ int (*codec_card_late_probe)(struct snd_soc_card *card);
};
struct mc_private {
struct list_head hdmi_pcm_list;
bool common_hdmi_codec_drv;
+ bool idisp_codec;
struct snd_soc_jack sdw_headset;
};
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);
@@ -84,6 +92,7 @@ int sof_sdw_rt711_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_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,
@@ -105,6 +114,14 @@ 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);
+
+int sof_sdw_mx8373_late_probe(struct snd_soc_card *card);
+
/* RT5682 support */
int sof_sdw_rt5682_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_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c
index 0654b38a7e0d..99b04bb2f3a0 100644
--- a/sound/soc/intel/boards/sof_sdw_hdmi.c
+++ b/sound/soc/intel/boards/sof_sdw_hdmi.c
@@ -52,6 +52,12 @@ int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card)
int err, i = 0;
char jack_name[NAME_SIZE];
+ if (!ctx->idisp_codec)
+ return 0;
+
+ if (list_empty(&ctx->hdmi_pcm_list))
+ return -EINVAL;
+
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
head);
component = pcm->codec_dai->component;
diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_max98373.c
new file mode 100644
index 000000000000..6437872a9b3d
--- /dev/null
+++ b/sound/soc/intel/boards/sof_sdw_max98373.c
@@ -0,0 +1,86 @@
+// 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;
+
+ info->late_probe = true;
+
+ dai_links->ops = &max_98373_sdw_ops;
+
+ return 0;
+}
+
+int sof_sdw_mx8373_late_probe(struct snd_soc_card *card)
+{
+ struct snd_soc_dapm_context *dapm = &card->dapm;
+
+ /* Disable Left and Right Spk pin after boot */
+ snd_soc_dapm_disable_pin(dapm, "Left Spk");
+ snd_soc_dapm_disable_pin(dapm, "Right Spk");
+ return snd_soc_dapm_sync(dapm);
+}
diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c
index 177cc781ada6..3655e890acec 100644
--- a/sound/soc/intel/boards/sof_sdw_rt1308.c
+++ b/sound/soc/intel/boards/sof_sdw_rt1308.c
@@ -91,7 +91,7 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd)
static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int clk_id, clk_freq, pll_out;
diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c
index d4d75c8dc6b7..606009fa3901 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711.c
@@ -133,6 +133,21 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
+int sof_sdw_rt711_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_init(const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
@@ -147,7 +162,7 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link,
if (!playback)
return 0;
- ret = rt711_add_codec_device_props("sdw:0:25d:711:0");
+ ret = rt711_add_codec_device_props(dai_links->codecs[0].name);
if (ret < 0)
return ret;
diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c
index c13fd20da559..a46ba13e8eb0 100644
--- a/sound/soc/intel/boards/sof_wm8804.c
+++ b/sound/soc/intel/boards/sof_wm8804.c
@@ -49,7 +49,7 @@ static const struct dmi_system_id sof_wm8804_quirk_table[] = {
static int sof_wm8804_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_component *codec = codec_dai->component;