diff options
Diffstat (limited to 'sound/soc/amd')
-rw-r--r-- | sound/soc/amd/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/amd/acp-pcm-dma.c | 6 | ||||
-rw-r--r-- | sound/soc/amd/acp/acp-rembrandt.c | 13 | ||||
-rw-r--r-- | sound/soc/amd/acp/acp-renoir.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/ps/acp63.h | 2 | ||||
-rw-r--r-- | sound/soc/amd/ps/pci-ps.c | 10 | ||||
-rw-r--r-- | sound/soc/amd/ps/ps-pdm-dma.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/raven/acp3x-pcm-dma.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/renoir/acp3x-pdm-dma.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/vangogh/acp5x-mach.c | 297 | ||||
-rw-r--r-- | sound/soc/amd/vangogh/acp5x-pcm-dma.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/yc/acp6x-mach.c | 21 | ||||
-rw-r--r-- | sound/soc/amd/yc/acp6x-pdm-dma.c | 5 | ||||
-rw-r--r-- | sound/soc/amd/yc/acp6x.h | 3 | ||||
-rw-r--r-- | sound/soc/amd/yc/pci-acp6x.c | 8 |
15 files changed, 203 insertions, 189 deletions
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index c88ebd84bdd5..08e42082f5e9 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -90,6 +90,7 @@ config SND_SOC_AMD_VANGOGH_MACH config SND_SOC_AMD_ACP6x tristate "AMD Audio Coprocessor-v6.x Yellow Carp support" + select SND_AMD_ACP_CONFIG depends on X86 && PCI help This option enables Audio Coprocessor i.e ACP v6.x support on @@ -130,6 +131,7 @@ config SND_SOC_AMD_RPL_ACP6x config SND_SOC_AMD_PS tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support" + select SND_AMD_ACP_CONFIG depends on X86 && PCI && ACPI help This option enables Audio Coprocessor i.e ACP v6.3 support on diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 198358d28ea9..d41df316da58 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -1323,7 +1323,7 @@ static int acp_audio_probe(struct platform_device *pdev) return status; } -static int acp_audio_remove(struct platform_device *pdev) +static void acp_audio_remove(struct platform_device *pdev) { int status; struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev); @@ -1332,8 +1332,6 @@ static int acp_audio_remove(struct platform_device *pdev) if (status) dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status); pm_runtime_disable(&pdev->dev); - - return 0; } static int acp_pcm_resume(struct device *dev) @@ -1428,7 +1426,7 @@ static const struct dev_pm_ops acp_pm_ops = { static struct platform_driver acp_dma_driver = { .probe = acp_audio_probe, - .remove = acp_audio_remove, + .remove_new = acp_audio_remove, .driver = { .name = DRV_NAME, .pm = &acp_pm_ops, diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 2b57c0ca4e99..5c455cc04113 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -366,28 +366,21 @@ static int rembrandt_audio_probe(struct platform_device *pdev) return 0; } -static int rembrandt_audio_remove(struct platform_device *pdev) +static void rembrandt_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_chip_info *chip; - - chip = dev_get_platdata(&pdev->dev); - if (!chip || !chip->base) { - dev_err(&pdev->dev, "ACP chip data is NULL\n"); - return -ENODEV; - } + struct acp_chip_info *chip = dev_get_platdata(dev); rmb_acp_deinit(chip->base); acp6x_disable_interrupts(adata); acp_platform_unregister(dev); - return 0; } static struct platform_driver rembrandt_driver = { .probe = rembrandt_audio_probe, - .remove = rembrandt_audio_remove, + .remove_new = rembrandt_audio_remove, .driver = { .name = "acp_asoc_rembrandt", }, diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 2a89a0d2e601..b3cbc7f19ec5 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -313,7 +313,7 @@ static int renoir_audio_probe(struct platform_device *pdev) return 0; } -static int renoir_audio_remove(struct platform_device *pdev) +static void renoir_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); @@ -329,12 +329,11 @@ static int renoir_audio_remove(struct platform_device *pdev) dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret)); acp_platform_unregister(dev); - return 0; } static struct platform_driver renoir_driver = { .probe = renoir_audio_probe, - .remove = renoir_audio_remove, + .remove_new = renoir_audio_remove, .driver = { .name = "acp_asoc_renoir", }, diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 6bf29b520511..dd36790b25ae 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -111,3 +111,5 @@ struct acp63_dev_data { u16 pdev_count; u16 pdm_dev_index; }; + +int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index e86f23d97584..afddb9a77ba4 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -91,7 +91,6 @@ static int acp63_init(void __iomem *acp_base, struct device *dev) dev_err(dev, "ACP reset failed\n"); return ret; } - acp63_writel(0x03, acp_base + ACP_CLKMUX_SEL); acp63_enable_interrupts(acp_base); return 0; } @@ -106,7 +105,6 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) dev_err(dev, "ACP reset failed\n"); return ret; } - acp63_writel(0, acp_base + ACP_CLKMUX_SEL); acp63_writel(0, acp_base + ACP_CONTROL); return 0; } @@ -249,11 +247,17 @@ static int snd_acp63_probe(struct pci_dev *pci, { struct acp63_dev_data *adata; u32 addr; - u32 irqflags; + u32 irqflags, flag; int val; int ret; irqflags = IRQF_SHARED; + + /* Return if acp config flag is defined */ + flag = snd_amd_acp_find_config(pci); + if (flag) + return -ENODEV; + /* Pink Sardine device check */ switch (pci->revision) { case 0x63: diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index 454dab062e4f..46b91327168f 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -399,10 +399,9 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev) return 0; } -static int acp63_pdm_audio_remove(struct platform_device *pdev) +static void acp63_pdm_audio_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - return 0; } static int __maybe_unused acp63_pdm_resume(struct device *dev) @@ -451,7 +450,7 @@ static const struct dev_pm_ops acp63_pdm_pm_ops = { static struct platform_driver acp63_pdm_dma_driver = { .probe = acp63_pdm_audio_probe, - .remove = acp63_pdm_audio_remove, + .remove_new = acp63_pdm_audio_remove, .driver = { .name = "acp_ps_pdm_dma", .pm = &acp63_pdm_pm_ops, diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index 6aec11cf0a6a..7362dd15ad30 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -421,10 +421,9 @@ static int acp3x_audio_probe(struct platform_device *pdev) return 0; } -static int acp3x_audio_remove(struct platform_device *pdev) +static void acp3x_audio_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - return 0; } static int acp3x_resume(struct device *dev) @@ -509,7 +508,7 @@ static const struct dev_pm_ops acp3x_pm_ops = { static struct platform_driver acp3x_dma_driver = { .probe = acp3x_audio_probe, - .remove = acp3x_audio_remove, + .remove_new = acp3x_audio_remove, .driver = { .name = "acp3x_rv_i2s_dma", .pm = &acp3x_pm_ops, diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index 0d8b693aecc9..4e299f96521f 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -435,10 +435,9 @@ static int acp_pdm_audio_probe(struct platform_device *pdev) return 0; } -static int acp_pdm_audio_remove(struct platform_device *pdev) +static void acp_pdm_audio_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - return 0; } static int acp_pdm_resume(struct device *dev) @@ -489,7 +488,7 @@ static const struct dev_pm_ops acp_pdm_pm_ops = { static struct platform_driver acp_pdm_dma_driver = { .probe = acp_pdm_audio_probe, - .remove = acp_pdm_audio_remove, + .remove_new = acp_pdm_audio_remove, .driver = { .name = "acp_rn_pdm_dma", .pm = &acp_pdm_pm_ops, diff --git a/sound/soc/amd/vangogh/acp5x-mach.c b/sound/soc/amd/vangogh/acp5x-mach.c index eebf2650ad27..e5bcd1e6eb73 100644 --- a/sound/soc/amd/vangogh/acp5x-mach.c +++ b/sound/soc/amd/vangogh/acp5x-mach.c @@ -6,37 +6,40 @@ * Copyright 2021 Advanced Micro Devices, Inc. */ -#include <sound/soc.h> -#include <sound/soc-dapm.h> -#include <linux/module.h> -#include <linux/io.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> - -#include <sound/jack.h> -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/gpio/consumer.h> -#include <linux/i2c.h> -#include <linux/input.h> #include <linux/acpi.h> #include <linux/dmi.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/input-event-codes.h> +#include <linux/module.h> +#include <sound/jack.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> #include "../../codecs/nau8821.h" -#include "../../codecs/cs35l41.h" - #include "acp5x.h" -#define DRV_NAME "acp5x_mach" -#define DUAL_CHANNEL 2 -#define ACP5X_NUVOTON_CODEC_DAI "nau8821-hifi" -#define VG_JUPITER 1 -#define ACP5X_NUVOTON_BCLK 3072000 -#define ACP5X_NAU8821_FREQ_OUT 12288000 +#define DRV_NAME "acp5x_mach" +#define DUAL_CHANNEL 2 +#define VG_JUPITER 1 +#define ACP5X_NAU8821_BCLK 3072000 +#define ACP5X_NAU8821_FREQ_OUT 12288000 +#define ACP5X_NAU8821_COMP_NAME "i2c-NVTN2020:00" +#define ACP5X_NAU8821_DAI_NAME "nau8821-hifi" +#define ACP5X_CS35L41_COMP_LNAME "spi-VLV1776:00" +#define ACP5X_CS35L41_COMP_RNAME "spi-VLV1776:01" +#define ACP5X_CS35L41_DAI_NAME "cs35l41-pcm" static unsigned long acp5x_machine_id; static struct snd_soc_jack vg_headset; +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0"))); +SND_SOC_DAILINK_DEF(acp5x_i2s, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0"))); +SND_SOC_DAILINK_DEF(acp5x_bt, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1"))); +SND_SOC_DAILINK_DEF(nau8821, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_NAU8821_COMP_NAME, + ACP5X_NAU8821_DAI_NAME))); + static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = { { .pin = "Headphone", @@ -48,18 +51,54 @@ static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = { }, }; +static const struct snd_kcontrol_new acp5x_8821_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), +}; + +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *dai; + int ret = 0; + + dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME); + if (!dai) { + dev_err(card->dev, "Codec dai not found\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "set sysclk err = %d\n", ret); + return -EIO; + } + } else { + ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(dai->dev, "can't set BLK clock %d\n", ret); + ret = snd_soc_dai_set_pll(dai, 0, 0, ACP5X_NAU8821_BCLK, ACP5X_NAU8821_FREQ_OUT); + if (ret < 0) + dev_err(dai->dev, "can't set FLL: %d\n", ret); + } + + return ret; +} + static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; int ret; - struct snd_soc_card *card = rtd->card; - struct snd_soc_component *component = - asoc_rtd_to_codec(rtd, 0)->component; /* * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new_pins(card, "Headset Jack", + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0, &vg_headset, acp5x_nau8821_jack_pins, ARRAY_SIZE(acp5x_nau8821_jack_pins)); @@ -70,12 +109,8 @@ static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_MEDIA); nau8821_enable_jack_detect(component, &vg_headset); - return ret; -} -static int acp5x_cs35l41_init(struct snd_soc_pcm_runtime *rtd) -{ - return 0; + return ret; } static const unsigned int rates[] = { @@ -109,8 +144,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_card *card = rtd->card; - struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card); + struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card); machine->play_i2s_instance = I2S_SP_INSTANCE; machine->cap_i2s_instance = I2S_SP_INSTANCE; @@ -123,6 +157,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, &constraints_sample_bits); + return 0; } @@ -131,29 +166,36 @@ static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = - snd_soc_card_get_codec_dai(card, - ACP5X_NUVOTON_CODEC_DAI); - int ret; + struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME); + int ret, bclk; - ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0, - SND_SOC_CLOCK_IN); + ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(card->dev, "can't set FS clock %d\n", ret); - ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params), - params_rate(params) * 256); + + bclk = snd_soc_params_to_bclk(params); + if (bclk < 0) { + dev_err(dai->dev, "Fail to get BCLK rate: %d\n", bclk); + return bclk; + } + + ret = snd_soc_dai_set_pll(dai, 0, 0, bclk, params_rate(params) * 256); if (ret < 0) dev_err(card->dev, "can't set FLL: %d\n", ret); return ret; } +static const struct snd_soc_ops acp5x_8821_ops = { + .startup = acp5x_8821_startup, + .hw_params = acp5x_nau8821_hw_params, +}; + static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_card *card = rtd->card; - struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card); + struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card); + struct snd_pcm_runtime *runtime = substream->runtime; machine->play_i2s_instance = I2S_HS_INSTANCE; @@ -162,6 +204,7 @@ static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream) &constraints_channels); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); + return 0; } @@ -169,80 +212,66 @@ static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai; + unsigned int bclk, rate = params_rate(params); + struct snd_soc_component *comp; int ret, i; - unsigned int num_codecs = rtd->dai_link->num_codecs; - unsigned int bclk_val; - - ret = 0; - for (i = 0; i < num_codecs; i++) { - codec_dai = asoc_rtd_to_codec(rtd, i); - if (strcmp(codec_dai->name, "cs35l41-pcm") == 0) { - switch (params_rate(params)) { - case 48000: - bclk_val = 1536000; - break; - default: - dev_err(card->dev, "Invalid Samplerate:0x%x\n", - params_rate(params)); + + switch (rate) { + case 48000: + bclk = 1536000; + break; + default: + bclk = 0; + break; + } + + for_each_rtd_components(rtd, i, comp) { + if (!(strcmp(comp->name, ACP5X_CS35L41_COMP_LNAME)) || + !(strcmp(comp->name, ACP5X_CS35L41_COMP_RNAME))) { + if (!bclk) { + dev_err(comp->dev, "Invalid sample rate: 0x%x\n", rate); return -EINVAL; } - ret = snd_soc_component_set_sysclk(codec_dai->component, - 0, 0, bclk_val, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "failed to set sysclk for CS35l41 dai\n"); + + ret = snd_soc_component_set_sysclk(comp, 0, 0, bclk, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(comp->dev, "failed to set SYSCLK: %d\n", ret); return ret; } } } - return ret; -} + return 0; -static const struct snd_soc_ops acp5x_8821_ops = { - .startup = acp5x_8821_startup, - .hw_params = acp5x_nau8821_hw_params, -}; +} static const struct snd_soc_ops acp5x_cs35l41_play_ops = { .startup = acp5x_cs35l41_startup, .hw_params = acp5x_cs35l41_hw_params, }; -static struct snd_soc_codec_conf cs35l41_conf[] = { +static struct snd_soc_codec_conf acp5x_cs35l41_conf[] = { { - .dlc = COMP_CODEC_CONF("spi-VLV1776:00"), + .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_LNAME), .name_prefix = "Left", }, { - .dlc = COMP_CODEC_CONF("spi-VLV1776:01"), + .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_RNAME), .name_prefix = "Right", }, }; -SND_SOC_DAILINK_DEF(acp5x_i2s, - DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0"))); +SND_SOC_DAILINK_DEF(cs35l41, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_CS35L41_COMP_LNAME, + ACP5X_CS35L41_DAI_NAME), + COMP_CODEC(ACP5X_CS35L41_COMP_RNAME, + ACP5X_CS35L41_DAI_NAME))); -SND_SOC_DAILINK_DEF(acp5x_bt, - DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1"))); - -SND_SOC_DAILINK_DEF(nau8821, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00", - "nau8821-hifi"))); - -SND_SOC_DAILINK_DEF(cs35l41, - DAILINK_COMP_ARRAY(COMP_CODEC("spi-VLV1776:00", "cs35l41-pcm"), - COMP_CODEC("spi-VLV1776:01", "cs35l41-pcm"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0"))); - -static struct snd_soc_dai_link acp5x_dai[] = { +static struct snd_soc_dai_link acp5x_8821_35l41_dai[] = { { .name = "acp5x-8821-play", .stream_name = "Playback/Capture", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .dpcm_playback = 1, .dpcm_capture = 1, @@ -253,65 +282,28 @@ static struct snd_soc_dai_link acp5x_dai[] = { { .name = "acp5x-CS35L41-Stereo", .stream_name = "CS35L41 Stereo Playback", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .dpcm_playback = 1, .playback_only = 1, .ops = &acp5x_cs35l41_play_ops, - .init = acp5x_cs35l41_init, SND_SOC_DAILINK_REG(acp5x_bt, cs35l41, platform), }, }; -static int platform_clock_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_card *card = dapm->card; - struct snd_soc_dai *codec_dai; - int ret = 0; - codec_dai = snd_soc_card_get_codec_dai(card, ACP5X_NUVOTON_CODEC_DAI); - if (!codec_dai) { - dev_err(card->dev, "Codec dai not found\n"); - return -EIO; - } - if (SND_SOC_DAPM_EVENT_OFF(event)) { - ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "set sysclk err = %d\n", ret); - return -EIO; - } - } else { - ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - dev_err(codec_dai->dev, "can't set BLK clock %d\n", ret); - ret = snd_soc_dai_set_pll(codec_dai, 0, 0, ACP5X_NUVOTON_BCLK, - ACP5X_NAU8821_FREQ_OUT); - if (ret < 0) - dev_err(codec_dai->dev, "can't set FLL: %d\n", ret); - } - return ret; -} - -static const struct snd_kcontrol_new acp5x_8821_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Int Mic"), -}; - -static const struct snd_soc_dapm_widget acp5x_8821_widgets[] = { +static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + platform_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; -static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = { +static const struct snd_soc_dapm_route acp5x_8821_35l41_audio_route[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone", NULL, "HPOL" }, { "Headphone", NULL, "HPOR" }, @@ -324,17 +316,17 @@ static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = { { "Int Mic", NULL, "Platform Clock" }, }; -static struct snd_soc_card acp5x_card = { +static struct snd_soc_card acp5x_8821_35l41_card = { .name = "acp5x", .owner = THIS_MODULE, - .dai_link = acp5x_dai, - .num_links = ARRAY_SIZE(acp5x_dai), - .dapm_widgets = acp5x_8821_widgets, - .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_widgets), - .dapm_routes = acp5x_8821_audio_route, - .num_dapm_routes = ARRAY_SIZE(acp5x_8821_audio_route), - .codec_conf = cs35l41_conf, - .num_configs = ARRAY_SIZE(cs35l41_conf), + .dai_link = acp5x_8821_35l41_dai, + .num_links = ARRAY_SIZE(acp5x_8821_35l41_dai), + .dapm_widgets = acp5x_8821_35l41_widgets, + .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_35l41_widgets), + .dapm_routes = acp5x_8821_35l41_audio_route, + .num_dapm_routes = ARRAY_SIZE(acp5x_8821_35l41_audio_route), + .codec_conf = acp5x_cs35l41_conf, + .num_configs = ARRAY_SIZE(acp5x_cs35l41_conf), .controls = acp5x_8821_controls, .num_controls = ARRAY_SIZE(acp5x_8821_controls), }; @@ -342,6 +334,7 @@ static struct snd_soc_card acp5x_card = { static int acp5x_vg_quirk_cb(const struct dmi_system_id *id) { acp5x_machine_id = VG_JUPITER; + return 1; } @@ -358,33 +351,31 @@ static const struct dmi_system_id acp5x_vg_quirk_table[] = { static int acp5x_probe(struct platform_device *pdev) { - int ret; struct acp5x_platform_info *machine; + struct device *dev = &pdev->dev; struct snd_soc_card *card; + int ret; - machine = devm_kzalloc(&pdev->dev, sizeof(struct acp5x_platform_info), - GFP_KERNEL); + machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL); if (!machine) return -ENOMEM; dmi_check_system(acp5x_vg_quirk_table); switch (acp5x_machine_id) { case VG_JUPITER: - card = &acp5x_card; - acp5x_card.dev = &pdev->dev; + card = &acp5x_8821_35l41_card; break; default: return -ENODEV; } + card->dev = dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) { - return dev_err_probe(&pdev->dev, ret, - "snd_soc_register_card(%s) failed\n", - acp5x_card.name); - } + ret = devm_snd_soc_register_card(dev, card); + if (ret) + return dev_err_probe(dev, ret, "Register card (%s) failed\n", card->name); + return 0; } diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c index d36bb718370f..29901ee4bfe3 100644 --- a/sound/soc/amd/vangogh/acp5x-pcm-dma.c +++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c @@ -415,10 +415,9 @@ static int acp5x_audio_probe(struct platform_device *pdev) return 0; } -static int acp5x_audio_remove(struct platform_device *pdev) +static void acp5x_audio_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - return 0; } static int __maybe_unused acp5x_pcm_resume(struct device *dev) @@ -500,7 +499,7 @@ static const struct dev_pm_ops acp5x_pm_ops = { static struct platform_driver acp5x_dma_driver = { .probe = acp5x_audio_probe, - .remove = acp5x_audio_remove, + .remove_new = acp5x_audio_remove, .driver = { .name = "acp5x_i2s_dma", .pm = &acp5x_pm_ops, diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 0acdf0156f07..b9958e555367 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -48,6 +48,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { { .driver_data = &acp6x_card, .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D0"), } @@ -182,6 +189,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "21HY"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21J5"), } }, @@ -266,6 +280,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8A42"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), DMI_MATCH(DMI_BOARD_NAME, "8A43"), } }, diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c index 294dd7fb43c9..d818eba48546 100644 --- a/sound/soc/amd/yc/acp6x-pdm-dma.c +++ b/sound/soc/amd/yc/acp6x-pdm-dma.c @@ -388,10 +388,9 @@ static int acp6x_pdm_audio_probe(struct platform_device *pdev) return 0; } -static int acp6x_pdm_audio_remove(struct platform_device *pdev) +static void acp6x_pdm_audio_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - return 0; } static int __maybe_unused acp6x_pdm_resume(struct device *dev) @@ -440,7 +439,7 @@ static const struct dev_pm_ops acp6x_pdm_pm_ops = { static struct platform_driver acp6x_pdm_dma_driver = { .probe = acp6x_pdm_audio_probe, - .remove = acp6x_pdm_audio_remove, + .remove_new = acp6x_pdm_audio_remove, .driver = { .name = "acp_yc_pdm_dma", .pm = &acp6x_pdm_pm_ops, diff --git a/sound/soc/amd/yc/acp6x.h b/sound/soc/amd/yc/acp6x.h index 036207568c04..2de7d1edf00b 100644 --- a/sound/soc/amd/yc/acp6x.h +++ b/sound/soc/amd/yc/acp6x.h @@ -105,3 +105,6 @@ static inline void acp6x_writel(u32 val, void __iomem *base_addr) { writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS); } + +int snd_amd_acp_find_config(struct pci_dev *pci); + diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c index 77c5fa1f7af1..7af6a349b1d4 100644 --- a/sound/soc/amd/yc/pci-acp6x.c +++ b/sound/soc/amd/yc/pci-acp6x.c @@ -149,10 +149,16 @@ static int snd_acp6x_probe(struct pci_dev *pci, int index = 0; int val = 0x00; u32 addr; - unsigned int irqflags; + unsigned int irqflags, flag; int ret; irqflags = IRQF_SHARED; + + /* Return if acp config flag is defined */ + flag = snd_amd_acp_find_config(pci); + if (flag) + return -ENODEV; + /* Yellow Carp device check */ switch (pci->revision) { case 0x60: |