Merge tag 'sound-fix-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Mar 2023 18:53:59 +0000 (10:53 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Mar 2023 18:53:59 +0000 (10:53 -0800)
Pull sound fixes from Takashi Iwai:
 "A collection of various small fixes that have been gathered since the
  last PR.

  The majority of changes are for ASoC, and there is a small change in
  ASoC PCM core, but the rest are all for driver- specific fixes /
  quirks / updates"

* tag 'sound-fix-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (32 commits)
  ALSA: ice1712: Delete unreachable code in aureon_add_controls()
  ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
  ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC
  ALSA: hda/realtek: Improve support for Dell Precision 3260
  ASoC: mediatek: mt8195: add missing initialization
  ASoC: mediatek: mt8188: add missing initialization
  ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A43)
  ASoC: zl38060 add gpiolib dependency
  ASoC: sam9g20ek: Disable capture unless building with microphone input
  ASoC: mt8192: Fix range for sidetone positive gain
  ASoC: mt8192: Report an error if when an invalid sidetone gain is written
  ASoC: mt8192: Fix event generation for controls
  ASoC: mt8192: Remove spammy log messages
  ASoC: mchp-pdmc: fix poc noise at capture startup
  ASoC: dt-bindings: sama7g5-pdmc: add microchip,startup-delay-us binding
  ASoC: soc-pcm: add option to start DMA after DAI
  ASoC: mt8183: Fix event generation for I2S DAI operations
  ASoC: mt8183: Remove spammy logging from I2S DAI driver
  ASoC: mt6358: Remove undefined HPx Mux enumeration values
  ASoC: mt6358: Validate Wake on Voice 2 writes
  ...

23 files changed:
Documentation/devicetree/bindings/sound/apple,mca.yaml
Documentation/devicetree/bindings/sound/microchip,sama7g5-pdmc.yaml
include/sound/soc-component.h
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/aureon.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/apple/mca.c
sound/soc/atmel/mchp-pdmc.c
sound/soc/atmel/sam9g20_wm8731.c
sound/soc/codecs/Kconfig
sound/soc/codecs/adau7118.c
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/da7219-aad.h
sound/soc/codecs/mt6358.c
sound/soc/codecs/sma1303.c
sound/soc/intel/boards/sof_rt5682.c
sound/soc/intel/common/soc-acpi-intel-mtl-match.c
sound/soc/mediatek/mt8183/mt8183-dai-i2s.c
sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
sound/soc/mediatek/mt8192/mt8192-dai-adda.c
sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
sound/soc/sh/rcar/adg.c
sound/soc/soc-pcm.c

index 40e3a202f443413ec50c102fbda2d4c3aaf2e65b..5c6ec08c7d247c88f0fcceb352a545f6a95f89fc 100644 (file)
@@ -23,6 +23,7 @@ properties:
       - enum:
           - apple,t6000-mca
           - apple,t8103-mca
+          - apple,t8112-mca
       - const: apple,mca
 
   reg:
index c4cf1e5ab84b03baeef34f706d5170eb79e9061f..9b40268537cb2a56f33f36e6e64ba282b71e2082 100644 (file)
@@ -67,6 +67,12 @@ properties:
     maxItems: 4
     uniqueItems: true
 
+  microchip,startup-delay-us:
+    description: |
+      Specifies the delay in microseconds that needs to be applied after
+      enabling the PDMC microphones to avoid unwanted noise due to microphones
+      not being ready.
+
 required:
   - compatible
   - reg
index 3203d35bc8c157326c4b38d04adc7be666964cb2..0814ed1438640988848f8146957973cceabe8aed 100644 (file)
@@ -190,6 +190,8 @@ struct snd_soc_component_driver {
        bool use_dai_pcm_id;    /* use DAI link PCM ID as PCM device number */
        int be_pcm_base;        /* base device ID for all BE PCMs */
 
+       unsigned int start_dma_last;
+
 #ifdef CONFIG_DEBUG_FS
        const char *debugfs_prefix;
 #endif
index e103bb3693c068ed22cd2d02d8db3309ff98cfaf..3c629f4ae08076c966f45e952a4b4ede60368570 100644 (file)
@@ -9260,6 +9260,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0ac9, "Dell Precision 3260", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
@@ -11617,6 +11618,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+       SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
        SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
        SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
        SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
index 9a30f6d35d1358e31282002bc07d2d276b3c65e1..24b9782340001810f3ac051eab3129d86f98a9e2 100644 (file)
@@ -1892,13 +1892,10 @@ static int aureon_add_controls(struct snd_ice1712 *ice)
                unsigned char id;
                snd_ice1712_save_gpio_status(ice);
                id = aureon_cs8415_get(ice, CS8415_ID);
+               snd_ice1712_restore_gpio_status(ice);
                if (id != 0x41)
                        dev_info(ice->card->dev,
                                 "No CS8415 chip. Skipping CS8415 controls.\n");
-               else if ((id & 0x0F) != 0x01)
-                       dev_info(ice->card->dev,
-                                "Detected unsupported CS8415 rev. (%c)\n",
-                                (char)((id & 0x0F) + 'A' - 1));
                else {
                        for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
                                struct snd_kcontrol *kctl;
@@ -1909,7 +1906,6 @@ static int aureon_add_controls(struct snd_ice1712 *ice)
                                        kctl->id.device = ice->pcm->device;
                        }
                }
-               snd_ice1712_restore_gpio_status(ice);
        }
 
        return 0;
index 36314753923b8c6adf458d5d7af6ca15681ac800..4a69ce702360c547e3fc904b1a15d6823227d0c2 100644 (file)
@@ -255,6 +255,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BOARD_NAME, "8A43"),
+               }
+       },
        {}
 };
 
index 24381c42eb54c15e50fad471c382f33b078e0e12..64750db9b96396e2b8d2a78cf185a3cb12c128f6 100644 (file)
 #define SERDES_CONF_UNK3       BIT(14)
 #define SERDES_CONF_NO_DATA_FEEDBACK   BIT(15)
 #define SERDES_CONF_SYNC_SEL   GENMASK(18, 16)
-#define SERDES_CONF_SOME_RST   BIT(19)
 #define REG_TX_SERDES_BITSTART 0x08
 #define REG_RX_SERDES_BITSTART 0x0c
 #define REG_TX_SERDES_SLOTMASK 0x0c
@@ -203,15 +202,24 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
+                          FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
+               mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
+                          FIELD_PREP(SERDES_CONF_SYNC_SEL, 7));
                mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
                           SERDES_STATUS_EN | SERDES_STATUS_RST,
                           SERDES_STATUS_RST);
-               mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
-                          SERDES_CONF_SOME_RST);
-               readl_relaxed(cl->base + serdes_conf);
-               mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
-               WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
+               /*
+                * Experiments suggest that it takes at most ~1 us
+                * for the bit to clear, so wait 2 us for good measure.
+                */
+               udelay(2);
+               WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
                        SERDES_STATUS_RST);
+               mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
+                          FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
+               mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
+                          FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
                break;
        default:
                break;
@@ -942,10 +950,17 @@ static int mca_pcm_new(struct snd_soc_component *component,
                chan = mca_request_dma_channel(cl, i);
 
                if (IS_ERR_OR_NULL(chan)) {
+                       mca_pcm_free(component, rtd->pcm);
+
+                       if (chan && PTR_ERR(chan) == -EPROBE_DEFER)
+                               return PTR_ERR(chan);
+
                        dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
                                i, cl->no, chan);
-                       mca_pcm_free(component, rtd->pcm);
-                       return -EINVAL;
+
+                       if (!chan)
+                               return -EINVAL;
+                       return PTR_ERR(chan);
                }
 
                cl->dma_chans[i] = chan;
index cf4084dcbd5eefd2a4a00079ca6c8c7d40882618..1aed3baa9369708336378c760f6a2a3e6bec5373 100644 (file)
@@ -114,6 +114,7 @@ struct mchp_pdmc {
        struct clk *gclk;
        u32 pdmcen;
        u32 suspend_irq;
+       u32 startup_delay_us;
        int mic_no;
        int sinc_order;
        bool audio_filter_en;
@@ -425,6 +426,7 @@ static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
        .open = &mchp_pdmc_open,
        .close = &mchp_pdmc_close,
        .legacy_dai_naming = 1,
+       .start_dma_last = 1,
 };
 
 static const unsigned int mchp_pdmc_1mic[] = {1};
@@ -632,6 +634,29 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static void mchp_pdmc_noise_filter_workaround(struct mchp_pdmc *dd)
+{
+       u32 tmp, steps = 16;
+
+       /*
+        * PDMC doesn't wait for microphones' startup time thus the acquisition
+        * may start before the microphones are ready leading to poc noises at
+        * the beginning of capture. To avoid this, we need to wait 50ms (in
+        * normal startup procedure) or 150 ms (worst case after resume from sleep
+        * states) after microphones are enabled and then clear the FIFOs (by
+        * reading the RHR 16 times) and possible interrupts before continuing.
+        * Also, for this to work the DMA needs to be started after interrupts
+        * are enabled.
+        */
+       usleep_range(dd->startup_delay_us, dd->startup_delay_us + 5);
+
+       while (steps--)
+               regmap_read(dd->regmap, MCHP_PDMC_RHR, &tmp);
+
+       /* Clear interrupts. */
+       regmap_read(dd->regmap, MCHP_PDMC_ISR, &tmp);
+}
+
 static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
                             int cmd, struct snd_soc_dai *dai)
 {
@@ -644,15 +669,17 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_START:
-               /* Enable overrun and underrun error interrupts */
-               regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
-                            MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
-               dd->suspend_irq = 0;
-               fallthrough;
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
                                              MCHP_PDMC_MR_PDMCEN_MASK,
                                              dd->pdmcen);
+
+               mchp_pdmc_noise_filter_workaround(dd);
+
+               /* Enable interrupts. */
+               regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
+                            MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
+               dd->suspend_irq = 0;
                break;
        case SNDRV_PCM_TRIGGER_SUSPEND:
                regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
@@ -796,6 +823,7 @@ static bool mchp_pdmc_readable_reg(struct device *dev, unsigned int reg)
        case MCHP_PDMC_CFGR:
        case MCHP_PDMC_IMR:
        case MCHP_PDMC_ISR:
+       case MCHP_PDMC_RHR:
        case MCHP_PDMC_VER:
                return true;
        default:
@@ -817,6 +845,17 @@ static bool mchp_pdmc_writeable_reg(struct device *dev, unsigned int reg)
        }
 }
 
+static bool mchp_pdmc_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MCHP_PDMC_ISR:
+       case MCHP_PDMC_RHR:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
@@ -836,6 +875,7 @@ static const struct regmap_config mchp_pdmc_regmap_config = {
        .readable_reg   = mchp_pdmc_readable_reg,
        .writeable_reg  = mchp_pdmc_writeable_reg,
        .precious_reg   = mchp_pdmc_precious_reg,
+       .volatile_reg   = mchp_pdmc_volatile_reg,
        .cache_type     = REGCACHE_FLAT,
 };
 
@@ -918,6 +958,9 @@ static int mchp_pdmc_dt_init(struct mchp_pdmc *dd)
                dd->channel_mic_map[i].clk_edge = edge;
        }
 
+       dd->startup_delay_us = 150000;
+       of_property_read_u32(np, "microchip,startup-delay-us", &dd->startup_delay_us);
+
        return 0;
 }
 
index 1430642c8433ab11d35aa953bd08c879cff7a21a..785b9d01d8afeb9b34dad6fb7a320a82b5080461 100644 (file)
@@ -98,6 +98,9 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
        .init = at91sam9g20ek_wm8731_init,
        .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
                   SND_SOC_DAIFMT_CBP_CFP,
+#ifndef ENABLE_MIC_INPUT
+       .playback_only = true,
+#endif
        SND_SOC_DAILINK_REG(pcm),
 };
 
index bd72c426a93d17d154862c848eebea24d37dde82..07747565c3b51c795e6472c560d44dcb333d4739 100644 (file)
@@ -2103,6 +2103,7 @@ config SND_SOC_WSA883X
 config SND_SOC_ZL38060
        tristate "Microsemi ZL38060 Connected Home Audio Processor"
        depends on SPI_MASTER
+       depends on GPIOLIB
        select REGMAP
        help
          Support for ZL38060 Connected Home Audio Processor from Microsemi,
index bbb09724988766f46b5fb2ae1d13669a5414e8d7..a663d37e57760ff19fe798f949c1e94aff20a281 100644 (file)
@@ -444,22 +444,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = {
        .endianness             = 1,
 };
 
-static void adau7118_regulator_disable(void *data)
-{
-       struct adau7118_data *st = data;
-       int ret;
-       /*
-        * If we fail to disable DVDD, don't bother in trying IOVDD. We
-        * actually don't want to be left in the situation where DVDD
-        * is enabled and IOVDD is disabled.
-        */
-       ret = regulator_disable(st->dvdd);
-       if (ret)
-               return;
-
-       regulator_disable(st->iovdd);
-}
-
 static int adau7118_regulator_setup(struct adau7118_data *st)
 {
        st->iovdd = devm_regulator_get(st->dev, "iovdd");
@@ -481,8 +465,7 @@ static int adau7118_regulator_setup(struct adau7118_data *st)
                regcache_cache_only(st->map, true);
        }
 
-       return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
-                                       st);
+       return 0;
 }
 
 static int adau7118_parset_dt(const struct adau7118_data *st)
index c55b033d89da235884f4ff633caa90dcbc22312a..4a4f09f924bc510ff54fff1cf02a008bca82d982 100644 (file)
@@ -339,11 +339,39 @@ static void da7219_aad_hptest_work(struct work_struct *work)
                                    SND_JACK_HEADSET | SND_JACK_LINEOUT);
 }
 
+static void da7219_aad_jack_det_work(struct work_struct *work)
+{
+       struct da7219_aad_priv *da7219_aad =
+               container_of(work, struct da7219_aad_priv, jack_det_work);
+       struct snd_soc_component *component = da7219_aad->component;
+       u8 srm_st;
+
+       mutex_lock(&da7219_aad->jack_det_mutex);
+
+       srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
+       msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
+       /* Enable ground switch */
+       snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
+
+       mutex_unlock(&da7219_aad->jack_det_mutex);
+}
+
 
 /*
  * IRQ
  */
 
+static irqreturn_t da7219_aad_pre_irq_thread(int irq, void *data)
+{
+
+       struct da7219_aad_priv *da7219_aad = data;
+
+       if (!da7219_aad->jack_inserted)
+               schedule_work(&da7219_aad->jack_det_work);
+
+       return IRQ_WAKE_THREAD;
+}
+
 static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 {
        struct da7219_aad_priv *da7219_aad = data;
@@ -351,14 +379,9 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        u8 events[DA7219_AAD_IRQ_REG_MAX];
-       u8 statusa, srm_st;
+       u8 statusa;
        int i, report = 0, mask = 0;
 
-       srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
-       msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
-       /* Enable ground switch */
-       snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
-
        /* Read current IRQ events */
        regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
                         events, DA7219_AAD_IRQ_REG_MAX);
@@ -377,6 +400,9 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
                events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
                statusa);
 
+       if (!da7219_aad->jack_inserted)
+               cancel_work_sync(&da7219_aad->jack_det_work);
+
        if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
                /* Jack Insertion */
                if (events[DA7219_AAD_IRQ_REG_A] &
@@ -940,8 +966,9 @@ int da7219_aad_init(struct snd_soc_component *component)
 
        INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
        INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
+       INIT_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
 
-       ret = request_threaded_irq(da7219_aad->irq, NULL,
+       ret = request_threaded_irq(da7219_aad->irq, da7219_aad_pre_irq_thread,
                                   da7219_aad_irq_thread,
                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                   "da7219-aad", da7219_aad);
index 21fdf53095cc223ecb564a1c02330463405b4db7..be87ee47edde13953250c8cc4d7d22c474a425e2 100644 (file)
@@ -11,6 +11,7 @@
 #define __DA7219_AAD_H
 
 #include <linux/timer.h>
+#include <linux/mutex.h>
 #include <sound/soc.h>
 #include <sound/jack.h>
 #include <sound/da7219-aad.h>
@@ -196,6 +197,9 @@ struct da7219_aad_priv {
 
        struct work_struct btn_det_work;
        struct work_struct hptest_work;
+       struct work_struct jack_det_work;
+
+       struct mutex  jack_det_mutex;
 
        struct snd_soc_jack *jack;
        bool micbias_resume_enable;
index 93f35e8d26fce33620b8c3b6a88ef6e1a8f6c834..b54610b27906437b0ede084710fb6fc1d5007600 100644 (file)
@@ -560,6 +560,9 @@ static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
        struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
        int enabled = ucontrol->value.integer.value[0];
 
+       if (enabled < 0 || enabled > 1)
+               return -EINVAL;
+
        if (priv->wov_enabled != enabled) {
                if (enabled)
                        mt6358_enable_wov_phase2(priv);
@@ -567,6 +570,8 @@ static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
                        mt6358_disable_wov_phase2(priv);
 
                priv->wov_enabled = enabled;
+
+               return 1;
        }
 
        return 0;
@@ -632,9 +637,6 @@ static const char * const hp_in_mux_map[] = {
        "Audio Playback",
        "Test Mode",
        "HP Impedance",
-       "undefined1",
-       "undefined2",
-       "undefined3",
 };
 
 static int hp_in_mux_map_value[] = {
@@ -643,9 +645,6 @@ static int hp_in_mux_map_value[] = {
        HP_MUX_HP,
        HP_MUX_TEST_MODE,
        HP_MUX_HP_IMPEDANCE,
-       HP_MUX_OPEN,
-       HP_MUX_OPEN,
-       HP_MUX_OPEN,
 };
 
 static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum,
index 727c01facf52db7aa7c94640996a29342fe4c1fc..fa4b0a60f8a91dac9cd4b309a277c69c65d2cf75 100644 (file)
@@ -569,7 +569,7 @@ static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w,
                        ret += sma1303_regmap_update_bits(sma1303,
                                        SMA1303_11_SYSTEM_CTRL2,
                                        SMA1303_LR_DATA_SW_MASK,
-                                       SMA1303_LR_DATA_SW_NORMAL,
+                                       SMA1303_LR_DATA_SW_SWAP,
                                        &temp);
                        if (temp == true)
                                change = true;
index 71a11d747622a61659cecb62f90cb298ffe6f63a..4fe448295a902604900d31d7814583363ff6d2c8 100644 (file)
@@ -223,6 +223,20 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
                                        SOF_RT5682_SSP_AMP(2) |
                                        SOF_RT5682_NUM_HDMIDEV(4)),
        },
+       {
+               .callback = sof_rt5682_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
+                       DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S"),
+               },
+               .driver_data = (void *)(SOF_RT5682_MCLK_EN |
+                                       SOF_RT5682_SSP_CODEC(2) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_MAX98360A_SPEAKER_AMP_PRESENT |
+                                       SOF_RT5682_SSP_AMP(0) |
+                                       SOF_RT5682_NUM_HDMIDEV(4)
+                                       ),
+       },
        {
                .callback = sof_rt5682_quirk_cb,
                .matches = {
@@ -1105,6 +1119,15 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_RT5682_SSP_AMP(1) |
                                        SOF_RT5682_NUM_HDMIDEV(4)),
        },
+       {
+               .name = "mtl_mx98360_rt5682",
+               .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+                                       SOF_RT5682_SSP_CODEC(0) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_MAX98360A_SPEAKER_AMP_PRESENT |
+                                       SOF_RT5682_SSP_AMP(1) |
+                                       SOF_RT5682_NUM_HDMIDEV(4)),
+       },
        {
                .name = "jsl_rt5682",
                .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
index b1a66a0f68181f9e12582c111334168445ebdede..7911c3af8071f26e8b3838daecf87b3ca4c141b7 100644 (file)
@@ -15,6 +15,11 @@ static const struct snd_soc_acpi_codecs mtl_max98357a_amp = {
        .codecs = {"MX98357A"}
 };
 
+static const struct snd_soc_acpi_codecs mtl_max98360a_amp = {
+       .num_codecs = 1,
+       .codecs = {"MX98360A"}
+};
+
 static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = {
        .num_codecs = 2,
        .codecs = {"10EC5682", "RTL5682"},
@@ -28,6 +33,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = {
                .quirk_data = &mtl_max98357a_amp,
                .sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg",
        },
+       {
+               .comp_ids = &mtl_rt5682_rt5682s_hp,
+               .drv_name = "mtl_mx98360_rt5682",
+               .machine_quirk = snd_soc_acpi_codec_list,
+               .quirk_data = &mtl_max98360a_amp,
+               .sof_tplg_filename = "sof-mtl-max98360a-rt5682.tplg",
+       },
        {},
 };
 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines);
index 6a9ace4180d3475bc6308a5a4df129afe7945308..8645ab686970f601e645624e87615a07093c3246 100644 (file)
@@ -141,16 +141,13 @@ static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
        struct mtk_afe_i2s_priv *i2s_priv;
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       int hd_en;
+       int hd_en, change;
 
        if (ucontrol->value.enumerated.item[0] >= e->items)
                return -EINVAL;
 
        hd_en = ucontrol->value.integer.value[0];
 
-       dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
-                __func__, kcontrol->id.name, hd_en);
-
        i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 
        if (!i2s_priv) {
@@ -158,9 +155,10 @@ static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
                return -EINVAL;
        }
 
+       change = i2s_priv->low_jitter_en != hd_en;
        i2s_priv->low_jitter_en = hd_en;
 
-       return 0;
+       return change;
 }
 
 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
@@ -276,9 +274,6 @@ static int mtk_apll_event(struct snd_soc_dapm_widget *w,
        struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 
-       dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
-                __func__, w->name, event);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (strcmp(w->name, APLL1_W_NAME) == 0)
@@ -307,9 +302,6 @@ static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
        struct mtk_afe_i2s_priv *i2s_priv;
 
-       dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
-                __func__, w->name, event);
-
        i2s_priv = get_i2s_priv_by_name(afe, w->name);
 
        if (!i2s_priv) {
@@ -715,11 +707,6 @@ static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
        unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;
        int ret = 0;
 
-       dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
-                __func__,
-                i2s_id,
-                rate, format);
-
        if (i2s_priv) {
                i2s_priv->rate = rate;
 
@@ -810,8 +797,6 @@ static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
                return -EINVAL;
        }
 
-       dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
-
        apll = mt8183_get_apll_by_rate(afe, freq);
        apll_rate = mt8183_get_apll_rate(afe, apll);
 
index 071841903c62000f5dae86ba466849040d79a3bc..7a37752d42444b2890fbbfdf45937b93ea2c69f3 100644 (file)
@@ -679,7 +679,6 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
        unsigned int old_val;
        unsigned int mask;
        unsigned int reg;
-       unsigned int shift;
 
        if (source >= e->items)
                return -EINVAL;
@@ -687,27 +686,22 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
        if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
                reg = ETDM_OUT1_CON4;
                mask = ETDM_OUT_CON4_CLOCK_MASK;
-               shift = ETDM_OUT_CON4_CLOCK_SHIFT;
                val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
        } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
                reg = ETDM_OUT2_CON4;
                mask = ETDM_OUT_CON4_CLOCK_MASK;
-               shift = ETDM_OUT_CON4_CLOCK_SHIFT;
                val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
        } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
                reg = ETDM_OUT3_CON4;
                mask = ETDM_OUT_CON4_CLOCK_MASK;
-               shift = ETDM_OUT_CON4_CLOCK_SHIFT;
                val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
        } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
                reg = ETDM_IN1_CON2;
                mask = ETDM_IN_CON2_CLOCK_MASK;
-               shift = ETDM_IN_CON2_CLOCK_SHIFT;
                val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
        } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
                reg = ETDM_IN2_CON2;
                mask = ETDM_IN_CON2_CLOCK_MASK;
-               shift = ETDM_IN_CON2_CLOCK_SHIFT;
                val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
        } else {
                return -EINVAL;
@@ -715,8 +709,6 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
 
        regmap_read(afe->regmap, reg, &old_val);
        old_val &= mask;
-       old_val >>= shift;
-
        if (old_val == val)
                return 0;
 
@@ -2506,6 +2498,9 @@ static void mt8188_dai_etdm_parse_of(struct mtk_base_afe *afe)
 
        /* etdm in only */
        for (i = 0; i < 2; i++) {
+               dai_id = ETDM_TO_DAI_ID(i);
+               etdm_data = afe_priv->dai_priv[dai_id];
+
                snprintf(prop, sizeof(prop), "mediatek,%s-chn-disabled",
                         of_afe_etdms[i].name);
 
index f8c73e8624df20b0a58e03b699dd470882f4d81b..4919535e2759d97253868bdacf20c30e2ba271df 100644 (file)
@@ -303,9 +303,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
        struct mt8192_afe_private *afe_priv = afe->platform_priv;
        int mtkaif_dmic = afe_priv->mtkaif_dmic;
 
-       dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n",
-                __func__, w->name, event, mtkaif_dmic);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 1);
@@ -345,10 +342,6 @@ static int mtk_adda_ch34_ul_event(struct snd_soc_dapm_widget *w,
        int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34;
        int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only;
 
-       dev_info(afe->dev,
-                "%s(), name %s, event 0x%x, mtkaif_dmic %d, mtkaif_adda6_only %d\n",
-                __func__, w->name, event, mtkaif_dmic, mtkaif_adda6_only);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
@@ -538,9 +531,6 @@ static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
        struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 
-       dev_info(afe->dev, "%s(), name %s, event 0x%x\n",
-                __func__, w->name, event);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 0);
@@ -564,9 +554,6 @@ static int mtk_adda_ch34_dl_event(struct snd_soc_dapm_widget *w,
        struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 
-       dev_info(afe->dev, "%s(), name %s, event 0x%x\n",
-                __func__, w->name, event);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
@@ -604,19 +591,21 @@ static int stf_positive_gain_set(struct snd_kcontrol *kcontrol,
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
        struct mt8192_afe_private *afe_priv = afe->platform_priv;
        int gain_db = ucontrol->value.integer.value[0];
+       bool change = false;
 
        afe_priv->stf_positive_gain_db = gain_db;
 
        if (gain_db >= 0 && gain_db <= 24) {
-               regmap_update_bits(afe->regmap,
-                                  AFE_SIDETONE_GAIN,
-                                  POSITIVE_GAIN_MASK_SFT,
-                                  (gain_db / 6) << POSITIVE_GAIN_SFT);
+               regmap_update_bits_check(afe->regmap,
+                                        AFE_SIDETONE_GAIN,
+                                        POSITIVE_GAIN_MASK_SFT,
+                                        (gain_db / 6) << POSITIVE_GAIN_SFT,
+                                        &change);
        } else {
-               dev_warn(afe->dev, "%s(), gain_db %d invalid\n",
-                        __func__, gain_db);
+               return -EINVAL;
        }
-       return 0;
+
+       return change;
 }
 
 static int mt8192_adda_dmic_get(struct snd_kcontrol *kcontrol,
@@ -637,15 +626,17 @@ static int mt8192_adda_dmic_set(struct snd_kcontrol *kcontrol,
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
        struct mt8192_afe_private *afe_priv = afe->platform_priv;
        int dmic_on;
+       bool change;
 
        dmic_on = ucontrol->value.integer.value[0];
 
-       dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
-                __func__, kcontrol->id.name, dmic_on);
+       change = (afe_priv->mtkaif_dmic != dmic_on) ||
+               (afe_priv->mtkaif_dmic_ch34 != dmic_on);
 
        afe_priv->mtkaif_dmic = dmic_on;
        afe_priv->mtkaif_dmic_ch34 = dmic_on;
-       return 0;
+
+       return change;
 }
 
 static int mt8192_adda6_only_get(struct snd_kcontrol *kcontrol,
@@ -666,20 +657,20 @@ static int mt8192_adda6_only_set(struct snd_kcontrol *kcontrol,
        struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
        struct mt8192_afe_private *afe_priv = afe->platform_priv;
        int mtkaif_adda6_only;
+       bool change;
 
        mtkaif_adda6_only = ucontrol->value.integer.value[0];
 
-       dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
-                __func__, kcontrol->id.name, mtkaif_adda6_only);
-
+       change = afe_priv->mtkaif_adda6_only != mtkaif_adda6_only;
        afe_priv->mtkaif_adda6_only = mtkaif_adda6_only;
-       return 0;
+
+       return change;
 }
 
 static const struct snd_kcontrol_new mtk_adda_controls[] = {
        SOC_SINGLE("Sidetone_Gain", AFE_SIDETONE_GAIN,
                   SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0),
-       SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 100, 0,
+       SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 24, 0,
                       stf_positive_gain_get, stf_positive_gain_set),
        SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
                   DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0),
@@ -750,9 +741,6 @@ static int mtk_stf_event(struct snd_soc_dapm_widget *w,
 
        regmap_read(afe->regmap, AFE_SIDETONE_CON1, &reg_value);
 
-       dev_info(afe->dev, "%s(), name %s, event 0x%x, ul_rate 0x%x, AFE_SIDETONE_CON1 0x%x\n",
-                __func__, w->name, event, ul_rate, reg_value);
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                /* set side tone gain = 0 */
@@ -1163,12 +1151,6 @@ static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
        unsigned int rate = params_rate(params);
        int id = dai->id;
 
-       dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
-                __func__,
-                id,
-                substream->stream,
-                rate);
-
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                unsigned int dl_src2_con0 = 0;
                unsigned int dl_src2_con1 = 0;
@@ -1441,8 +1423,6 @@ int mt8192_dai_adda_register(struct mtk_base_afe *afe)
        struct mtk_base_afe_dai *dai;
        struct mt8192_afe_private *afe_priv = afe->platform_priv;
 
-       dev_info(afe->dev, "%s()\n", __func__);
-
        dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
        if (!dai)
                return -ENOMEM;
index c2e268054773df30f5a78e29a93d5a7c186579c9..f2c9a1fdbe0d04c2b11f7f9f4ebcc3ba3680fb9c 100644 (file)
@@ -2567,6 +2567,9 @@ static void mt8195_dai_etdm_parse_of(struct mtk_base_afe *afe)
 
        /* etdm in only */
        for (i = 0; i < 2; i++) {
+               dai_id = ETDM_TO_DAI_ID(i);
+               etdm_data = afe_priv->dai_priv[dai_id];
+
                ret = snprintf(prop, sizeof(prop),
                               "mediatek,%s-chn-disabled",
                               of_afe_etdms[i].name);
index 7bc4421835d7261fbbffa72b6aecc3712bfb6bd4..0b8926600d900a688cae2f4942cf82e3ff8ad46d 100644 (file)
@@ -39,10 +39,10 @@ struct rsnd_adg {
        int clkin_size;
        int clkout_size;
        u32 ckr;
-       u32 rbga;
-       u32 rbgb;
+       u32 brga;
+       u32 brgb;
 
-       int rbg_rate[ADG_HZ_SIZE]; /* RBGA / RBGB */
+       int brg_rate[ADG_HZ_SIZE]; /* BRGA / BRGB */
 };
 
 #define for_each_rsnd_clkin(pos, adg, i)       \
@@ -75,7 +75,7 @@ static const char * const clkout_name_gen2[] = {
        [CLKOUT3] = "audio_clkout3",
 };
 
-static u32 rsnd_adg_calculate_rbgx(unsigned long div)
+static u32 rsnd_adg_calculate_brgx(unsigned long div)
 {
        int i;
 
@@ -131,8 +131,8 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
                adg->clkin_rate[CLKA],  /* 0000: CLKA */
                adg->clkin_rate[CLKB],  /* 0001: CLKB */
                adg->clkin_rate[CLKC],  /* 0010: CLKC */
-               adg->rbg_rate[ADG_HZ_441],      /* 0011: RBGA */
-               adg->rbg_rate[ADG_HZ_48],       /* 0100: RBGB */
+               adg->brg_rate[ADG_HZ_441],      /* 0011: BRGA */
+               adg->brg_rate[ADG_HZ_48],       /* 0100: BRGB */
        };
 
        min = ~0;
@@ -323,10 +323,10 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
        /*
         * find divided clock from BRGA/BRGB
         */
-       if (rate == adg->rbg_rate[ADG_HZ_441])
+       if (rate == adg->brg_rate[ADG_HZ_441])
                return 0x10;
 
-       if (rate == adg->rbg_rate[ADG_HZ_48])
+       if (rate == adg->brg_rate[ADG_HZ_48])
                return 0x20;
 
        return -EIO;
@@ -358,13 +358,13 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
                ckr = 0x80000000; /* BRGB output = 48kHz */
 
        rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
-       rsnd_mod_write(adg_mod, BRRA,  adg->rbga);
-       rsnd_mod_write(adg_mod, BRRB,  adg->rbgb);
+       rsnd_mod_write(adg_mod, BRRA,  adg->brga);
+       rsnd_mod_write(adg_mod, BRRB,  adg->brgb);
 
        dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
                (ckr) ? 'B' : 'A',
-               (ckr) ? adg->rbg_rate[ADG_HZ_48] :
-                       adg->rbg_rate[ADG_HZ_441]);
+               (ckr) ? adg->brg_rate[ADG_HZ_48] :
+                       adg->brg_rate[ADG_HZ_441]);
 
        return 0;
 }
@@ -484,7 +484,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
        struct device *dev = rsnd_priv_to_dev(priv);
        struct device_node *np = dev->of_node;
        struct property *prop;
-       u32 ckr, rbgx, rbga, rbgb;
+       u32 ckr, brgx, brga, brgb;
        u32 rate, div;
        u32 req_rate[ADG_HZ_SIZE] = {};
        uint32_t count = 0;
@@ -501,8 +501,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
        };
 
        ckr = 0;
-       rbga = 2; /* default 1/6 */
-       rbgb = 2; /* default 1/6 */
+       brga = 2; /* default 1/6 */
+       brgb = 2; /* default 1/6 */
 
        /*
         * ADG supports BRRA/BRRB output only
@@ -543,30 +543,30 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
                if (0 == rate) /* not used */
                        continue;
 
-               /* RBGA */
-               if (!adg->rbg_rate[ADG_HZ_441] && (0 == rate % 44100)) {
+               /* BRGA */
+               if (!adg->brg_rate[ADG_HZ_441] && (0 == rate % 44100)) {
                        div = 6;
                        if (req_Hz[ADG_HZ_441])
                                div = rate / req_Hz[ADG_HZ_441];
-                       rbgx = rsnd_adg_calculate_rbgx(div);
-                       if (BRRx_MASK(rbgx) == rbgx) {
-                               rbga = rbgx;
-                               adg->rbg_rate[ADG_HZ_441] = rate / div;
+                       brgx = rsnd_adg_calculate_brgx(div);
+                       if (BRRx_MASK(brgx) == brgx) {
+                               brga = brgx;
+                               adg->brg_rate[ADG_HZ_441] = rate / div;
                                ckr |= brg_table[i] << 20;
                                if (req_Hz[ADG_HZ_441])
                                        parent_clk_name = __clk_get_name(clk);
                        }
                }
 
-               /* RBGB */
-               if (!adg->rbg_rate[ADG_HZ_48] && (0 == rate % 48000)) {
+               /* BRGB */
+               if (!adg->brg_rate[ADG_HZ_48] && (0 == rate % 48000)) {
                        div = 6;
                        if (req_Hz[ADG_HZ_48])
                                div = rate / req_Hz[ADG_HZ_48];
-                       rbgx = rsnd_adg_calculate_rbgx(div);
-                       if (BRRx_MASK(rbgx) == rbgx) {
-                               rbgb = rbgx;
-                               adg->rbg_rate[ADG_HZ_48] = rate / div;
+                       brgx = rsnd_adg_calculate_brgx(div);
+                       if (BRRx_MASK(brgx) == brgx) {
+                               brgb = brgx;
+                               adg->brg_rate[ADG_HZ_48] = rate / div;
                                ckr |= brg_table[i] << 16;
                                if (req_Hz[ADG_HZ_48])
                                        parent_clk_name = __clk_get_name(clk);
@@ -620,8 +620,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 
 rsnd_adg_get_clkout_end:
        adg->ckr = ckr;
-       adg->rbga = rbga;
-       adg->rbgb = rbgb;
+       adg->brga = brga;
+       adg->brgb = brgb;
 
        return 0;
 
@@ -663,9 +663,9 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
                        __clk_get_name(clk), clk, clk_get_rate(clk));
 
        dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
-               adg->ckr, adg->rbga, adg->rbgb);
-       dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbg_rate[ADG_HZ_441]);
-       dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbg_rate[ADG_HZ_48]);
+               adg->ckr, adg->brga, adg->brgb);
+       dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->brg_rate[ADG_HZ_441]);
+       dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->brg_rate[ADG_HZ_48]);
 
        /*
         * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
index 005b179a770a05e2b8251fa7b25ce298c040931a..5eb056b942ce8d6c1d95a9ee49c27be5d8bae8d0 100644 (file)
@@ -1088,22 +1088,39 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
-       int ret = -EINVAL, _ret = 0;
+       struct snd_soc_component *component;
+       int ret = -EINVAL, _ret = 0, start_dma_last = 0, i;
        int rollback = 0;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               /* Do we need to start dma last? */
+               for_each_rtd_components(rtd, i, component) {
+                       if (component->driver->start_dma_last) {
+                               start_dma_last = 1;
+                               break;
+                       }
+               }
+
                ret = snd_soc_link_trigger(substream, cmd, 0);
                if (ret < 0)
                        goto start_err;
 
-               ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
-               if (ret < 0)
-                       goto start_err;
+               if (start_dma_last) {
+                       ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
+                       if (ret < 0)
+                               goto start_err;
+
+                       ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
+               } else {
+                       ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
+                       if (ret < 0)
+                               goto start_err;
 
-               ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
+                       ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
+               }
 start_err:
                if (ret < 0)
                        rollback = 1;