Merge tag 'asoc-fix-v4.14-rc6' into asoc-linus
authorMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:30:27 +0000 (21:30 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 10 Nov 2017 21:30:27 +0000 (21:30 +0000)
ASoC: Fixes for v4.14

I've been quite lax in sending these due to conference season but here's
a fairly large collection of ASoC updates.  The one thing that's not
device specific is Takashi's fix for races between delayed work and PCM
destruction, otherwise everything is specific to an individual device.

# gpg: Signature made Thu 26 Oct 2017 15:11:23 BST
# gpg:                using RSA key ADE668AA675718B59FE29FEA24D68B725D5487D0
# gpg:                issuer "broonie@kernel.org"
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>" [unknown]
# gpg:                 aka "Mark Brown <broonie@debian.org>" [unknown]
# gpg:                 aka "Mark Brown <broonie@kernel.org>" [unknown]
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>" [unknown]
# gpg:                 aka "Mark Brown <broonie@linaro.org>" [unknown]
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 3F25 68AA C269 98F9 E813  A1C5 C3F4 36CA 30F5 D8EB
#      Subkey fingerprint: ADE6 68AA 6757 18B5 9FE2  9FEA 24D6 8B72 5D54 87D0

15 files changed:
sound/soc/codecs/max98090.c
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/msm8916-wcd-digital.c
sound/soc/codecs/wm8998.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/rockchip/rockchip_i2s.c
sound/soc/samsung/i2s.c
sound/soc/sh/rcar/adg.c
sound/soc/sh/rcar/ssi.c
sound/soc/soc-pcm.c
sound/soc/stm/stm32_sai.c
sound/soc/stm/stm32_sai_sub.c

index 13bcfb1ef9b423ceb5fa2ae222340eccaed2ed69..f5075d1f79e6360abef58526908f351b341546b1 100644 (file)
@@ -2115,7 +2115,7 @@ static void max98090_pll_work(struct work_struct *work)
        if (!snd_soc_codec_is_active(codec))
                return;
 
-       dev_info(codec->dev, "PLL unlocked\n");
+       dev_info_ratelimited(codec->dev, "PLL unlocked\n");
 
        /* Toggle shutdown OFF then ON */
        snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
index 549c269acc7dfd0a084c333f08076b77390d1c79..a42f8ebb96701d1a5e392465ad00db73a3b83f00 100644 (file)
 #define CDC_A_MICB_1_VAL               (0xf141)
 #define MICB_MIN_VAL 1600
 #define MICB_STEP_SIZE 50
-#define MICB_VOLTAGE_REGVAL(v)         ((v - MICB_MIN_VAL)/MICB_STEP_SIZE)
+#define MICB_VOLTAGE_REGVAL(v)         (((v - MICB_MIN_VAL)/MICB_STEP_SIZE) << 3)
 #define MICB_1_VAL_MICB_OUT_VAL_MASK   GENMASK(7, 3)
 #define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16)  << 3)
 #define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4)  << 3)
@@ -349,8 +349,9 @@ static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
                            | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
 
        if (wcd->micbias_mv) {
-               snd_soc_write(codec, CDC_A_MICB_1_VAL,
-                             MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
+               snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
+                                   MICB_1_VAL_MICB_OUT_VAL_MASK,
+                                   MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
                /*
                 * Special headset needs MICBIAS as 2.7V so wait for
                 * 50 msec for the MICBIAS to reach 2.7 volts.
index 66df8f810f0d740772a62d965466358012d91d4f..a10a724eb448f4d06bffb034fbc86c68ccecb94d 100644 (file)
@@ -238,7 +238,7 @@ static const struct soc_enum rx_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
 static const struct soc_enum rx2_mix1_inp_enum[] = {
        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text),
-       SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
+       SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text),
 };
 
 /* RX2 MIX2 */
@@ -249,7 +249,7 @@ static const struct soc_enum rx2_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
 static const struct soc_enum rx3_mix1_inp_enum[] = {
        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text),
-       SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
+       SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
 };
 
 /* DEC */
index 44f447136e224d3206839cbf1dee1a62143cae9f..4b64bb46eb21bb426d153e3dc119fc3396e16fbf 100644 (file)
@@ -101,7 +101,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
-static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
+static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
                            struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
@@ -109,84 +109,38 @@ static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
        struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
        struct arizona *arizona = wm8998->core.arizona;
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       unsigned int mux, inmode;
-       unsigned int mode_val, src_val;
+       unsigned int mode_reg, mode_index;
+       unsigned int mux, inmode, src_val, mode_val;
 
        mux = ucontrol->value.enumerated.item[0];
        if (mux > 1)
                return -EINVAL;
 
-       /* L and R registers have same shift and mask */
-       inmode = arizona->pdata.inmode[2 * mux];
-       src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
-       if (inmode & ARIZONA_INMODE_SE)
-               src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
-
-       switch (arizona->pdata.inmode[0]) {
-       case ARIZONA_INMODE_DMIC:
-               if (mux)
-                       mode_val = 0;   /* B always analogue */
-               else
-                       mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
-
-               snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
-                                   ARIZONA_IN1_MODE_MASK, mode_val);
-
-               /* IN1A is digital so L and R must change together */
-               /* src_val setting same for both registers */
-               snd_soc_update_bits(codec,
-                                   ARIZONA_ADC_DIGITAL_VOLUME_1L,
-                                   ARIZONA_IN1L_SRC_MASK |
-                                   ARIZONA_IN1L_SRC_SE_MASK, src_val);
-               snd_soc_update_bits(codec,
-                                   ARIZONA_ADC_DIGITAL_VOLUME_1R,
-                                   ARIZONA_IN1R_SRC_MASK |
-                                   ARIZONA_IN1R_SRC_SE_MASK, src_val);
+       switch (e->reg) {
+       case ARIZONA_ADC_DIGITAL_VOLUME_2L:
+               mode_reg = ARIZONA_IN2L_CONTROL;
+               mode_index = 1 + (2 * mux);
                break;
        default:
-               /* both analogue */
-               snd_soc_update_bits(codec,
-                                   e->reg,
-                                   ARIZONA_IN1L_SRC_MASK |
-                                   ARIZONA_IN1L_SRC_SE_MASK,
-                                   src_val);
+               mode_reg = ARIZONA_IN1L_CONTROL;
+               mode_index = (2 * mux);
                break;
        }
 
-       return snd_soc_dapm_mux_update_power(dapm, kcontrol,
-                                            ucontrol->value.enumerated.item[0],
-                                            e, NULL);
-}
-
-static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
-                           struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
-       struct arizona *arizona = wm8998->core.arizona;
-       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       unsigned int mux, inmode, src_val, mode_val;
-
-       mux = ucontrol->value.enumerated.item[0];
-       if (mux > 1)
-               return -EINVAL;
-
-       inmode = arizona->pdata.inmode[1 + (2 * mux)];
+       inmode = arizona->pdata.inmode[mode_index];
        if (inmode & ARIZONA_INMODE_DMIC)
-               mode_val = 1 << ARIZONA_IN2_MODE_SHIFT;
+               mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
        else
                mode_val = 0;
 
-       src_val = mux << ARIZONA_IN2L_SRC_SHIFT;
+       src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
        if (inmode & ARIZONA_INMODE_SE)
-               src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT;
+               src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
 
-       snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL,
-                           ARIZONA_IN2_MODE_MASK, mode_val);
+       snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
 
-       snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L,
-                           ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK,
+       snd_soc_update_bits(codec, e->reg,
+                           ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
                            src_val);
 
        return snd_soc_dapm_mux_update_power(dapm, kcontrol,
@@ -216,14 +170,14 @@ static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
 
 static const struct snd_kcontrol_new wm8998_in1mux[2] = {
        SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
-                         snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+                         snd_soc_dapm_get_enum_double, wm8998_inmux_put),
        SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
-                         snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+                         snd_soc_dapm_get_enum_double, wm8998_inmux_put),
 };
 
 static const struct snd_kcontrol_new wm8998_in2mux =
        SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
-                         snd_soc_dapm_get_enum_double, wm8998_in2mux_put);
+                         snd_soc_dapm_get_enum_double, wm8998_inmux_put);
 
 static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
 static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
index f395bbc7c354549d089ecfbb8a633e0d4e2aadac..23b0da7df1f28a0a71b948f50a665869ae378969 100644 (file)
@@ -1982,8 +1982,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                             GFP_KERNEL);
 
        if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
-           !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)
-               return -ENOMEM;
+           !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list) {
+               ret = -ENOMEM;
+               goto err;
+       }
 
        ret = davinci_mcasp_set_ch_constraints(mcasp);
        if (ret)
index 20755ecc7f9ea7e17d1fcdd5096f577929bb1957..455a55af7ad2d1949edebd4191a6cfa90f59900d 100644 (file)
@@ -160,7 +160,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
                return ret;
        }
 
-       fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF
+       fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
                                | SND_SOC_DAIFMT_CBS_CFS;
 
        ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
@@ -173,8 +173,8 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
        rate->min = rate->max = 48000;
        channels->min = channels->max = 2;
 
-       /* set SSP2 to 24-bit */
-       params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+       /* set SSP2 to 16-bit */
+       params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
        return 0;
 }
 
index 88ff542200075634e9a6b6e0fd0a7f1ba1dbaf7a..9cd0769ccd347c66c4fd65ea0f2d1e1b14df2a55 100644 (file)
@@ -604,6 +604,8 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                codec = pcm->codec_dai->codec;
+               snprintf(jack_name, sizeof(jack_name),
+                       "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
                                SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
                                NULL, 0);
index 22f768ca3c73be752b208ac52b06ed52be53bada..27bcb62568fbc70c6291c34f377c48c9fe36f448 100644 (file)
@@ -2382,7 +2382,7 @@ static int skl_tplg_get_token(struct device *dev,
        case SKL_TKN_U32_MAX_MCPS:
        case SKL_TKN_U32_OBS:
        case SKL_TKN_U32_IBS:
-               ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, dir, pin_index);
+               ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_index, dir);
                if (ret < 0)
                        return ret;
 
index b6590467fd140c9cbfa8e802af70a5fe390da9f4..908211e1d6fcb46eb8e0d7d8401a892967ba156a 100644 (file)
@@ -692,7 +692,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
        if (!pm_runtime_status_suspended(&pdev->dev))
                i2s_runtime_suspend(&pdev->dev);
 
-       clk_disable_unprepare(i2s->mclk);
        clk_disable_unprepare(i2s->hclk);
 
        return 0;
index 10a4da06c0a1477388758f30b2aaf61ae8a5ef12..de783c6d2a7091a4de73c8c8a3d55e05d9493f7c 100644 (file)
@@ -552,8 +552,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
                        }
 
                        ret = clk_prepare_enable(i2s->op_clk);
-                       if (ret)
+                       if (ret) {
+                               clk_put(i2s->op_clk);
+                               i2s->op_clk = NULL;
                                goto err;
+                       }
                        i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
 
                        /* Over-ride the other's */
@@ -1285,6 +1288,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                        }
                }
        }
+       quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
index 938baff86ef280a9b6f6d93a4e4e7283a3ea9eb8..e11ce5036bcfb8347d930673f8888ba414c37418 100644 (file)
@@ -479,10 +479,10 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
        }
 
        if (req_rate[0] % 48000 == 0)
-               adg->flags = AUDIO_OUT_48;
+               adg->flags |= AUDIO_OUT_48;
 
        if (of_get_property(np, "clkout-lr-asynchronous", NULL))
-               adg->flags = LRCLK_ASYNC;
+               adg->flags |= LRCLK_ASYNC;
 
        /*
         * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
index fffc07e7262741781dbe1bf00e9acb05c3c5a766..03c2a1f02643b8eac6a56918a759b8fb95352f72 100644 (file)
@@ -1112,6 +1112,9 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
 
        i = 0;
        for_each_child_of_node(node, np) {
+               if (!of_device_is_available(np))
+                       goto skip;
+
                ssi = rsnd_ssi_get(priv, i);
 
                snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
@@ -1148,7 +1151,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
                        of_node_put(np);
                        goto rsnd_ssi_probe_done;
                }
-
+skip:
                i++;
        }
 
index 94b88b897c3bb1acd0d8b18922a8286f5cadd081..c0f0b09cb433543e32bb38b7d1a17552a2f49381 100644 (file)
@@ -2632,6 +2632,17 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
        return ret;
 }
 
+static void soc_pcm_private_free(struct snd_pcm *pcm)
+{
+       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+       struct snd_soc_platform *platform = rtd->platform;
+
+       /* need to sync the delayed work before releasing resources */
+       flush_delayed_work(&rtd->delayed_work);
+       if (platform->driver->pcm_free)
+               platform->driver->pcm_free(pcm);
+}
+
 /* create a new pcm */
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 {
@@ -2757,7 +2768,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
                }
        }
 
-       pcm->private_free = platform->driver->pcm_free;
+       pcm->private_free = soc_pcm_private_free;
 out:
        dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
                 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
index 1258bef4dcb37e8f8a9e0ea9d69466d64ccd02ed..5fe878ace605f71818c2d978b047357b0ad2254c 100644 (file)
@@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev)
        }
 
        /* reset */
-       rst = reset_control_get_exclusive(&pdev->dev, NULL);
+       rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
        if (!IS_ERR(rst)) {
                reset_control_assert(rst);
                udelay(2);
index 90d43961389977f470a5c870d8678cdbd60a1cfe..dde8ddf9e777b04e5d23850f42f51150a26f6278 100644 (file)
@@ -184,7 +184,6 @@ static const struct regmap_config stm32_sai_sub_regmap_config_h7 = {
 static irqreturn_t stm32_sai_isr(int irq, void *devid)
 {
        struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
-       struct snd_pcm_substream *substream = sai->substream;
        struct platform_device *pdev = sai->pdev;
        unsigned int sr, imr, flags;
        snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
@@ -199,6 +198,11 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
        regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
                           SAI_XCLRFR_MASK);
 
+       if (!sai->substream) {
+               dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
+               return IRQ_NONE;
+       }
+
        if (flags & SAI_XIMR_OVRUDRIE) {
                dev_err(&pdev->dev, "IRQ %s\n",
                        STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
@@ -227,9 +231,9 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
        }
 
        if (status != SNDRV_PCM_STATE_RUNNING) {
-               snd_pcm_stream_lock(substream);
-               snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
-               snd_pcm_stream_unlock(substream);
+               snd_pcm_stream_lock(sai->substream);
+               snd_pcm_stop(sai->substream, SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock(sai->substream);
        }
 
        return IRQ_HANDLED;
@@ -442,12 +446,16 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
 {
        struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
        int cr1, cr1_mask, ret;
-       int fth = STM_SAI_FIFO_TH_HALF;
 
-       /* FIFO config */
+       /*
+        * DMA bursts increment is set to 4 words.
+        * SAI fifo threshold is set to half fifo, to keep enough space
+        * for DMA incoming bursts.
+        */
        regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
                           SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
-                          SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));
+                          SAI_XCR2_FFLUSH |
+                          SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
 
        /* Mode, data format and channel config */
        cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
@@ -481,10 +489,6 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
                return ret;
        }
 
-       /* DMA config */
-       sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
-       snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
-
        return 0;
 }
 
@@ -727,7 +731,12 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
        struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
 
        sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
-       sai->dma_params.maxburst = 1;
+       /*
+        * DMA supports 4, 8 or 16 burst sizes. Burst size 4 is the best choice,
+        * as it allows bytes, half-word and words transfers. (See DMA fifos
+        * constraints).
+        */
+       sai->dma_params.maxburst = 4;
        /* Buswidth will be set by framework at runtime */
        sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;