[PATCH 00/17] ASoC: Intel: machine driver updates for 5.9
This patchset adds:
a) fixes for missing .owner = THIS_MODULE initializations for snd_soc_card structures
b) extensions for TigerLake and JasperLake reusing the same machine drivers.
c) Max98373 support for SoundWire machine driver.
d) cleanups (use-after-free, quirks, etc).
Bard Liao (1): ASoC: intel: cml_rt1011_rt5682: use for_each_card_prelinks
Dharageswari R (3): ASoC: Intel: Boards: tgl_max98373: add dai_trigger function ASoC: Intel: Boards: tgl_max98373: Fix the comment for max_98373_components ASoC: Intel: Boards: tgl_max98373: Update TDM configuration in hw_params
Fred Oh (3): ASoC: Intel: Boards: cml_rt1011_rt5682: reduce log level for printing quirk ASoC: Intel: Boards: cml_rt1011_rt5682: use statically define codec config ASoc: Intel: cml_rt1011_rt5682: explicitly access first codec
Naveen Manohar (2): ASoC: Intel: sof_sdw: Add MAX98373 support ASoC: Intel: common: add match table for TGL MAX98373 + RT5682 SoundWire driver
Pierre-Louis Bossart (6): ASoC: SOF: nocodec: add missing .owner field ASoC: Intel: cml_rt1011_rt5682: add missing .owner field ASoC: Intel: sof_sdw: add missing .owner field ASoC: Intel: bxt_rt298: add missing .owner field ASoC: Intel: sof_sdw: add quirk override with kernel parameter ASoC: Intel: boards: byt*.c: remove cast in dev_info quirk log
Yong Zhi (1): ASoC: intel: sof_rt5682: Add support for jsl-max98360a-rt5682
randerwang (1): ASoC: Intel: sdw_max98373: add card_late_probe support
sound/soc/intel/boards/Kconfig | 3 +- sound/soc/intel/boards/Makefile | 2 + sound/soc/intel/boards/bxt_rt298.c | 2 + sound/soc/intel/boards/bytcht_es8316.c | 5 +- sound/soc/intel/boards/bytcr_rt5640.c | 4 +- sound/soc/intel/boards/bytcr_rt5651.c | 4 +- sound/soc/intel/boards/cml_rt1011_rt5682.c | 90 ++++++------------- sound/soc/intel/boards/sof_maxim_common.c | 55 ++++++++++-- sound/soc/intel/boards/sof_maxim_common.h | 3 + sound/soc/intel/boards/sof_rt5682.c | 32 +++++++ sound/soc/intel/boards/sof_sdw.c | 72 ++++++++++++++- sound/soc/intel/boards/sof_sdw_common.h | 15 ++++ sound/soc/intel/boards/sof_sdw_max98373.c | 86 ++++++++++++++++++ .../intel/common/soc-acpi-intel-jsl-match.c | 13 +++ .../intel/common/soc-acpi-intel-tgl-match.c | 25 ++++++ sound/soc/sof/nocodec.c | 1 + 16 files changed, 332 insertions(+), 80 deletions(-) create mode 100644 sound/soc/intel/boards/sof_sdw_max98373.c
base-commit: 6f81e520b2906258a063f09b8d1dd9d0cc6a3172
This field is required for ASoC cards. Not setting it will result in a module->name pointer being NULL and generate problems such as
cat /proc/asound/modules 0 (efault)
Reported-by: Jaroslav Kysela perex@perex.cz Suggested-by: Takashi Iwai tiwai@suse.de Fixes: 8017b8fd37bf ('ASoC: SOF: Add Nocodec machine driver support') Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/sof/nocodec.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c index d03b5be31255..9e922df6a710 100644 --- a/sound/soc/sof/nocodec.c +++ b/sound/soc/sof/nocodec.c @@ -14,6 +14,7 @@
static struct snd_soc_card sof_nocodec_card = { .name = "nocodec", /* the sof- prefix is added by the core */ + .owner = THIS_MODULE };
static int sof_nocodec_bes_setup(struct device *dev,
This field is required for ASoC cards. Not setting it will result in a module->name pointer being NULL and generate problems such as
cat /proc/asound/modules 0 (efault)
Reported-by: Jaroslav Kysela perex@perex.cz Suggested-by: Takashi Iwai tiwai@suse.de Fixes: 17fe95d6df93 ('ASoC: Intel: boards: Add CML m/c using RT1011 and RT5682') Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/intel/boards/cml_rt1011_rt5682.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 189c908c4aa8..6e8934f348ef 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -501,6 +501,7 @@ static struct snd_soc_codec_conf rt1011_conf[] = { /* 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,
This field is required for ASoC cards. Not setting it will result in a module->name pointer being NULL and generate problems such as
cat /proc/asound/modules 0 (efault)
Reported-by: Jaroslav Kysela perex@perex.cz Suggested-by: Takashi Iwai tiwai@suse.de Fixes: 52db12d193d4 ('ASoC: Intel: boards: add sof_sdw machine driver') Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index e1c1a8ba78e6..1bfd9613449e 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -893,6 +893,7 @@ static const char sdw_card_long_name[] = "Intel Soundwire SOF";
static struct snd_soc_card card_sof_sdw = { .name = "soundwire", + .owner = THIS_MODULE, .late_probe = sof_sdw_hdmi_card_late_probe, .codec_conf = codec_conf, .num_configs = ARRAY_SIZE(codec_conf),
This field is required for ASoC cards. Not setting it will result in a module->name pointer being NULL and generate problems such as
cat /proc/asound/modules 0 (efault)
Reported-by: Jaroslav Kysela perex@perex.cz Suggested-by: Takashi Iwai tiwai@suse.de Fixes: 76016322ec56 ('ASoC: Intel: Add Broxton-P machine driver') Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/intel/boards/bxt_rt298.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 7a4decf34191..c84c60df17db 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -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,
During the bring-up of new platforms, or to take care of specific hardware reworks, it's useful to add a kernel parameter to override the default DMI-based quirks.
For example, adding the following line in a .conf file in /etc/modprobe.d/ will change the default quirk and log the changes if dynamic debug is enabled.
options snd_soc_sof_sdw quirk=0x802
[ 735.025785] sof_sdw sof_sdw: Overriding quirk 0x10 => 0x802 [ 735.025787] sof_sdw sof_sdw: quirk realtek,jack-detect-source 2 [ 735.025790] sof_sdw sof_sdw: quirk SOF_RT715_DAI_ID_FIX enabled
Tested on ICL RVP with add-on board instead of default codec.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/intel/boards/sof_sdw.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 1bfd9613449e..70ee79a6b8ab 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; @@ -915,6 +938,13 @@ 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;
We don't need an explicit cast, using the right format is simple enough.
Suggested-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com --- sound/soc/intel/boards/bytcht_es8316.c | 5 ++--- sound/soc/intel/boards/bytcr_rt5640.c | 4 ++-- sound/soc/intel/boards/bytcr_rt5651.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 98e47a5d3a65..71b39e579af9 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -525,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 1851aea983c7..a46777b80485 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1265,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 3e5cd3a87c3d..57bec0554ba8 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -977,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; }
From: Dharageswari R dharageswari.r@intel.com
Speaker amplifier feedback is not modeled as being dependent on any active output. Even when there is no playback happening, parts of the graph, specifically the IV sense->speaker protection->output remains active and this prevents the DSP from entering low-power states.
This patch suggests a machine driver level approach where the speaker pins are enabled/disabled dynamically depending on stream start/stop events. DPAM graph representations show the feedback loop is indeed disabled and low-power states can be reached.
Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Dharageswari R dharageswari.r@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_maxim_common.c | 45 +++++++++++++++++++++++ sound/soc/intel/boards/sof_rt5682.c | 9 +++++ 2 files changed, 54 insertions(+)
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 1a549b32d1c9..b7014c424163 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -9,6 +9,8 @@ #include <uapi/sound/asound.h> #include "sof_maxim_common.h"
+#define MAX_98373_PIN_NAME 16 + static const struct snd_soc_dapm_route max_98373_dapm_routes[] = { /* speaker */ { "Left Spk", NULL, "Left BE_OUT" }, @@ -57,8 +59,51 @@ static int max98373_hw_params(struct snd_pcm_substream *substream, return 0; }
+static 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; + 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_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index f80ed62025f3..20ab2664f7c8 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -318,6 +318,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; @@ -356,6 +357,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); }
From: Dharageswari R dharageswari.r@intel.com
MAX_98373_DEV0_NAME is the Right speaker and MAX_98373_DEV1_NAME is the Left speaker, hence updating the comments for max98373 dailink components accordingly.
Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Dharageswari R dharageswari.r@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_maxim_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index b7014c424163..f8871af2f0d3 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -29,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, },
From: Yong Zhi yong.zhi@intel.com
Add support for max98360a speaker amp on SSP1 and ALC5682 on SSP0 for jsl+ platform.
Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Signed-off-by: Yong Zhi yong.zhi@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_rt5682.c | 23 +++++++++++++++++++ .../intel/common/soc-acpi-intel-jsl-match.c | 13 +++++++++++ 2 files changed, 36 insertions(+)
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 20ab2664f7c8..cc8b0f26f724 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 | @@ -500,6 +501,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", @@ -662,6 +670,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); @@ -833,6 +846,15 @@ 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)), + }, { } };
@@ -855,3 +877,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/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c index 859f8a1bd914..34f5fcad5701 100644 --- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c @@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs rt1015_spk = { .codecs = {"10EC1015"} };
+static struct snd_soc_acpi_codecs mx98360a_spk = { + .num_codecs = 1, + .codecs = {"MX98360A"} +}; + /* * When adding new entry to the snd_soc_acpi_intel_jsl_machines array, * use .quirk_data member to distinguish different machine driver, @@ -47,6 +52,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { .quirk_data = &rt1015_spk, .sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg", }, + { + .id = "10EC5682", + .drv_name = "jsl_rt5682_max98360a", + .sof_fw_filename = "sof-jsl.ri", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &mx98360a_spk, + .sof_tplg_filename = "sof-jsl-rt5682-mx98360a.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_jsl_machines);
From: Fred Oh fred.oh@linux.intel.com
Change dev_info to dev_dbg to reduce noise during multiple deferred probes.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Fred Oh fred.oh@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/cml_rt1011_rt5682.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 6e8934f348ef..4ad6a3acf887 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -536,7 +536,7 @@ 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);
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL | SOF_RT1011_SPEAKER_TR)) {
From: Fred Oh fred.oh@linux.intel.com
When the cml_rt1011_rt5682_dailink[].codecs pointer is overridden by a quirk with a devm allocated structure and the probe is deferred, in the next probe we will see an use-after-free condition (verified with KASAN). This can be avoided by using statically allocated configurations - which simplifies the code quite a bit as well.
KASAN issue fixed. [ 23.301373] cml_rt1011_rt5682 cml_rt1011_rt5682: sof_rt1011_quirk = f [ 23.301875] ================================================================== [ 23.302018] BUG: KASAN: use-after-free in snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682] [ 23.302178] Read of size 8 at addr ffff8881ec6acae0 by task kworker/0:2/105 [ 23.302320] CPU: 0 PID: 105 Comm: kworker/0:2 Not tainted 5.7.0-rc7-test+ #3 [ 23.302322] Hardware name: Google Helios/Helios, BIOS 01/21/2020 [ 23.302329] Workqueue: events deferred_probe_work_func [ 23.302331] Call Trace: [ 23.302339] dump_stack+0x76/0xa0 [ 23.302345] print_address_description.constprop.0.cold+0xd3/0x43e [ 23.302351] ? _raw_spin_lock_irqsave+0x7b/0xd0 [ 23.302355] ? _raw_spin_trylock_bh+0xf0/0xf0 [ 23.302362] ? snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682] [ 23.302365] __kasan_report.cold+0x37/0x86 [ 23.302371] ? snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682] [ 23.302375] kasan_report+0x38/0x50 [ 23.302382] snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682] [ 23.302389] platform_drv_probe+0x66/0xc0
Fixes: 629ba12e9998 ("ASoC: Intel: boards: split woofer and tweeter support") Suggested-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Fred Oh fred.oh@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/cml_rt1011_rt5682.c | 83 ++++++---------------- 1 file changed, 23 insertions(+), 60 deletions(-)
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 4ad6a3acf887..d29b4a8ff70d 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 | @@ -383,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"))); @@ -483,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), }, };
@@ -496,6 +502,15 @@ 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 */ @@ -518,8 +533,6 @@ 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 card_private *ctx; struct snd_soc_acpi_mach *mach; const char *platform_name; @@ -538,65 +551,15 @@ static int snd_cml_rt1011_probe(struct platform_device *pdev)
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; + CML_RT1011_CODEC_DAI)) { + cml_rt1011_rt5682_dailink[i].codecs = ssp1_codec_4spk; + cml_rt1011_rt5682_dailink[i].num_codecs = + ARRAY_SIZE(ssp1_codec_4spk); } } }
From: Bard Liao yung-chuan.liao@linux.intel.com
for_each_card_prelinks() is a common API to walk through each prelink in the card.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/cml_rt1011_rt5682.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index d29b4a8ff70d..3f8b7d9820cd 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -533,6 +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 *dai_link; struct card_private *ctx; struct snd_soc_acpi_mach *mach; const char *platform_name; @@ -554,12 +555,11 @@ static int snd_cml_rt1011_probe(struct platform_device *pdev) /* when 4 speaker is available, update codec config */ if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL | SOF_RT1011_SPEAKER_TR)) { - for (i = 0; i < ARRAY_SIZE(cml_rt1011_rt5682_dailink); i++) { - if (!strcmp(cml_rt1011_rt5682_dailink[i].codecs->dai_name, + for_each_card_prelinks(&snd_soc_card_cml, i, dai_link) { + if (!strcmp(dai_link->codecs->dai_name, CML_RT1011_CODEC_DAI)) { - cml_rt1011_rt5682_dailink[i].codecs = ssp1_codec_4spk; - cml_rt1011_rt5682_dailink[i].num_codecs = - ARRAY_SIZE(ssp1_codec_4spk); + dai_link->codecs = ssp1_codec_4spk; + dai_link->num_codecs = ARRAY_SIZE(ssp1_codec_4spk); } } }
From: Dharageswari R dharageswari.r@intel.com
This patch updates tx_mask, so that (0-3)slots are reserved for Maxim amps to feedback data.
V0->slot0, I0->slot1, V1->slot2, I1->slot3.
also update slot_width in tdm configuration to 24 as the BE configuration is 24 in topology.
Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Dharageswari R dharageswari.r@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/intel/boards/sof_maxim_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index f8871af2f0d3..123e6e5313fb 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -49,11 +49,11 @@ static int max98373_hw_params(struct snd_pcm_substream *substream, 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;
participants (1)
-
Pierre-Louis Bossart