diff options
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r-- | sound/soc/intel/boards/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/intel/boards/Makefile | 3 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcht_es8316.c | 20 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 37 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5651.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_wm5102.c | 2 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_cs42l42.c | 3 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_es8336.c | 16 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_nau8825.c | 36 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_realtek_common.c | 3 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_rt5682.c | 11 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw.c | 10 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_common.h | 20 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt1316.c | 239 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt1318.c | 120 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw_rt_amp.c (renamed from sound/soc/intel/boards/sof_sdw_rt1308.c) | 139 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_ssp_amp.c | 5 |
17 files changed, 222 insertions, 446 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index a472de1909f4..99308ed85277 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -554,10 +554,12 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH select SND_SOC_RT1015P select SND_SOC_MAX98373_I2C select SND_SOC_MAX98357A + select SND_SOC_NAU8315 select SND_SOC_DMIC select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_REALTEK_COMMON help This adds support for ASoC machine driver for SOF platforms with nau8825 codec. diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 7e1a4ff77ac3..d1fd7a2b32db 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,8 +37,7 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o sof_sdw_rt1308.o \ - sof_sdw_rt1316.o sof_sdw_rt1318.o \ + sof_sdw_max98373.o sof_sdw_rt_amp.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 09d1f0f6d686..df157b01df8b 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_cht_es8316_dais[dai_index].codecs->name = codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; } + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* override platform name, if required */ byt_cht_es8316_card.dev = dev; platform_name = mach->mach_params.platform; ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card, platform_name); - if (ret) + if (ret) { + put_device(codec_dev); return ret; + } /* Check for BYTCR or other platform and setup quirks */ dmi_id = dmi_first_match(byt_cht_es8316_quirk_table); @@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) /* get the clock */ priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); - if (IS_ERR(priv->mclk)) + if (IS_ERR(priv->mclk)) { + put_device(codec_dev); return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n"); - - codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); + } if (quirk & BYT_CHT_ES8316_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 6db07b2417ca..79e0039c79a3 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -571,6 +571,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_MCLK_EN), }, { + /* Advantech MICA-071 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), + }, + /* OVCD Th = 1500uA to reliable detect head-phones vs -set */ + .driver_data = (void *)(BYT_RT5640_IN3_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_1500UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_MCLK_EN), + }, + { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"), @@ -796,6 +811,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* HP Stream 8 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 8 Tablet"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_JD_NOT_INV | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), @@ -1611,13 +1636,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; } + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* * swap SSP0 if bytcr is detected * (will be overridden if DMI quirk is detected) @@ -1692,11 +1722,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_quirk = quirk_override; } - codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); - if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) { acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev), byt_rt5640_hp_elitepad_1000g2_gpios); diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 81ac6eeda2e6..8fca9b82d4d0 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); @@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) } codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev); diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 1669eb3bd80f..c0706537f673 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return -ENOENT; } snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); - put_device(&adev->dev); codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index e38bd2831e6a..e9d190cb13b0 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -336,6 +336,9 @@ static int create_spk_amp_dai_links(struct device *dev, links[*id].platforms = platform_component; links[*id].num_platforms = ARRAY_SIZE(platform_component); links[*id].dpcm_playback = 1; + /* firmware-generated echo reference */ + links[*id].dpcm_capture = 1; + links[*id].no_pcm = 1; links[*id].cpus = &cpus[*id]; links[*id].num_cpus = 1; diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 70713e4b07dc..894b6610b9e2 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); dai_links[0].codecs->name = codec_name; /* also fixup codec dai name if relevant */ @@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev) return -ENXIO; } - ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, - mach->mach_params.platform); - if (ret) - return ret; - codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev); + ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, + mach->mach_params.platform); + if (ret) { + put_device(codec_dev); + return ret; + } + if (quirk & SOF_ES8336_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); @@ -783,7 +785,7 @@ static int sof_es8336_remove(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); - cancel_delayed_work(&priv->pcm_pop_work); + cancel_delayed_work_sync(&priv->pcm_pop_work); gpiod_put(priv->gpio_speakers); device_remove_software_node(priv->codec_dev); put_device(priv->codec_dev); diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 27880224359d..6794a0249a9a 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -48,6 +48,7 @@ #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) +#define SOF_NAU8318_SPEAKER_AMP_PRESENT BIT(18) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); @@ -338,6 +339,13 @@ static struct snd_soc_dai_link_component rt1019p_component[] = { } }; +static struct snd_soc_dai_link_component nau8318_components[] = { + { + .name = "NVTN2012:00", + .dai_name = "nau8315-hifi", + } +}; + static struct snd_soc_dai_link_component dummy_component[] = { { .name = "snd-soc-dummy", @@ -479,13 +487,16 @@ 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 = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - /* feedback stream */ - links[id].dpcm_capture = 1; } else if (sof_nau8825_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { sof_rt1015p_dai_link(&links[id]); + } else if (sof_nau8825_quirk & + SOF_NAU8318_SPEAKER_AMP_PRESENT) { + links[id].codecs = nau8318_components; + links[id].num_codecs = ARRAY_SIZE(nau8318_components); + links[id].init = speaker_codec_init; } else { goto devm_err; } @@ -493,6 +504,9 @@ 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].dpcm_playback = 1; + /* feedback stream or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -618,7 +632,7 @@ static const struct platform_device_id board_ids[] = { }, { - .name = "adl_rt1019p_nau8825", + .name = "adl_rt1019p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_RT1019P_SPEAKER_AMP_PRESENT | @@ -626,7 +640,7 @@ static const struct platform_device_id board_ids[] = { SOF_NAU8825_NUM_HDMIDEV(4)), }, { - .name = "adl_max98373_nau8825", + .name = "adl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_MAX98373_SPEAKER_AMP_PRESENT | @@ -637,7 +651,7 @@ static const struct platform_device_id board_ids[] = { }, { /* The limitation of length of char array, shorten the name */ - .name = "adl_mx98360a_nau8825", + .name = "adl_mx98360a_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_MAX98360A_SPEAKER_AMP_PRESENT | @@ -648,7 +662,7 @@ static const struct platform_device_id board_ids[] = { }, { - .name = "adl_rt1015p_nau8825", + .name = "adl_rt1015p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_RT1015P_SPEAKER_AMP_PRESENT | @@ -657,6 +671,16 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "adl_nau8318_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_NAU8318_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index ff2851fc8930..6c12ca92f371 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -267,7 +267,8 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dai *codec_dai; - int i, clk_freq, ret; + int i, clk_freq; + int ret = 0; clk_freq = sof_dai_get_bclk(rtd); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 4a2f91249b10..71a11d747622 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -761,8 +761,6 @@ 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 = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - /* feedback stream */ - links[id].dpcm_capture = 1; } else if (sof_rt5682_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); @@ -789,6 +787,9 @@ 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].dpcm_playback = 1; + /* feedback stream or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -1104,6 +1105,12 @@ static const struct platform_device_id board_ids[] = { SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4)), }, + { + .name = "jsl_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_MCLK_24MHZ | + SOF_RT5682_SSP_CODEC(0)), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index b58c7b35599d..d2ed807abde9 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -550,23 +550,23 @@ static struct sof_sdw_codec_info codec_info_list[] = { .direction = {true, false}, .dai_name = "rt1308-aif", .ops = &sof_sdw_rt1308_i2s_ops, - .init = sof_sdw_rt1308_init, - .exit = sof_sdw_rt1308_exit, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1316, .direction = {true, true}, .dai_name = "rt1316-aif", - .init = sof_sdw_rt1316_init, - .exit = sof_sdw_rt1316_exit, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1318, .direction = {true, true}, .dai_name = "rt1318-aif", - .init = sof_sdw_rt1318_init, + .init = sof_sdw_rt_amp_init, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 54a50f7da4da..350010b0e5f4 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -125,30 +125,18 @@ int sof_sdw_rt700_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); -/* RT1308 support */ +/* RT1308 I2S support */ extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops; -int sof_sdw_rt1308_init(struct snd_soc_card *card, +/* generic amp support */ +int sof_sdw_rt_amp_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); -int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT1316 support */ -int sof_sdw_rt1316_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); -int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - -/* RT1318 support */ -int sof_sdw_rt1318_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); /* RT715 support */ int sof_sdw_rt715_init(struct snd_soc_card *card, diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c deleted file mode 100644 index f6bbea0d3810..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt1316.c +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt1316 - Helpers to handle RT1316 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include <linux/soundwire/sdw.h> -#include <linux/soundwire/sdw_type.h> -#include <linux/dmi.h> -#include "sof_sdw_common.h" -#include "sof_sdw_amp_coeff_tables.h" - -struct rt1316_platform_data { - const unsigned char *bq_params; - const unsigned int bq_params_cnt; -}; - -static const struct rt1316_platform_data dell_0b00_platform_data = { - .bq_params = dell_0b00_bq_params, - .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), -}; - -static const struct dmi_system_id dmi_platform_data[] = { - /* AlderLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, -}; - -static int rt1316_add_device_props(struct device *sdw_dev) -{ - struct property_entry props[3] = {}; - struct fwnode_handle *fwnode; - const struct dmi_system_id *dmi_data; - const struct rt1316_platform_data *pdata; - unsigned char params[RT1316_MAX_BQ_REG]; - int ret; - - dmi_data = dmi_first_match(dmi_platform_data); - if (!dmi_data) - return 0; - - pdata = dmi_data->driver_data; - memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); - - props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); - props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_soc_dapm_widget rt1316_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1316 will be registered dynamically according - * to the number of rt1316 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1316s are used. - */ -static const struct snd_soc_dapm_route rt1316_map[] = { - { "Speaker", NULL, "rt1316-1 SPOL" }, - { "Speaker", NULL, "rt1316-1 SPOR" }, - { "Speaker", NULL, "rt1316-2 SPOL" }, - { "Speaker", NULL, "rt1316-2 SPOR" }, -}; - -static const struct snd_kcontrol_new rt1316_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int first_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:rt1316", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt1316_controls, - ARRAY_SIZE(rt1316_controls)); - if (ret) { - dev_err(card->dev, "rt1316 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt1316_widgets, - ARRAY_SIZE(rt1316_widgets)); - if (ret) { - dev_err(card->dev, "rt1316 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int second_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map + 2, 2); - if (ret) - dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); - - return ret; -} - -static int all_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = first_spk_init(rtd); - if (ret) - return ret; - - return second_spk_init(rtd); -} - -int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (ctx->amp_dev1) { - device_remove_software_node(ctx->amp_dev1); - put_device(ctx->amp_dev1); - } - - if (ctx->amp_dev2) { - device_remove_software_node(ctx->amp_dev2); - put_device(ctx->amp_dev2); - } - - return 0; -} - -int sof_sdw_rt1316_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev1, *sdw_dev2; - int ret; - - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - if (info->amp_num == 1) - dai_links->init = first_spk_init; - - if (info->amp_num == 2) { - sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev1) - return -EPROBE_DEFER; - - ret = rt1316_add_device_props(sdw_dev1); - if (ret < 0) { - put_device(sdw_dev1); - return ret; - } - ctx->amp_dev1 = sdw_dev1; - - sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); - if (!sdw_dev2) - return -EPROBE_DEFER; - - ret = rt1316_add_device_props(sdw_dev2); - if (ret < 0) { - put_device(sdw_dev2); - return ret; - } - ctx->amp_dev2 = sdw_dev2; - - /* - * if two 1316s are in one dai link, the init function - * in this dai link will be first set for the first speaker, - * and it should be reset to initialize all speakers when - * the second speaker is found. - */ - if (dai_links->init) - dai_links->init = all_spk_init; - else - dai_links->init = second_spk_init; - } - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt1318.c b/sound/soc/intel/boards/sof_sdw_rt1318.c deleted file mode 100644 index dbee4bf5c814..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt1318.c +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2022 Intel Corporation - -/* - * sof_sdw_rt1318 - Helpers to handle RT1318 from generic machine driver - */ - -#include <linux/device.h> -#include <linux/errno.h> -#include <sound/control.h> -#include <sound/soc.h> -#include <sound/soc-acpi.h> -#include <sound/soc-dapm.h> -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget rt1318_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1318 will be registered dynamically according - * to the number of rt1318 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1318s are used. - */ -static const struct snd_soc_dapm_route rt1318_map[] = { - { "Speaker", NULL, "rt1318-1 SPOL" }, - { "Speaker", NULL, "rt1318-1 SPOR" }, - { "Speaker", NULL, "rt1318-2 SPOL" }, - { "Speaker", NULL, "rt1318-2 SPOR" }, -}; - -static const struct snd_kcontrol_new rt1318_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int first_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:rt1318", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt1318_controls, - ARRAY_SIZE(rt1318_controls)); - if (ret) { - dev_err(card->dev, "rt1318 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt1318_widgets, - ARRAY_SIZE(rt1318_widgets)); - if (ret) { - dev_err(card->dev, "rt1318 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int second_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map + 2, 2); - if (ret) - dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); - - return ret; -} - -static int all_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = first_spk_init(rtd); - if (ret) - return ret; - - return second_spk_init(rtd); -} - -int sof_sdw_rt1318_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) -{ - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - if (info->amp_num == 1) - dai_links->init = first_spk_init; - - if (info->amp_num == 2) { - /* - * if two 1318s are in one dai link, the init function - * in this dai link will be first set for the first speaker, - * and it should be reset to initialize all speakers when - * the second speaker is found. - */ - if (dai_links->init) - dai_links->init = all_spk_init; - else - dai_links->init = second_spk_init; - } - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt_amp.c index a19b055b9c6f..26bf9e0dd3d2 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1308.c +++ b/sound/soc/intel/boards/sof_sdw_rt_amp.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation +// Copyright (c) 2022 Intel Corporation /* - * sof_sdw_rt1308 - Helpers to handle RT1308 from generic machine driver + * sof_sdw_rt_amp - Helpers to handle RT1308/RT1316/RT1318 from generic machine driver */ #include <linux/device.h> @@ -18,16 +18,26 @@ #include "sof_sdw_amp_coeff_tables.h" #include "../../codecs/rt1308.h" -struct rt1308_platform_data { +#define CODEC_NAME_SIZE 7 + +/* choose a larger value to resolve compatibility issues */ +#define RT_AMP_MAX_BQ_REG RT1316_MAX_BQ_REG + +struct rt_amp_platform_data { const unsigned char *bq_params; const unsigned int bq_params_cnt; }; -static const struct rt1308_platform_data dell_0a5d_platform_data = { +static const struct rt_amp_platform_data dell_0a5d_platform_data = { .bq_params = dell_0a5d_bq_params, .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), }; +static const struct rt_amp_platform_data dell_0b00_platform_data = { + .bq_params = dell_0b00_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), +}; + static const struct dmi_system_id dmi_platform_data[] = { /* CometLake devices */ { @@ -59,15 +69,45 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&dell_0a5d_platform_data, }, + /* AlderLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + {}, }; -static int rt1308_add_device_props(struct device *sdw_dev) +static int rt_amp_add_device_props(struct device *sdw_dev) { struct property_entry props[3] = {}; struct fwnode_handle *fwnode; const struct dmi_system_id *dmi_data; - const struct rt1308_platform_data *pdata; - unsigned char params[RT1308_MAX_BQ_REG]; + const struct rt_amp_platform_data *pdata; + unsigned char params[RT_AMP_MAX_BQ_REG]; int ret; dmi_data = dmi_first_match(dmi_platform_data); @@ -91,15 +131,19 @@ static int rt1308_add_device_props(struct device *sdw_dev) return ret; } -static const struct snd_soc_dapm_widget rt1308_widgets[] = { +static const struct snd_kcontrol_new rt_amp_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static const struct snd_soc_dapm_widget rt_amp_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), }; /* - * dapm routes for rt1308 will be registered dynamically according - * to the number of rt1308 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1308s are used. + * dapm routes for rt1308/rt1316/rt1318 will be registered dynamically + * according to the number of rt1308/rt1316/rt1318 used. The first two + * entries will be registered for one codec case, and the last two entries + * are also registered if two 1308s/1316s/1318s are used. */ static const struct snd_soc_dapm_route rt1308_map[] = { { "Speaker", NULL, "rt1308-1 SPOL" }, @@ -108,36 +152,69 @@ static const struct snd_soc_dapm_route rt1308_map[] = { { "Speaker", NULL, "rt1308-2 SPOR" }, }; -static const struct snd_kcontrol_new rt1308_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), +static const struct snd_soc_dapm_route rt1316_map[] = { + { "Speaker", NULL, "rt1316-1 SPOL" }, + { "Speaker", NULL, "rt1316-1 SPOR" }, + { "Speaker", NULL, "rt1316-2 SPOL" }, + { "Speaker", NULL, "rt1316-2 SPOR" }, }; +static const struct snd_soc_dapm_route rt1318_map[] = { + { "Speaker", NULL, "rt1318-1 SPOL" }, + { "Speaker", NULL, "rt1318-1 SPOR" }, + { "Speaker", NULL, "rt1318-2 SPOL" }, + { "Speaker", NULL, "rt1318-2 SPOR" }, +}; + +static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_pcm_runtime *rtd, + char *codec_name) +{ + const char *dai_name; + + dai_name = rtd->dai_link->codecs->dai_name; + + /* get the codec name */ + snprintf(codec_name, CODEC_NAME_SIZE, "%s", dai_name); + + /* choose the right codec's map */ + if (strcmp(codec_name, "rt1308") == 0) + return rt1308_map; + else if (strcmp(codec_name, "rt1316") == 0) + return rt1316_map; + else + return rt1318_map; +} + static int first_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + const struct snd_soc_dapm_route *rt_amp_map; + char codec_name[CODEC_NAME_SIZE]; int ret; + rt_amp_map = get_codec_name_and_route(rtd, codec_name); + card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:rt1308", - card->components); + "%s spk:%s", + card->components, codec_name); if (!card->components) return -ENOMEM; - ret = snd_soc_add_card_controls(card, rt1308_controls, - ARRAY_SIZE(rt1308_controls)); + ret = snd_soc_add_card_controls(card, rt_amp_controls, + ARRAY_SIZE(rt_amp_controls)); if (ret) { - dev_err(card->dev, "rt1308 controls addition failed: %d\n", ret); + dev_err(card->dev, "%s controls addition failed: %d\n", codec_name, ret); return ret; } - ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_widgets, - ARRAY_SIZE(rt1308_widgets)); + ret = snd_soc_dapm_new_controls(&card->dapm, rt_amp_widgets, + ARRAY_SIZE(rt_amp_widgets)); if (ret) { - dev_err(card->dev, "rt1308 widgets addition failed: %d\n", ret); + dev_err(card->dev, "%s widgets addition failed: %d\n", codec_name, ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map, 2); + ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map, 2); if (ret) dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); @@ -147,9 +224,13 @@ static int first_spk_init(struct snd_soc_pcm_runtime *rtd) static int second_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + const struct snd_soc_dapm_route *rt_amp_map; + char codec_name[CODEC_NAME_SIZE]; int ret; - ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map + 2, 2); + rt_amp_map = get_codec_name_and_route(rtd, codec_name); + + ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map + 2, 2); if (ret) dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); @@ -204,7 +285,7 @@ struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { .hw_params = rt1308_i2s_hw_params, }; -int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); @@ -221,7 +302,7 @@ int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_ return 0; } -int sof_sdw_rt1308_init(struct snd_soc_card *card, +int sof_sdw_rt_amp_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, @@ -244,7 +325,7 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, if (!sdw_dev1) return -EPROBE_DEFER; - ret = rt1308_add_device_props(sdw_dev1); + ret = rt_amp_add_device_props(sdw_dev1); if (ret < 0) { put_device(sdw_dev1); return ret; @@ -255,7 +336,7 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, if (!sdw_dev2) return -EPROBE_DEFER; - ret = rt1308_add_device_props(sdw_dev2); + ret = rt_amp_add_device_props(sdw_dev2); if (ret < 0) { put_device(sdw_dev2); return ret; @@ -263,7 +344,7 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, ctx->amp_dev2 = sdw_dev2; /* - * if two 1308s are in one dai link, the init function + * if two amps are in one dai link, the init function * in this dai link will be first set for the first speaker, * and it should be reset to initialize all speakers when * the second speaker is found. diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 94d25aeb6e7c..7b74f122e340 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -258,13 +258,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, sof_rt1308_dai_link(&links[id]); } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { cs35l41_set_dai_link(&links[id]); - - /* feedback from amplifier */ - links[id].dpcm_capture = 1; } links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; + /* feedback from amplifier or firmware-generated echo reference */ + links[id].dpcm_capture = 1; links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; |