unsigned int                            fmt;
        const struct atmel_i2s_gck_param        *gck_param;
        const struct atmel_i2s_caps             *caps;
+       int                                     clk_use_no;
 };
 
 static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
 {
        struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
        bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-       unsigned int mr = 0;
+       unsigned int mr = 0, mr_mask;
        int ret;
 
+       mr_mask = ATMEL_I2SC_MR_FORMAT_MASK | ATMEL_I2SC_MR_MODE_MASK |
+               ATMEL_I2SC_MR_DATALENGTH_MASK;
+       if (is_playback)
+               mr_mask |= ATMEL_I2SC_MR_TXMONO;
+       else
+               mr_mask |= ATMEL_I2SC_MR_RXMONO;
+
        switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
                mr |= ATMEL_I2SC_MR_FORMAT_I2S;
                return -EINVAL;
        }
 
-       return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
+       return regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
 }
 
 static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
        is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
 
        /* If master starts, enable the audio clock. */
-       if (is_master && mck_enabled)
-               err = atmel_i2s_switch_mck_generator(dev, true);
-       if (err)
-               return err;
+       if (is_master && mck_enabled) {
+               if (!dev->clk_use_no) {
+                       err = atmel_i2s_switch_mck_generator(dev, true);
+                       if (err)
+                               return err;
+               }
+               dev->clk_use_no++;
+       }
 
        err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
        if (err)
                return err;
 
        /* If master stops, disable the audio clock. */
-       if (is_master && !mck_enabled)
-               err = atmel_i2s_switch_mck_generator(dev, false);
+       if (is_master && !mck_enabled) {
+               if (dev->clk_use_no == 1) {
+                       err = atmel_i2s_switch_mck_generator(dev, false);
+                       if (err)
+                               return err;
+               }
+               dev->clk_use_no--;
+       }
 
        return err;
 }