Merge remote-tracking branches 'asoc/fix/rt5514', 'asoc/fix/rt5616', 'asoc/fix/rt5659...
authorMark Brown <broonie@kernel.org>
Thu, 26 Oct 2017 07:45:46 +0000 (09:45 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 26 Oct 2017 07:45:46 +0000 (09:45 +0200)
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514-spi.h
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5514.h
sound/soc/codecs/rt5616.c
sound/soc/codecs/rt5659.c
sound/soc/codecs/rt5663.c
sound/soc/samsung/i2s.c
sound/soc/stm/stm32_sai.c
sound/soc/stm/stm32_sai_sub.c

index ed6e5373916c390fb15dfc9efd943c9c55f7d819..12f2ecf3a4feeb3a6133012b33b5b10cad33999f 100644 (file)
@@ -145,9 +145,8 @@ done:
        mutex_unlock(&rt5514_dsp->dma_lock);
 }
 
-static irqreturn_t rt5514_spi_irq(int irq, void *data)
+static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
 {
-       struct rt5514_dsp *rt5514_dsp = data;
        u8 buf[8];
 
        rt5514_dsp->get_size = 0;
@@ -180,6 +179,13 @@ static irqreturn_t rt5514_spi_irq(int irq, void *data)
        if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
                rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
                schedule_delayed_work(&rt5514_dsp->copy_work, 0);
+}
+
+static irqreturn_t rt5514_spi_irq(int irq, void *data)
+{
+       struct rt5514_dsp *rt5514_dsp = data;
+
+       rt5514_schedule_copy(rt5514_dsp);
 
        return IRQ_HANDLED;
 }
@@ -199,12 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
        struct rt5514_dsp *rt5514_dsp =
                        snd_soc_platform_get_drvdata(rtd->platform);
        int ret;
+       u8 buf[8];
 
        mutex_lock(&rt5514_dsp->dma_lock);
        ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
                        params_buffer_bytes(hw_params));
        rt5514_dsp->substream = substream;
        rt5514_dsp->dma_offset = 0;
+
+       /* Read IRQ status and schedule copy accordingly. */
+       rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
+       if (buf[0] & RT5514_IRQ_STATUS_BIT)
+               rt5514_schedule_copy(rt5514_dsp);
+
        mutex_unlock(&rt5514_dsp->dma_lock);
 
        return ret;
index a6434ee6ff037c11c945a3358a90070de316b09c..c1a36647c1197f925985a623ffe52336fd167c68 100644 (file)
@@ -20,6 +20,9 @@
 #define RT5514_BUFFER_VOICE_BASE       0x18000200
 #define RT5514_BUFFER_VOICE_LIMIT      0x18000204
 #define RT5514_BUFFER_VOICE_WP         0x1800020c
+#define RT5514_IRQ_CTRL                        0x18002094
+
+#define RT5514_IRQ_STATUS_BIT          (0x1 << 5)
 
 /* SPI Command */
 enum {
index 0945d212b8dca9d34d19b273d9075977075964e1..d7956ababd11775b0b9d04552faa68f2fadd2545 100644 (file)
@@ -338,39 +338,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
                                fw = NULL;
                        }
 
-                       if (rt5514->model_buf && rt5514->model_len) {
-#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
-                               int ret;
-
-                               ret = rt5514_spi_burst_write(0x4ff80000,
-                                       rt5514->model_buf,
-                                       ((rt5514->model_len / 8) + 1) * 8);
-                               if (ret) {
-                                       dev_err(codec->dev,
-                                               "Model load failed %d\n", ret);
-                                       return ret;
-                               }
-#else
-                               dev_err(codec->dev,
-                                       "No SPI driver for loading firmware\n");
-#endif
-                       } else {
-                               request_firmware(&fw, RT5514_FIRMWARE3,
-                                                codec->dev);
-                               if (fw) {
-#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
-                                       rt5514_spi_burst_write(0x4ff80000,
-                                               fw->data,
-                                               ((fw->size/8)+1)*8);
-#else
-                                       dev_err(codec->dev,
-                                               "No SPI driver to load fw\n");
-#endif
-                                       release_firmware(fw);
-                                       fw = NULL;
-                               }
-                       }
-
                        /* DSP run */
                        regmap_write(rt5514->i2c_regmap, 0x18002f00,
                                0x00055148);
@@ -385,34 +352,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int rt5514_hotword_model_put(struct snd_kcontrol *kcontrol,
-               const unsigned int __user *bytes, unsigned int size)
-{
-       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
-       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
-       struct snd_soc_codec *codec = rt5514->codec;
-       int ret = 0;
-
-       if (rt5514->model_buf || rt5514->model_len < size) {
-               if (rt5514->model_buf)
-                       devm_kfree(codec->dev, rt5514->model_buf);
-               rt5514->model_buf = devm_kmalloc(codec->dev, size, GFP_KERNEL);
-               if (!rt5514->model_buf) {
-                       ret = -ENOMEM;
-                       goto done;
-               }
-       }
-
-       /* Skips the TLV header. */
-       bytes += 2;
-
-       if (copy_from_user(rt5514->model_buf, bytes, size))
-               ret = -EFAULT;
-done:
-       rt5514->model_len = (ret ? 0 : size);
-       return ret;
-}
-
 static const struct snd_kcontrol_new rt5514_snd_controls[] = {
        SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
                RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
@@ -424,8 +363,6 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
                adc_vol_tlv),
        SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
                rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
-       SND_SOC_BYTES_TLV("Hotword Model", 0x8504,
-               NULL, rt5514_hotword_model_put),
 };
 
 /* ADC Mixer*/
index 803311cb7e2a075aa405847a673b31cac66afc6a..2dc40e6d8b3f69835ded69ac71012cb765ac0a36 100644 (file)
 
 #define RT5514_FIRMWARE1       "rt5514_dsp_fw1.bin"
 #define RT5514_FIRMWARE2       "rt5514_dsp_fw2.bin"
-#define RT5514_FIRMWARE3       "rt5514_dsp_fw3.bin"
 
 /* System Clock Source */
 enum {
@@ -282,8 +281,6 @@ struct rt5514_priv {
        int pll_in;
        int pll_out;
        int dsp_enabled;
-       u8 *model_buf;
-       unsigned int model_len;
 };
 
 #endif /* __RT5514_H__ */
index c94e94fe8297877c75f929498628b5d5adf4b654..0e5f54a9bc7efdf1db73307030310b21472c862c 100644 (file)
@@ -98,7 +98,7 @@ static const struct reg_default rt5616_reg[] = {
        { 0x8e, 0x0004 },
        { 0x8f, 0x1100 },
        { 0x90, 0x0000 },
-       { 0x91, 0x0000 },
+       { 0x91, 0x0c00 },
        { 0x92, 0x0000 },
        { 0x93, 0x2000 },
        { 0x94, 0x0200 },
index 71216db15eab8811775275575b573754b85889b5..fa66b11df8d447d1a41af835d085d76afca2ba5e 100644 (file)
@@ -2744,7 +2744,8 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
                SND_SOC_DAPM_PRE_PMU),
        SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
                SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-       SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA_S("LOUT Amp", 1,  RT5659_PWR_ANLG_1, RT5659_PWR_LM_BIT,
+               0,  NULL, 0),
 
        SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
                rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
@@ -3208,6 +3209,7 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
        { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
        { "LOUT Amp", NULL, "LOUT L MIX" },
        { "LOUT Amp", NULL, "LOUT R MIX" },
+       { "LOUT Amp", NULL, "Charge Pump" },
        { "LOUT Amp", NULL, "SYS CLK DET" },
        { "LOUT L Playback", "Switch", "LOUT Amp" },
        { "LOUT R Playback", "Switch", "LOUT Amp" },
index ab9e0ebff5a7ffe8c24a026441538c6bd877a733..e45b895d8279e42ea8bbac880f5be31a669f0206 100644 (file)
@@ -1639,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
 {
        struct rt5663_priv *rt5663 = data;
 
-       dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__);
+       dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n",
+               __func__);
 
        queue_delayed_work(system_wq, &rt5663->jack_detect_work,
                msecs_to_jiffies(250));
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 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;