Merge tag 'asoc-v4.20-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorTakashi Iwai <tiwai@suse.de>
Tue, 27 Nov 2018 15:06:42 +0000 (16:06 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 27 Nov 2018 15:06:42 +0000 (16:06 +0100)
ASoC: Fixes for v4.20

Lots of fixes here, the majority of which are driver specific but
there's a couple of core things and one notable driver specific one:

 - A core fix for a DAPM regression introduced during the component
   refactoring, we'd lost the code that forced a reevaluation of the
   DAPM graph after probe (which we suppress during init to save lots
   of recalcuation) and have now restored it.
 - A core fix for error handling using the newly added
   for_each_rtd_codec_dai_rollback() macro.
 - A fix for the names of widgets in the newly introduced pcm3060
   driver, merged as a fix so we don't have a release with legacy names.

26 files changed:
MAINTAINERS
include/sound/soc.h
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/pcm186x.h
sound/soc/codecs/pcm3060.c
sound/soc/codecs/wm_adsp.c
sound/soc/intel/Kconfig
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/skylake/skl.c
sound/soc/omap/omap-abe-twl6040.c
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/qcom/common.c
sound/soc/qcom/qdsp6/q6afe-dai.c
sound/soc/qcom/qdsp6/q6afe.c
sound/soc/qcom/qdsp6/q6asm-dai.c
sound/soc/qcom/qdsp6/q6routing.c
sound/soc/rockchip/rockchip_pcm.c
sound/soc/sh/rcar/ssi.c
sound/soc/soc-acpi.c
sound/soc/soc-core.c
sound/soc/stm/stm32_sai_sub.c
sound/soc/sunxi/Kconfig
sound/soc/sunxi/sun8i-codec.c

index f4855974f325063c1e5fea88d9d755ce75ee3b66..103bc4b1964c9a0e6a8168f3360e3dd42b3047c3 100644 (file)
@@ -13915,6 +13915,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
index f1dab1f4b194d46423bd168e9027eab8fe09891a..70c10a8f3e90a7a828d9df930e16fed5915f1686 100644 (file)
@@ -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 */
index 4e9854889a9570dd66e9476fb7a9b082053016e7..e63d6e33df487dff441f1890e8235d491d7d5144 100644 (file)
@@ -2187,11 +2187,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) {
@@ -2201,7 +2196,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)
index 2c6ba55bf394eb0f2ad4a2a4ce2f2fc21291a541..bb3f0c42a1cdddb31a603948c39bafa56a42a654 100644 (file)
@@ -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)
index 494d9d662be8d084113e5720a2c3e86b3331eaf2..771b46e1974b9d068cc7797b8c2d0353d4b2ddfd 100644 (file)
@@ -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" },
index a53dc174bbf0702c2876e19ccf3d7e8b45b71e94..66501b8dc46fb17e962f7bf1b69923da7bdae1a6 100644 (file)
@@ -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,
index 0caa1f4eb94d7d3ab086d2bdca642a9a975651b4..18e71770368550f167ea32385160e853e9dd5264 100644 (file)
@@ -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
index 73ca1350aa3124f1e2d784509cbc9ad6ae9be1d1..b177db2a0dbb2ada825849e5e8d85d952a67d1b2 100644 (file)
@@ -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
index db6976f4ddaa28b9eb0e123b93d9952cd1869634..9d9f6e41d81c079796cb7bec6d9422bd6cbb5c67 100644 (file)
@@ -19,6 +19,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -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,29 @@ 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[] = {
+       {
+               /* 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 +432,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);
        }
 
index 29225623b4b40d1c8fea6822b85b007e57aba690..7487f388e65d729c8fc6032a3e84d0908ac454f4 100644 (file)
@@ -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
@@ -658,6 +660,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
 
 /*
@@ -676,6 +680,8 @@ static void load_codec_module(struct hda_codec *codec)
 #endif
 }
 
+#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
+
 /*
  * Probe the given codec address
  */
@@ -685,9 +691,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);
@@ -697,6 +705,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)
@@ -715,6 +724,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 */
@@ -815,6 +831,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) {
@@ -824,12 +846,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);
@@ -870,7 +886,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);
index d5ae9eb8c7569f6364f8fc5173be2967cd9be092..fed45b41f9d3e7766c2239de15b9ef05453097ae 100644 (file)
@@ -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);
index fe966272bd0cd0ba6d049bb60d80f759722eb96d..cba9645b648763cc03d7ffa7dbcca4f060056fe1 100644 (file)
@@ -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);
 
index d0ebb6b9bfac3a38ed320cb957a32cb71788b418..2d6decbfc99efc021bb19f5bd1eecc9b333a6b77 100644 (file)
@@ -308,9 +308,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);
index 4c1be36c22075b3b449325dfc44eccd565c50f1a..7d5bdc5a2890369eea9ea84ae7b0b5ed30d3e334 100644 (file)
@@ -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;
 }
 
index eb1b9da05dd47a5dcf9013e01c88e0a74af3e60f..4715527054e5e07fc1d3218937aa3d91130e3c9e 100644 (file)
@@ -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) {
index 60ff4a2d35774eebdaced12f36a275ce2738f5f2..8f6c8fc073a93048cb2e33d8439105ac2dc7d025 100644 (file)
@@ -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),
 };
 
index 000775b4bba83d5d7e877acfb5aefca6d5b759be..829b5e987b2aaf03d234fc79f276bb5e324ba715 100644 (file)
 #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
index a16c71c03058eb4e7a7a427a1aad3cb226f5f8ed..86115de5c1b2a1bd16a42a13305b4c62d6feee27 100644 (file)
@@ -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,
index c6b51571be945e5262dbf46966caab4e1615f529..d61b8404f7da999c2326e2aa6ee26522a044257e 100644 (file)
@@ -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,
index 9e7b5fa4cf59630ee65d2ee15e9893f97d8245ce..4ac78d7a4b2da8fb51e9de8fcc751614787fb324 100644 (file)
@@ -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,
 };
 
index fcb4df23248c163b287ff39aab02dd6b2970b237..6ec78f3096dd3e8158561535569e1f2502674d49 100644 (file)
@@ -306,7 +306,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;
index b8e72b52db30ea44c92092dc2a0a4135218624fc..4fb29f0e561ef3b1a558ebe93f201efb105628df 100644 (file)
@@ -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;
                }
        }
index 6ddcf12bc030dbb6a8a582fae810c8ba4ccf5bd3..b29d0f65611eb536ded7aaa3e41416ca600c2bde 100644 (file)
@@ -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);
index ea05cc91aa05d8d14a402769928cb9119a8c9147..211589b0b2ef5400276d689599134bd02919691d 100644 (file)
@@ -390,7 +390,7 @@ static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)
        char *mclk_name, *p, *s = (char *)pname;
        int ret, i = 0;
 
-       mclk = devm_kzalloc(dev, sizeof(mclk), GFP_KERNEL);
+       mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL);
        if (!mclk)
                return -ENOMEM;
 
index 66aad0d3f9c7f9d04a44795eeca7591b190fde77..8134c3c94229263a982d0009bc89dfa6b5a0aad6 100644 (file)
@@ -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.
index 522a72fde78da9b89f40551577de40fee351f59f..92c5de026c43a7c8cf1ec3913ee5257353ef201f 100644 (file)
@@ -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;
 }