diff --git a/driver/audio_driver.c b/driver/audio_driver.c
index 3d9debd..169348b 100644
--- a/driver/audio_driver.c
+++ b/driver/audio_driver.c
@@ -824,13 +824,13 @@ static int mr_alsa_audio_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd
             n = snd_pcm_playback_hw_avail(runtime);
             n += runtime->delay;
         }
-        chip->mr_alsa_audio_ops->start_interrupts(chip->ravenna_peer);
+        chip->mr_alsa_audio_ops->start_interrupts(chip->ravenna_peer, alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK);
         return 0;
 
     case SNDRV_PCM_TRIGGER_STOP:
     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
     case SNDRV_PCM_TRIGGER_SUSPEND:
-        chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer);
+        chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer, alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK);
         return 0;
     default:
         return -EINVAL;
@@ -870,13 +870,13 @@ static int mr_alsa_audio_pcm_prepare(struct snd_pcm_substream *substream)
         {
             if(runtime_dsd_mode != chip->current_dsd)
             {
-                chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer);
+                chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer, substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
                 err = chip->mr_alsa_audio_ops->set_sample_rate(chip->ravenna_peer, runtime_dsd_rate);
             }
         }
         else if(chip->current_rate != runtime->rate)
         {
-            chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer);
+            chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer, substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
             //printk("\n### mr_alsa_audio_pcm_prepare: mr_alsa_audio_ops->set_sample_rate to %u\n", runtime->rate);
             err = chip->mr_alsa_audio_ops->set_sample_rate(chip->ravenna_peer, runtime->rate);
             //printk("### mr_alsa_audio_pcm_prepare: mr_alsa_audio_ops->set_sample_rate returned %d\n\n", err);
@@ -1825,13 +1825,13 @@ static int mr_alsa_audio_pcm_hw_params( struct snd_pcm_substream *substream,
     {
         if(dsd_mode != chip->current_dsd)
         {
-            chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer);
+            chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer, substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
             err = chip->mr_alsa_audio_ops->set_sample_rate(chip->ravenna_peer, dsd_rate);
         }
     }
     else if(rate != chip->current_rate)
     {
-        chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer);
+        chip->mr_alsa_audio_ops->stop_interrupts(chip->ravenna_peer, substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
         err = chip->mr_alsa_audio_ops->set_sample_rate(chip->ravenna_peer, rate);
     }
 
diff --git a/driver/manager.c b/driver/manager.c
index 25b77dc..ec62624 100644
--- a/driver/manager.c
+++ b/driver/manager.c
@@ -133,6 +133,8 @@ bool init(struct TManager* self, int* errorCode)
     self->m_bIORunning = false;
     self->m_pALSAChip = NULL;
     self->m_alsa_driver_frontend = NULL;
+    self->m_bIsPlaybackIO = false;
+    self->m_bIsRecordingIO = false;
 
     memset(self->m_cInterfaceName, 0, MAX_INTERFACE_NAME);
 
@@ -249,8 +251,10 @@ bool start(struct TManager* self)
 bool stop(struct TManager* self)
 {
     MTAL_DP("entering CManager::stop..\n");
-    if(self->m_bIORunning)
-        stopIO(self);
+    if(self->m_bIORunning) {
+        stopIO(self, false);
+        stopIO(self, true);
+    }
     EnableEtherTube(&self->m_EthernetFilter, 0);
 
     StopAudioFrameTICTimer(&self->m_PTP);
@@ -261,14 +265,23 @@ bool stop(struct TManager* self)
 }
 
 //////////////////////////////////////////////////////////////////////////////////
-bool startIO(struct TManager* self)
+bool startIO(struct TManager* self, bool is_playback)
 {
     if(!self->m_bIsStarted)
         return false;
+
     MTAL_DP("MergingRAVENNAAudioDriver::startIO\n");
 
-    MuteInputBuffer(self);
-    MuteOutputBuffer(self);
+    if (!is_playback) {
+        printk(KERN_DEBUG "starting capture I/O\n");
+        MuteInputBuffer(self);
+        self->m_bIsRecordingIO = true;
+    }
+    else {
+        printk(KERN_DEBUG "starting playback I/O\n");
+        MuteOutputBuffer(self);
+        self->m_bIsPlaybackIO = true;
+    }
 
     #if defined(MT_TONE_TEST)
     self->m_tone_test_phase = 0;
@@ -283,12 +296,27 @@ bool startIO(struct TManager* self)
 }
 
 //////////////////////////////////////////////////////////////////////////////////
-bool stopIO(struct TManager* self)
+bool stopIO(struct TManager* self, bool is_playback)
 {
     MTAL_DP("MergingRAVENNAAudioDriver::stopIO\n");
-    self->m_bIORunning = false;
-    MuteInputBuffer(self);
-    MuteOutputBuffer(self);
+
+    if (is_playback && !self->m_bIsPlaybackIO)
+        return true;
+    if (!is_playback && !self->m_bIsRecordingIO)
+        return true;
+
+    if (!is_playback) {
+        printk(KERN_DEBUG "stopping capture I/O\n");
+        MuteInputBuffer(self);
+        self->m_bIsRecordingIO = false;
+    } else {
+        printk(KERN_DEBUG "stopping playback I/O\n");
+        MuteOutputBuffer(self);
+        self->m_bIsPlaybackIO = false;
+    }
+
+    self->m_bIORunning = self->m_bIsRecordingIO || self->m_bIsPlaybackIO;
+
     return true;
 }
 
@@ -613,7 +641,8 @@ void OnNewMessage(struct TManager* self, struct MT_ALSA_msg* msg_rcv)
         case MT_ALSA_Msg_StartIO:
         {
             MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StartIO..\n");
-            if (!startIO(self))
+            /*
+            if (!startIO(self) )
             {
                 MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StartIO.. failed\n");
                 msg_reply.errCode = -401;
@@ -623,11 +652,14 @@ void OnNewMessage(struct TManager* self, struct MT_ALSA_msg* msg_rcv)
                 MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StartIO.. succeeded\n");
                 msg_reply.errCode = 0;
             }
+            */
+            msg_reply.errCode = -401;
             break;
         }
         case MT_ALSA_Msg_StopIO:
         {
             MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StopIO..\n");
+            /*
             if (!stopIO(self))
             {
                 MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StopIO.. failed\n");
@@ -638,6 +670,8 @@ void OnNewMessage(struct TManager* self, struct MT_ALSA_msg* msg_rcv)
                 MTAL_DP("CManager::OnNewMessage MT_ALSA_Msg_StopIO.. succeeded\n");
                 msg_reply.errCode = 0;
             }
+            */
+            msg_reply.errCode = -401;
             break;
         }
         case MT_ALSA_Msg_SetSampleRate:
@@ -1680,20 +1714,25 @@ int get_interrupts_frame_size(void* user, uint32_t *framesize)
     return -EINVAL;
 }
 
-int start_interrupts(void* user)
+int start_interrupts(void* user, bool is_playback)
 {
     struct TManager* self = (struct TManager*)user;
-    if(startIO(self))
+
+    MTAL_DP("entering CManager::start_interrupts..\n");
+    if(startIO(self, is_playback)) {
         return 0;
+    }
     return -1;
 }
 
-int stop_interrupts(void* user)
+int stop_interrupts(void* user, bool is_playback)
 {
     struct TManager* self = (struct TManager*)user;
+
 	MTAL_DP("entering CManager::stop_interrupts..\n");
-    if(stopIO(self))
+    if (stopIO(self, is_playback)) {
         return 0;
+    }
     return -1;
 }
 
diff --git a/driver/manager.h b/driver/manager.h
index a5b2fc2..3306bc9 100644
--- a/driver/manager.h
+++ b/driver/manager.h
@@ -86,6 +86,9 @@ struct TManager
     int32_t m_nPlayoutDelay;
     int32_t m_nCaptureDelay;
 
+    bool m_bIsPlaybackIO;
+    bool m_bIsRecordingIO;
+
     volatile bool m_bIsStarted;
     volatile bool m_bIORunning;
 
@@ -144,8 +147,8 @@ void destroy(struct TManager* self);
 bool start(struct TManager* self);
 bool stop(struct TManager* self);
 
-bool startIO(struct TManager* self);
-bool stopIO(struct TManager* self);
+bool startIO(struct TManager* self, bool is_playback);
+bool stopIO(struct TManager* self, bool is_playback);
 
 bool SetInterfaceName(struct TManager* self, const char* cInterfaceName);
 bool SetSamplingRate(struct TManager* self, uint32_t SamplingRate);
@@ -242,8 +245,8 @@ int get_nb_inputs(void* user, uint32_t *nb_Channels);
 int get_nb_outputs(void* user, uint32_t *nb_Channels);
 int get_playout_delay(void* user, snd_pcm_sframes_t *delay_in_sample);
 int get_capture_delay(void* user, snd_pcm_sframes_t *delay_in_sample);
-int start_interrupts(void* user);
-int stop_interrupts(void* user);
+int start_interrupts(void* user, bool is_playback);
+int stop_interrupts(void* user, bool is_playback);
 int notify_master_volume_change(void* user, int direction, int32_t value);
 int notify_master_switch_change(void* user, int direction, int32_t value);
 int get_master_volume_value(void* user, int direction, int32_t* value);
diff --git a/driver/audio_driver.h b/driver/audio_driver.h
index 930e429..3f2c76d 100644
--- a/driver/audio_driver.h
+++ b/driver/audio_driver.h
@@ -74,8 +74,8 @@ struct alsa_ops
     int (*get_nb_outputs)(void* ravenna_peer, uint32_t *nb_channels);
     int (*get_playout_delay)(void* ravenna_peer, snd_pcm_sframes_t *delay_in_sample);
     int (*get_capture_delay)(void* ravenna_peer, snd_pcm_sframes_t *delay_in_sample);
-    int (*start_interrupts)(void* ravenna_peer); /// starts IO
-    int (*stop_interrupts)(void* ravenna_peer); /// stops IO
+    int (*start_interrupts)(void* ravenna_peer, bool is_playback); /// starts IO
+    int (*stop_interrupts)(void* ravenna_peer, bool is_playback); /// stops IO
 
     int (*notify_master_volume_change)(void* ravenna_peer, int direction, int32_t value); /// direction: 0 for playback, 1 for capture. value: from -99 to 0
     int (*notify_master_switch_change)(void* ravenna_peer, int direction, int32_t value); /// direction: 0 for playback, 1 for capture. value: 0 for mute, 1 for enable
