Added patch to the ALSA RAVENNA/AES67 driver to handle independent playback and capture I/O startup and termination.
This fixes issue #11
This commit is contained in:
parent
9062a82033
commit
3aeed93856
252
3rdparty/patches/ravenna-alsa-lkm-independent-playback-capture.path
vendored
Normal file
252
3rdparty/patches/ravenna-alsa-lkm-independent-playback-capture.path
vendored
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
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 = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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
|
1
build.sh
1
build.sh
@ -20,6 +20,7 @@ if [ ! -d ravenna-alsa-lkm.git ]; then
|
|||||||
git apply ../../patches/ravenna-alsa-lkm-arm-32bit.patch
|
git apply ../../patches/ravenna-alsa-lkm-arm-32bit.patch
|
||||||
git apply ../../patches/ravenna-alsa-lkm-add-codec-am824.patch
|
git apply ../../patches/ravenna-alsa-lkm-add-codec-am824.patch
|
||||||
git apply ../../patches/ravenna-alsa-lkm-disable-ptp-checksum.patch
|
git apply ../../patches/ravenna-alsa-lkm-disable-ptp-checksum.patch
|
||||||
|
git apply ../../patches/ravenna-alsa-lkm-independent-playback-capture.path
|
||||||
echo "Building ravenna-alsa-lkm kernel module ..."
|
echo "Building ravenna-alsa-lkm kernel module ..."
|
||||||
make
|
make
|
||||||
cd ../..
|
cd ../..
|
||||||
|
Loading…
x
Reference in New Issue
Block a user