diff --git a/MAINTAINERS b/MAINTAINERS index 637f6ce22626..ef17863af710 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13922,6 +13922,7 @@ S: Supported F: Documentation/devicetree/bindings/sound/ F: Documentation/sound/soc/ F: sound/soc/ +F: include/dt-bindings/sound/ F: include/sound/soc* SOUNDWIRE SUBSYSTEM diff --git a/include/sound/soc.h b/include/sound/soc.h index 66aafadcf5ef..8ec1de856ee7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1192,7 +1192,7 @@ struct snd_soc_pcm_runtime { ((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \ (i)++) #define for_each_rtd_codec_dai_rollback(rtd, i, dai) \ - for (; ((i--) >= 0) && ((dai) = rtd->codec_dais[i]);) + for (; ((--i) >= 0) && ((dai) = rtd->codec_dais[i]);) /* mixer control */ diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index fac397326515..db709eeb019c 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2230,11 +2230,6 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) */ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - err = snd_hdac_display_power(bus, false); - if (err < 0) { - dev_err(dev, "Cannot turn on display power on i915\n"); - return err; - } hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); if (!hlink) { @@ -2244,7 +2239,11 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) snd_hdac_ext_bus_link_put(bus, hlink); - return 0; + err = snd_hdac_display_power(bus, false); + if (err < 0) + dev_err(dev, "Cannot turn off display power on i915\n"); + + return err; } static int hdac_hdmi_runtime_resume(struct device *dev) diff --git a/sound/soc/codecs/pcm186x.h b/sound/soc/codecs/pcm186x.h index 2c6ba55bf394..bb3f0c42a1cd 100644 --- a/sound/soc/codecs/pcm186x.h +++ b/sound/soc/codecs/pcm186x.h @@ -139,7 +139,7 @@ enum pcm186x_type { #define PCM186X_MAX_REGISTER PCM186X_CURR_TRIM_CTRL /* PCM186X_PAGE */ -#define PCM186X_RESET 0xff +#define PCM186X_RESET 0xfe /* PCM186X_ADCX_INPUT_SEL_X */ #define PCM186X_ADC_INPUT_SEL_POL BIT(7) diff --git a/sound/soc/codecs/pcm3060.c b/sound/soc/codecs/pcm3060.c index 5f479aa61097..1dd851a7b43b 100644 --- a/sound/soc/codecs/pcm3060.c +++ b/sound/soc/codecs/pcm3060.c @@ -198,20 +198,16 @@ static const struct snd_kcontrol_new pcm3060_dapm_controls[] = { }; static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = { - SND_SOC_DAPM_OUTPUT("OUTL+"), - SND_SOC_DAPM_OUTPUT("OUTR+"), - SND_SOC_DAPM_OUTPUT("OUTL-"), - SND_SOC_DAPM_OUTPUT("OUTR-"), + SND_SOC_DAPM_OUTPUT("OUTL"), + SND_SOC_DAPM_OUTPUT("OUTR"), SND_SOC_DAPM_INPUT("INL"), SND_SOC_DAPM_INPUT("INR"), }; static const struct snd_soc_dapm_route pcm3060_dapm_map[] = { - { "OUTL+", NULL, "Playback" }, - { "OUTR+", NULL, "Playback" }, - { "OUTL-", NULL, "Playback" }, - { "OUTR-", NULL, "Playback" }, + { "OUTL", NULL, "Playback" }, + { "OUTR", NULL, "Playback" }, { "Capture", NULL, "INL" }, { "Capture", NULL, "INR" }, diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 115f21658222..08d3fe192e65 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -758,15 +758,22 @@ err_clk: } EXPORT_SYMBOL_GPL(pcm3168a_probe); -void pcm3168a_remove(struct device *dev) +static void pcm3168a_disable(struct device *dev) { struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev); - pm_runtime_disable(dev); regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), - pcm3168a->supplies); + pcm3168a->supplies); clk_disable_unprepare(pcm3168a->scki); } + +void pcm3168a_remove(struct device *dev) +{ + pm_runtime_disable(dev); +#ifndef CONFIG_PM + pcm3168a_disable(dev); +#endif +} EXPORT_SYMBOL_GPL(pcm3168a_remove); #ifdef CONFIG_PM @@ -821,10 +828,7 @@ static int pcm3168a_rt_suspend(struct device *dev) regcache_cache_only(pcm3168a->regmap, true); - regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), - pcm3168a->supplies); - - clk_disable_unprepare(pcm3168a->scki); + pcm3168a_disable(dev); return 0; } diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 27f7445b2432..e74b2e8cd423 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1246,6 +1246,7 @@ MODULE_DEVICE_TABLE(of, rt5660_of_match); static const struct acpi_device_id rt5660_acpi_match[] = { { "10EC5660", 0 }, + { "10EC3277", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 0ed44e5c58f7..1dd291cebe67 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -765,38 +765,41 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) { - u16 scratch[4]; + unsigned int scratch[4]; + unsigned int addr = dsp->base + ADSP2_SCRATCH0; + unsigned int i; int ret; - ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0, - scratch, sizeof(scratch)); - if (ret) { - adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); - return; + for (i = 0; i < ARRAY_SIZE(scratch); ++i) { + ret = regmap_read(dsp->regmap, addr + i, &scratch[i]); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); + return; + } } adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", - be16_to_cpu(scratch[0]), - be16_to_cpu(scratch[1]), - be16_to_cpu(scratch[2]), - be16_to_cpu(scratch[3])); + scratch[0], scratch[1], scratch[2], scratch[3]); } static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) { - u32 scratch[2]; + unsigned int scratch[2]; int ret; - ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1, - scratch, sizeof(scratch)); - + ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1, + &scratch[0]); if (ret) { - adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); + adsp_err(dsp, "Failed to read SCRATCH0_1: %d\n", ret); return; } - scratch[0] = be32_to_cpu(scratch[0]); - scratch[1] = be32_to_cpu(scratch[1]); + ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH2_3, + &scratch[1]); + if (ret) { + adsp_err(dsp, "Failed to read SCRATCH2_3: %d\n", ret); + return; + } adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", scratch[0] & 0xFFFF, diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 0caa1f4eb94d..18e717703685 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -101,22 +101,42 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI codec, then enable this option by saying Y or m. This is a recommended option -config SND_SOC_INTEL_SKYLAKE_SSP_CLK - tristate - config SND_SOC_INTEL_SKYLAKE tristate "SKL/BXT/KBL/GLK/CNL... Platforms" depends on PCI && ACPI + select SND_SOC_INTEL_SKYLAKE_COMMON + help + If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ + GeminiLake or CannonLake platform with the DSP enabled in the BIOS + then enable this option by saying Y or m. + +if SND_SOC_INTEL_SKYLAKE + +config SND_SOC_INTEL_SKYLAKE_SSP_CLK + tristate + +config SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + bool "HDAudio codec support" + help + If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ + GeminiLake or CannonLake platform with an HDaudio codec + then enable this option by saying Y + +config SND_SOC_INTEL_SKYLAKE_COMMON + tristate select SND_HDA_EXT_CORE select SND_HDA_DSP_LOADER select SND_SOC_TOPOLOGY select SND_SOC_INTEL_SST + select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC select SND_SOC_ACPI_INTEL_MATCH help If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ GeminiLake or CannonLake platform with the DSP enabled in the BIOS then enable this option by saying Y or m. +endif ## SND_SOC_INTEL_SKYLAKE + config SND_SOC_ACPI_INTEL_MATCH tristate select SND_SOC_ACPI if ACPI diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 73ca1350aa31..b177db2a0dbb 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -293,16 +293,6 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH Say Y if you have such a device. If unsure select "N". -config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH - tristate "SKL/KBL/BXT/APL with HDA Codecs" - select SND_SOC_HDAC_HDMI - select SND_SOC_HDAC_HDA - help - This adds support for ASoC machine driver for Intel platforms - SKL/KBL/BXT/APL with iDisp, HDA audio codecs. - Say Y or m if you have such a device. This is a recommended option. - If unsure select "N". - config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH tristate "GLK with RT5682 and MAX98357A in I2S Mode" depends on MFD_INTEL_LPSS && I2C && ACPI @@ -319,4 +309,18 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH endif ## SND_SOC_INTEL_SKYLAKE +if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + +config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH + tristate "SKL/KBL/BXT/APL with HDA Codecs" + select SND_SOC_HDAC_HDMI + # SND_SOC_HDAC_HDA is already selected + help + This adds support for ASoC machine driver for Intel platforms + SKL/KBL/BXT/APL with iDisp, HDA audio codecs. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + +endif ## SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + endif ## SND_SOC_INTEL_MACH diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index db6976f4ddaa..08a5152e635a 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -19,6 +19,7 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include #include #include #include @@ -35,6 +36,8 @@ #define CHT_PLAT_CLK_3_HZ 19200000 #define CHT_CODEC_DAI "HiFi" +#define QUIRK_PMC_PLT_CLK_0 0x01 + struct cht_mc_private { struct clk *mclk; struct snd_soc_jack jack; @@ -385,11 +388,43 @@ static struct snd_soc_card snd_soc_card_cht = { .num_controls = ARRAY_SIZE(cht_mc_controls), }; +static const struct dmi_system_id cht_max98090_quirk_table[] = { + { + /* Clapper model Chromebook */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Clapper"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Gnawty model Chromebook (Acer Chromebook CB3-111) */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Gnawty"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + { + /* Swanky model Chromebook (Toshiba Chromebook 2) */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"), + }, + .driver_data = (void *)QUIRK_PMC_PLT_CLK_0, + }, + {} +}; + static int snd_cht_mc_probe(struct platform_device *pdev) { + const struct dmi_system_id *dmi_id; struct device *dev = &pdev->dev; int ret_val = 0; struct cht_mc_private *drv; + const char *mclk_name; + int quirks = 0; + + dmi_id = dmi_first_match(cht_max98090_quirk_table); + if (dmi_id) + quirks = (unsigned long)dmi_id->driver_data; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); if (!drv) @@ -411,11 +446,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) snd_soc_card_cht.dev = &pdev->dev; snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); - drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (quirks & QUIRK_PMC_PLT_CLK_0) + mclk_name = "pmc_plt_clk_0"; + else + mclk_name = "pmc_plt_clk_3"; + + drv->mclk = devm_clk_get(&pdev->dev, mclk_name); if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev, - "Failed to get MCLK from pmc_plt_clk_3: %ld\n", - PTR_ERR(drv->mclk)); + "Failed to get MCLK from %s: %ld\n", + mclk_name, PTR_ERR(drv->mclk)); return PTR_ERR(drv->mclk); } diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index f81e7996aa0c..3f0ac1312982 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -37,7 +37,9 @@ #include "skl.h" #include "skl-sst-dsp.h" #include "skl-sst-ipc.h" +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) #include "../../../soc/codecs/hdac_hda.h" +#endif /* * initialize the PCI registers @@ -661,6 +663,8 @@ static void skl_clock_device_unregister(struct skl *skl) platform_device_unregister(skl->clk_dev); } +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) + #define IDISP_INTEL_VENDOR_ID 0x80860000 /* @@ -679,6 +683,8 @@ static void load_codec_module(struct hda_codec *codec) #endif } +#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ + /* * Probe the given codec address */ @@ -688,9 +694,11 @@ static int probe_codec(struct hdac_bus *bus, int addr) (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; unsigned int res = -1; struct skl *skl = bus_to_skl(bus); +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) struct hdac_hda_priv *hda_codec; - struct hdac_device *hdev; int err; +#endif + struct hdac_device *hdev; mutex_lock(&bus->cmd_mutex); snd_hdac_bus_send_cmd(bus, cmd); @@ -700,6 +708,7 @@ static int probe_codec(struct hdac_bus *bus, int addr) return -EIO; dev_dbg(bus->dev, "codec #%d probed OK: %x\n", addr, res); +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) hda_codec = devm_kzalloc(&skl->pci->dev, sizeof(*hda_codec), GFP_KERNEL); if (!hda_codec) @@ -718,6 +727,13 @@ static int probe_codec(struct hdac_bus *bus, int addr) load_codec_module(&hda_codec->codec); } return 0; +#else + hdev = devm_kzalloc(&skl->pci->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) + return -ENOMEM; + + return snd_hdac_ext_bus_device_init(bus, addr, hdev); +#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ } /* Codec initialization */ @@ -818,6 +834,12 @@ static void skl_probe_work(struct work_struct *work) } } + /* + * we are done probing so decrement link counts + */ + list_for_each_entry(hlink, &bus->hlink_list, list) + snd_hdac_ext_bus_link_put(bus, hlink); + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { err = snd_hdac_display_power(bus, false); if (err < 0) { @@ -827,12 +849,6 @@ static void skl_probe_work(struct work_struct *work) } } - /* - * we are done probing so decrement link counts - */ - list_for_each_entry(hlink, &bus->hlink_list, list) - snd_hdac_ext_bus_link_put(bus, hlink); - /* configure PM */ pm_runtime_put_noidle(bus->dev); pm_runtime_allow(bus->dev); @@ -873,7 +889,7 @@ static int skl_create(struct pci_dev *pci, hbus = skl_to_hbus(skl); bus = skl_to_bus(skl); -#if IS_ENABLED(CONFIG_SND_SOC_HDAC_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) ext_ops = snd_soc_hdac_hda_get_ops(); #endif snd_hdac_ext_bus_init(bus, &pci->dev, &bus_core_ops, io_ops, ext_ops); diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index d5ae9eb8c756..fed45b41f9d3 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -36,6 +36,8 @@ #include "../codecs/twl6040.h" struct abe_twl6040 { + struct snd_soc_card card; + struct snd_soc_dai_link dai_links[2]; int jack_detection; /* board can detect jack events */ int mclk_freq; /* MCLK frequency speed for twl6040 */ }; @@ -208,40 +210,10 @@ static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) ARRAY_SIZE(dmic_audio_map)); } -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link abe_twl6040_dai_links[] = { - { - .name = "TWL6040", - .stream_name = "TWL6040", - .codec_dai_name = "twl6040-legacy", - .codec_name = "twl6040-codec", - .init = omap_abe_twl6040_init, - .ops = &omap_abe_ops, - }, - { - .name = "DMIC", - .stream_name = "DMIC Capture", - .codec_dai_name = "dmic-hifi", - .codec_name = "dmic-codec", - .init = omap_abe_dmic_init, - .ops = &omap_abe_dmic_ops, - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card omap_abe_card = { - .owner = THIS_MODULE, - - .dapm_widgets = twl6040_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - static int omap_abe_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct snd_soc_card *card = &omap_abe_card; + struct snd_soc_card *card; struct device_node *dai_node; struct abe_twl6040 *priv; int num_links = 0; @@ -252,12 +224,18 @@ static int omap_abe_probe(struct platform_device *pdev) return -ENODEV; } - card->dev = &pdev->dev; - priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); if (priv == NULL) return -ENOMEM; + card = &priv->card; + card->dev = &pdev->dev; + card->owner = THIS_MODULE; + card->dapm_widgets = twl6040_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets); + card->dapm_routes = audio_map; + card->num_dapm_routes = ARRAY_SIZE(audio_map); + if (snd_soc_of_parse_card_name(card, "ti,model")) { dev_err(&pdev->dev, "Card name is not provided\n"); return -ENODEV; @@ -274,14 +252,27 @@ static int omap_abe_probe(struct platform_device *pdev) dev_err(&pdev->dev, "McPDM node is not provided\n"); return -EINVAL; } - abe_twl6040_dai_links[0].cpu_of_node = dai_node; - abe_twl6040_dai_links[0].platform_of_node = dai_node; + + priv->dai_links[0].name = "DMIC"; + priv->dai_links[0].stream_name = "TWL6040"; + priv->dai_links[0].cpu_of_node = dai_node; + priv->dai_links[0].platform_of_node = dai_node; + priv->dai_links[0].codec_dai_name = "twl6040-legacy"; + priv->dai_links[0].codec_name = "twl6040-codec"; + priv->dai_links[0].init = omap_abe_twl6040_init; + priv->dai_links[0].ops = &omap_abe_ops; dai_node = of_parse_phandle(node, "ti,dmic", 0); if (dai_node) { num_links = 2; - abe_twl6040_dai_links[1].cpu_of_node = dai_node; - abe_twl6040_dai_links[1].platform_of_node = dai_node; + priv->dai_links[1].name = "TWL6040"; + priv->dai_links[1].stream_name = "DMIC Capture"; + priv->dai_links[1].cpu_of_node = dai_node; + priv->dai_links[1].platform_of_node = dai_node; + priv->dai_links[1].codec_dai_name = "dmic-hifi"; + priv->dai_links[1].codec_name = "dmic-codec"; + priv->dai_links[1].init = omap_abe_dmic_init; + priv->dai_links[1].ops = &omap_abe_dmic_ops; } else { num_links = 1; } @@ -300,7 +291,7 @@ static int omap_abe_probe(struct platform_device *pdev) return -ENODEV; } - card->dai_link = abe_twl6040_dai_links; + card->dai_link = priv->dai_links; card->num_links = num_links; snd_soc_card_set_drvdata(card, priv); diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index fe966272bd0c..cba9645b6487 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -48,6 +48,8 @@ struct omap_dmic { struct device *dev; void __iomem *io_base; struct clk *fclk; + struct pm_qos_request pm_qos_req; + int latency; int fclk_freq; int out_freq; int clk_div; @@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream, mutex_lock(&dmic->mutex); + pm_qos_remove_request(&dmic->pm_qos_req); + if (!dai->active) dmic->active = 0; @@ -228,6 +232,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, /* packet size is threshold * channels */ dma_data = snd_soc_dai_get_dma_data(dai, substream); dma_data->maxburst = dmic->threshold * channels; + dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC / + params_rate(params); return 0; } @@ -238,6 +244,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream, struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); u32 ctrl; + if (pm_qos_request_active(&dmic->pm_qos_req)) + pm_qos_update_request(&dmic->pm_qos_req, dmic->latency); + /* Configure uplink threshold */ omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold); diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index e0ef4774c710..a395598f1f20 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -999,9 +999,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, pkt_size = channels; } - latency = ((((buffer_size - pkt_size) / channels) * 1000) - / (params->rate_num / params->rate_den)); - + latency = (buffer_size - pkt_size) / channels; + latency = latency * USEC_PER_SEC / + (params->rate_num / params->rate_den); mcbsp->latency[substream->stream] = latency; omap_mcbsp_set_threshold(substream, pkt_size); diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 4c1be36c2207..7d5bdc5a2890 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -54,6 +54,8 @@ struct omap_mcpdm { unsigned long phys_base; void __iomem *io_base; int irq; + struct pm_qos_request pm_qos_req; + int latency[2]; struct mutex mutex; @@ -277,6 +279,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; mutex_lock(&mcpdm->mutex); @@ -289,6 +294,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, } } + if (mcpdm->latency[stream2]) + pm_qos_update_request(&mcpdm->pm_qos_req, + mcpdm->latency[stream2]); + else if (mcpdm->latency[stream1]) + pm_qos_remove_request(&mcpdm->pm_qos_req); + + mcpdm->latency[stream1] = 0; + mutex_unlock(&mcpdm->mutex); } @@ -300,7 +313,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, int stream = substream->stream; struct snd_dmaengine_dai_dma_data *dma_data; u32 threshold; - int channels; + int channels, latency; int link_mask = 0; channels = params_channels(params); @@ -344,14 +357,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, dma_data->maxburst = (MCPDM_DN_THRES_MAX - threshold) * channels; + latency = threshold; } else { /* If playback is not running assume a stereo stream to come */ if (!mcpdm->config[!stream].link_mask) mcpdm->config[!stream].link_mask = (0x3 << 3); dma_data->maxburst = threshold * channels; + latency = (MCPDM_DN_THRES_MAX - threshold); } + /* + * The DMA must act to a DMA request within latency time (usec) to avoid + * under/overflow + */ + mcpdm->latency[stream] = latency * USEC_PER_SEC / params_rate(params); + + if (!mcpdm->latency[stream]) + mcpdm->latency[stream] = 10; + /* Check if we need to restart McPDM with this stream */ if (mcpdm->config[stream].link_mask && mcpdm->config[stream].link_mask != link_mask) @@ -366,6 +390,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req; + int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; + int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + int latency = mcpdm->latency[stream2]; + + /* Prevent omap hardware from hitting off between FIFO fills */ + if (!latency || mcpdm->latency[stream1] < latency) + latency = mcpdm->latency[stream1]; + + if (pm_qos_request_active(pm_qos_req)) + pm_qos_update_request(pm_qos_req, latency); + else if (latency) + pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); if (!omap_mcpdm_active(mcpdm)) { omap_mcpdm_start(mcpdm); @@ -427,6 +465,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) free_irq(mcpdm->irq, (void *)mcpdm); pm_runtime_disable(mcpdm->dev); + if (pm_qos_request_active(&mcpdm->pm_qos_req)) + pm_qos_remove_request(&mcpdm->pm_qos_req); + return 0; } diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index eb1b9da05dd4..4715527054e5 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -13,6 +13,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card) struct device_node *cpu = NULL; struct device *dev = card->dev; struct snd_soc_dai_link *link; + struct of_phandle_args args; int ret, num_links; ret = snd_soc_of_parse_card_name(card, "model"); @@ -47,12 +48,14 @@ int qcom_snd_parse_of(struct snd_soc_card *card) goto err; } - link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); - if (!link->cpu_of_node) { + ret = of_parse_phandle_with_args(cpu, "sound-dai", + "#sound-dai-cells", 0, &args); + if (ret) { dev_err(card->dev, "error getting cpu phandle\n"); - ret = -EINVAL; goto err; } + link->cpu_of_node = args.np; + link->id = args.args[0]; ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); if (ret) { diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c index a07a4538d5cf..bfc3bbf1d4de 100644 --- a/sound/soc/qcom/qdsp6/q6afe-dai.c +++ b/sound/soc/qcom/qdsp6/q6afe-dai.c @@ -1112,204 +1112,204 @@ static int q6afe_of_xlate_dai_name(struct snd_soc_component *component, } static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = { - SND_SOC_DAPM_AIF_OUT("HDMI_RX", "HDMI Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_1_TX", "Slimbus1 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_3_TX", "Slimbus3 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SLIMBUS_6_TX", "Slimbus6 Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback", + SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback", + SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback", + SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1", + SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1", "Secondary MI2S Playback SD1", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback", + SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture", + SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_0", "Primary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_1", "Primary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_2", "Primary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_3", "Primary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_4", "Primary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_5", "Primary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_6", "Primary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_7", "Primary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_0", "Primary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_1", "Primary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_2", "Primary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_3", "Primary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_4", "Primary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_5", "Primary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_6", "Primary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_7", "Primary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback", + SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL, 0, 0, 0, 0), - SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture", + SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL, 0, 0, 0, 0), }; diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 000775b4bba8..829b5e987b2a 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -49,14 +49,14 @@ #define AFE_PORT_I2S_SD1 0x2 #define AFE_PORT_I2S_SD2 0x3 #define AFE_PORT_I2S_SD3 0x4 -#define AFE_PORT_I2S_SD0_MASK BIT(0x1) -#define AFE_PORT_I2S_SD1_MASK BIT(0x2) -#define AFE_PORT_I2S_SD2_MASK BIT(0x3) -#define AFE_PORT_I2S_SD3_MASK BIT(0x4) -#define AFE_PORT_I2S_SD0_1_MASK GENMASK(2, 1) -#define AFE_PORT_I2S_SD2_3_MASK GENMASK(4, 3) -#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(3, 1) -#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(4, 1) +#define AFE_PORT_I2S_SD0_MASK BIT(0x0) +#define AFE_PORT_I2S_SD1_MASK BIT(0x1) +#define AFE_PORT_I2S_SD2_MASK BIT(0x2) +#define AFE_PORT_I2S_SD3_MASK BIT(0x3) +#define AFE_PORT_I2S_SD0_1_MASK GENMASK(1, 0) +#define AFE_PORT_I2S_SD2_3_MASK GENMASK(3, 2) +#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(2, 0) +#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(3, 0) #define AFE_PORT_I2S_QUAD01 0x5 #define AFE_PORT_I2S_QUAD23 0x6 #define AFE_PORT_I2S_6CHS 0x7 diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index a16c71c03058..86115de5c1b2 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -122,7 +122,6 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = { .rate_max = 48000, \ }, \ .name = "MultiMedia"#num, \ - .probe = fe_dai_probe, \ .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \ } @@ -511,38 +510,6 @@ static void q6asm_dai_pcm_free(struct snd_pcm *pcm) } } -static const struct snd_soc_dapm_route afe_pcm_routes[] = { - {"MM_DL1", NULL, "MultiMedia1 Playback" }, - {"MM_DL2", NULL, "MultiMedia2 Playback" }, - {"MM_DL3", NULL, "MultiMedia3 Playback" }, - {"MM_DL4", NULL, "MultiMedia4 Playback" }, - {"MM_DL5", NULL, "MultiMedia5 Playback" }, - {"MM_DL6", NULL, "MultiMedia6 Playback" }, - {"MM_DL7", NULL, "MultiMedia7 Playback" }, - {"MM_DL7", NULL, "MultiMedia8 Playback" }, - {"MultiMedia1 Capture", NULL, "MM_UL1"}, - {"MultiMedia2 Capture", NULL, "MM_UL2"}, - {"MultiMedia3 Capture", NULL, "MM_UL3"}, - {"MultiMedia4 Capture", NULL, "MM_UL4"}, - {"MultiMedia5 Capture", NULL, "MM_UL5"}, - {"MultiMedia6 Capture", NULL, "MM_UL6"}, - {"MultiMedia7 Capture", NULL, "MM_UL7"}, - {"MultiMedia8 Capture", NULL, "MM_UL8"}, - -}; - -static int fe_dai_probe(struct snd_soc_dai *dai) -{ - struct snd_soc_dapm_context *dapm; - - dapm = snd_soc_component_get_dapm(dai->component); - snd_soc_dapm_add_routes(dapm, afe_pcm_routes, - ARRAY_SIZE(afe_pcm_routes)); - - return 0; -} - - static const struct snd_soc_component_driver q6asm_fe_dai_component = { .name = DRV_NAME, .ops = &q6asm_dai_ops, diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index c6b51571be94..d61b8404f7da 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -909,6 +909,25 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL7", NULL, "MultiMedia7 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + + {"MM_DL1", NULL, "MultiMedia1 Playback" }, + {"MM_DL2", NULL, "MultiMedia2 Playback" }, + {"MM_DL3", NULL, "MultiMedia3 Playback" }, + {"MM_DL4", NULL, "MultiMedia4 Playback" }, + {"MM_DL5", NULL, "MultiMedia5 Playback" }, + {"MM_DL6", NULL, "MultiMedia6 Playback" }, + {"MM_DL7", NULL, "MultiMedia7 Playback" }, + {"MM_DL8", NULL, "MultiMedia8 Playback" }, + + {"MultiMedia1 Capture", NULL, "MM_UL1"}, + {"MultiMedia2 Capture", NULL, "MM_UL2"}, + {"MultiMedia3 Capture", NULL, "MM_UL3"}, + {"MultiMedia4 Capture", NULL, "MM_UL4"}, + {"MultiMedia5 Capture", NULL, "MM_UL5"}, + {"MultiMedia6 Capture", NULL, "MM_UL6"}, + {"MultiMedia7 Capture", NULL, "MM_UL7"}, + {"MultiMedia8 Capture", NULL, "MM_UL8"}, + }; static int routing_hw_params(struct snd_pcm_substream *substream, diff --git a/sound/soc/rockchip/rockchip_pcm.c b/sound/soc/rockchip/rockchip_pcm.c index 9e7b5fa4cf59..4ac78d7a4b2d 100644 --- a/sound/soc/rockchip/rockchip_pcm.c +++ b/sound/soc/rockchip/rockchip_pcm.c @@ -33,6 +33,7 @@ static const struct snd_pcm_hardware snd_rockchip_hardware = { static const struct snd_dmaengine_pcm_config rk_dmaengine_pcm_config = { .pcm_hardware = &snd_rockchip_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, .prealloc_buffer_size = 32 * 1024, }; diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index ad6298330fdb..59e250cc2e9d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1525,6 +1525,18 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, }; int ret; + /* + * 1) Avoid duplicate register (ex. MIXer case) + * 2) re-register if card was rebinded + */ + list_for_each_entry(kctrl, &card->controls, list) { + struct rsnd_kctrl_cfg *c = kctrl->private_data; + + if (strcmp(kctrl->id.name, name) == 0 && + c->mod == mod) + return 0; + } + if (size > RSND_MAX_CHANNELS) return -EINVAL; diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 17eff3e60bbe..8d91c0eb0880 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -40,11 +40,8 @@ struct rsnd_dvc { struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */ struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ - u32 flags; }; -#define KCTRL_INITIALIZED (1 << 0) - #define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id) #define rsnd_dvc_nr(priv) ((priv)->dvc_nr) @@ -221,9 +218,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int channels = rsnd_rdai_channels_get(rdai); int ret; - if (rsnd_flags_has(dvc, KCTRL_INITIALIZED)) - return 0; - /* Volume */ ret = rsnd_kctrl_new_m(mod, io, rtd, is_play ? @@ -279,8 +273,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, if (ret < 0) return ret; - rsnd_flags_set(dvc, KCTRL_INITIALIZED); - return 0; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 1fdcc7c3fc7e..45ef295743ec 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -286,7 +286,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (rsnd_ssi_is_multi_slave(mod, io)) return 0; - if (ssi->rate) { + if (ssi->usrcnt > 1) { if (ssi->rate != rate) { dev_err(dev, "SSI parent/child should use same rate\n"); return -EINVAL; diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c index b8e72b52db30..4fb29f0e561e 100644 --- a/sound/soc/soc-acpi.c +++ b/sound/soc/soc-acpi.c @@ -10,11 +10,17 @@ struct snd_soc_acpi_mach * snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) { struct snd_soc_acpi_mach *mach; + struct snd_soc_acpi_mach *mach_alt; for (mach = machines; mach->id[0]; mach++) { if (acpi_dev_present(mach->id, NULL, -1)) { - if (mach->machine_quirk) - mach = mach->machine_quirk(mach); + if (mach->machine_quirk) { + mach_alt = mach->machine_quirk(mach); + if (!mach_alt) + continue; /* not full match, ignore */ + mach = mach_alt; + } + return mach; } } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 012000de4bf0..b0db59e6339d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2131,6 +2131,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } card->instantiated = 1; + dapm_mark_endpoints_dirty(card); snd_soc_dapm_sync(&card->dapm); mutex_unlock(&card->mutex); mutex_unlock(&client_mutex); diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig index 66aad0d3f9c7..8134c3c94229 100644 --- a/sound/soc/sunxi/Kconfig +++ b/sound/soc/sunxi/Kconfig @@ -31,7 +31,7 @@ config SND_SUN8I_CODEC_ANALOG config SND_SUN50I_CODEC_ANALOG tristate "Allwinner sun50i Codec Analog Controls Support" depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST - select SND_SUNXI_ADDA_PR_REGMAP + select SND_SUN8I_ADDA_PR_REGMAP help Say Y or M if you want to add support for the analog controls for the codec embedded in Allwinner A64 SoC. diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 522a72fde78d..92c5de026c43 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -481,7 +481,11 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 Slot 0 Right"}, - /* ADC routes */ + /* ADC Routes */ + { "AIF1 Slot 0 Right ADC", NULL, "ADC" }, + { "AIF1 Slot 0 Left ADC", NULL, "ADC" }, + + /* ADC Mixer Routes */ { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "AIF1 Slot 0 Left ADC" }, { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", @@ -605,16 +609,10 @@ err_pm_disable: static int sun8i_codec_remove(struct platform_device *pdev) { - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card); - pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) sun8i_codec_runtime_suspend(&pdev->dev); - clk_disable_unprepare(scodec->clk_module); - clk_disable_unprepare(scodec->clk_bus); - return 0; }