/*
  * Audio parameters are global and shared among all
- * capture channels. The driver makes no effort to prevent
- * any modifications. User is free change the audio rate,
- * or period size, thus changing parameters for all capture
- * sub-devices.
+ * capture channels. The driver prevents changes to
+ * the parameters if any audio channel is capturing.
  */
 static const struct snd_pcm_hardware tw686x_capture_hw = {
        .info                   = (SNDRV_PCM_INFO_MMAP |
        int i;
 
        spin_lock_irqsave(&dev->lock, flags);
+       /*
+        * Given the audio parameters are global (i.e. shared across
+        * DMA channels), we need to check new params are allowed.
+        */
+       if (((dev->audio_rate != rt->rate) ||
+            (dev->period_size != period_size)) && dev->audio_enabled)
+               goto err_audio_busy;
+
        tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
        spin_unlock_irqrestore(&dev->lock, flags);
 
        spin_unlock_irqrestore(&ac->lock, flags);
 
        return 0;
+
+err_audio_busy:
+       spin_unlock_irqrestore(&dev->lock, flags);
+       return -EBUSY;
 }
 
 static int tw686x_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
        case SNDRV_PCM_TRIGGER_START:
                if (ac->curr_bufs[0] && ac->curr_bufs[1]) {
                        spin_lock_irqsave(&dev->lock, flags);
+                       dev->audio_enabled = 1;
                        tw686x_enable_channel(dev,
                                AUDIO_CHANNEL_OFFSET + ac->ch);
                        spin_unlock_irqrestore(&dev->lock, flags);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
                spin_lock_irqsave(&dev->lock, flags);
+               dev->audio_enabled = 0;
                tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
                spin_unlock_irqrestore(&dev->lock, flags);