Merge branch 'asoc-5.4' into asoc-next
[linux-2.6-microblaze.git] / sound / soc / atmel / mchp-i2s-mcc.c
index 9a40614..befc2a3 100644 (file)
@@ -674,8 +674,13 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
        dev->channels = channels;
 
        ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra);
-       if (ret < 0)
+       if (ret < 0) {
+               if (dev->gclk_use) {
+                       clk_unprepare(dev->gclk);
+                       dev->gclk_use = 0;
+               }
                return ret;
+       }
        return regmap_write(dev->regmap, MCHP_I2SMCC_MRB, mrb);
 }
 
@@ -690,31 +695,37 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
                err = wait_event_interruptible_timeout(dev->wq_txrdy,
                                                       dev->tx_rdy,
                                                       msecs_to_jiffies(500));
+               if (err == 0) {
+                       dev_warn_once(dev->dev,
+                                     "Timeout waiting for Tx ready\n");
+                       regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
+                                    MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
+                       dev->tx_rdy = 1;
+               }
        } else {
                err = wait_event_interruptible_timeout(dev->wq_rxrdy,
                                                       dev->rx_rdy,
                                                       msecs_to_jiffies(500));
-       }
-
-       if (err == 0) {
-               u32 idra;
-
-               dev_warn_once(dev->dev, "Timeout waiting for %s\n",
-                             is_playback ? "Tx ready" : "Rx ready");
-               if (is_playback)
-                       idra = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
-               else
-                       idra = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
-               regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
+               if (err == 0) {
+                       dev_warn_once(dev->dev,
+                                     "Timeout waiting for Rx ready\n");
+                       regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
+                                    MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
+                       dev->rx_rdy = 1;
+               }
        }
 
        if (!mchp_i2s_mcc_is_running(dev)) {
                regmap_write(dev->regmap, MCHP_I2SMCC_CR, MCHP_I2SMCC_CR_CKDIS);
 
                if (dev->gclk_running) {
-                       clk_disable_unprepare(dev->gclk);
+                       clk_disable(dev->gclk);
                        dev->gclk_running = 0;
                }
+               if (dev->gclk_use) {
+                       clk_unprepare(dev->gclk);
+                       dev->gclk_use = 0;
+               }
        }
 
        return 0;
@@ -813,6 +824,8 @@ static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai)
 
        init_waitqueue_head(&dev->wq_txrdy);
        init_waitqueue_head(&dev->wq_rxrdy);
+       dev->tx_rdy = 1;
+       dev->rx_rdy = 1;
 
        snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture);