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, 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; } diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 189c908c4aa8..3f8b7d9820cd 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,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, @@ -517,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; @@ -535,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->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/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 1a549b32d1c9..123e6e5313fb 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -9,6 +9,8 @@ #include #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" }, @@ -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, }, @@ -47,18 +49,61 @@ 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; } +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..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 | @@ -318,6 +319,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 +358,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); } @@ -491,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", @@ -653,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); @@ -824,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)), + }, { } }; @@ -846,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/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index e1c1a8ba78e6..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; @@ -893,6 +916,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), @@ -914,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; 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); 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,