diff --git a/sound/soc/amlogic/auge/audio_utils.c b/sound/soc/amlogic/auge/audio_utils.c index a4e82255b22f..5de8b4211025 100644 --- a/sound/soc/amlogic/auge/audio_utils.c +++ b/sound/soc/amlogic/auge/audio_utils.c @@ -32,6 +32,7 @@ struct snd_elem_info { }; static unsigned int loopback_enable; +static unsigned int loopback_is_running; static const char *const loopback_enable_texts[] = { "Disable", @@ -1085,7 +1086,7 @@ static void loopback_modules_disable( { /* tdminLB */ tdmin_lb_fifo_enable(0); - tdmin_lb_enable(0); + tdmin_lb_enable(tdm_index, 0); /* pdmin */ pdm_enable(0); @@ -1100,12 +1101,14 @@ static void loopback_modules_disable( /* frddr */ if (frddr_index >= 3) toddr_enable(0, frddr_index - 3); - else + else if (frddr_index >= 0) frddr_enable(0, frddr_index); /* tdmout */ - tdm_fifo_enable(tdm_index, 0); - tdm_enable(tdm_index, 0); + if (frddr_index >= 0) { + tdm_fifo_enable(tdm_index, 0); + tdm_enable(tdm_index, 0); + } } static void loopback_modules_enable( @@ -1118,13 +1121,15 @@ static void loopback_modules_enable( */ /* tdmout */ - tdm_fifo_enable(tdm_index, 1); - tdm_enable(tdm_index, 1); + if (frddr_index >= 0) { + tdm_fifo_enable(tdm_index, 1); + tdm_enable(tdm_index, 1); + } /* frddr */ if (frddr_index >= 3) toddr_enable(1, frddr_index - 3); - else + else if (frddr_index >= 0) frddr_enable(1, frddr_index); /* toddr */ @@ -1139,7 +1144,7 @@ static void loopback_modules_enable( /*tdminLB*/ tdmin_lb_fifo_enable(1); - tdmin_lb_enable(1); + tdmin_lb_enable(tdm_index, 1); } int loopback_trigger( @@ -1147,13 +1152,13 @@ int loopback_trigger( int cmd, struct loopback_cfg *lb_cfg) { - pr_info("%s\n", __func__); - switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (loopback_enable && loopback_is_running) { + pr_info("loopback enable\n"); + /* * toddr/frdd is selected in dai_prepare already. * check toddr index of datain @@ -1173,22 +1178,18 @@ int loopback_trigger( lb_cfg->toddr_index, lb_cfg->frddr_index); - if (loopback_enable - && (lb_cfg->toddr_index >= 0) - && (lb_cfg->frddr_index >= 0)) { - pr_info("loopback modules in sequence!\n"); - /*if pdm overrun, re-set up the sequence*/ - if (lb_cfg->frddr_index >= 0) - loopback_modules_disable( - lb_cfg->datalb_src, - lb_cfg->frddr_index, - lb_cfg->toddr_index); + pr_info("loopback modules in sequence!\n"); + /*if pdm overrun, re-set up the sequence*/ + if (lb_cfg->frddr_index >= 0) + loopback_modules_disable( + lb_cfg->datalb_src, + lb_cfg->frddr_index, + lb_cfg->toddr_index); - loopback_modules_enable( - lb_cfg->datalb_src, - lb_cfg->frddr_index, - lb_cfg->toddr_index); - } + loopback_modules_enable( + lb_cfg->datalb_src, + lb_cfg->frddr_index, + lb_cfg->toddr_index); } break; case SNDRV_PCM_TRIGGER_STOP: @@ -1198,7 +1199,7 @@ int loopback_trigger( if (loopback_enable) { pr_info("loopback disable\n"); lb_enable(0); - tdmin_lb_enable(0); + tdmin_lb_enable(lb_cfg->datalb_src, 0); } } break; @@ -1209,7 +1210,19 @@ int loopback_trigger( return 0; } +void loopback_set_status(int is_running) +{ + loopback_is_running = is_running; +} + int loopback_is_enable(void) { return (loopback_enable == 1); } + +int loopback_check_enable(int src) +{ + return (src <= PDMIN) + && (loopback_datain == src) + && (loopback_enable == 1); +} diff --git a/sound/soc/amlogic/auge/audio_utils.h b/sound/soc/amlogic/auge/audio_utils.h index 77012f646d99..530d07f17733 100644 --- a/sound/soc/amlogic/auge/audio_utils.h +++ b/sound/soc/amlogic/auge/audio_utils.h @@ -118,16 +118,20 @@ struct loopback_cfg { enum datain_src datain_src; unsigned int datain_chnum; unsigned int datain_chmask; - unsigned int toddr_index; + int toddr_index; enum tdmin_lb_src datalb_src; unsigned int datalb_chnum; unsigned int datalb_chmask; - unsigned int frddr_index; + int frddr_index; }; +extern void loopback_set_status(int is_running); + extern int loopback_is_enable(void); +extern int loopback_check_enable(int src); + extern int snd_card_add_kcontrols(struct snd_soc_card *card); extern int loopback_parse_of(struct device_node *node, diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index 22923dad117e..dcc026bb13c1 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -55,6 +55,7 @@ struct toddr { unsigned int lsb_bit; unsigned int reg_base; enum toddr_src src; + int is_lb; /* check whether for loopback */ int irq; bool in_use: 1; struct aml_audio_controller *actrl; @@ -135,6 +136,12 @@ static int unregister_toddr_l(struct device *dev, void *data) to = &toddrs[i]; + /* check for loopback */ + if (to->is_lb) { + loopback_set_status(0); + to->is_lb = 0; + } + /* disable audio ddr arb */ mask_bit = i; actrl = to->actrl; @@ -259,8 +266,11 @@ void aml_toddr_select_src(struct toddr *to, enum toddr_src src) to->src = src; /* check whether loopback enable */ - if (loopback_is_enable()) + if (loopback_check_enable(src)) { + loopback_set_status(1); + to->is_lb = 1; /* in loopback */ src = LOOPBACK; + } reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); aml_audiobus_update_bits(actrl, reg, 0x7, src & 0x7); diff --git a/sound/soc/amlogic/auge/loopback_hw.c b/sound/soc/amlogic/auge/loopback_hw.c index ba573a65dca3..a609da0e61e0 100644 --- a/sound/soc/amlogic/auge/loopback_hw.c +++ b/sound/soc/amlogic/auge/loopback_hw.c @@ -123,19 +123,22 @@ void lb_mode(int mode) ); } -void tdmin_lb_clk_enalbe(int is_enable) +static void tdmin_lb_clk_enalbe(int tdm_src, int is_enable) { - audiobus_update_bits( - EE_AUDIO_CLK_TDMIN_LB_CTRL, - 0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20, - 0x3 << 30 | 1 << 29 | 2 << 24 | 2 << 20 - ); + if (tdm_src <= 2) + audiobus_update_bits( + EE_AUDIO_CLK_TDMIN_LB_CTRL, + 0x3 << 30 | 1 << 29 | 0xf << 24 | 0xf << 20, + 0x3 << 30 | 1 << 29 | tdm_src << 24 | tdm_src << 20 + ); + else + pr_warn_once("pad from tdmin_a, tdmin_b, tdmin_c needs clks\n"); } -void tdmin_lb_enable(int is_enable) +void tdmin_lb_enable(int tdm_index, int is_enable) { if (is_enable) - tdmin_lb_clk_enalbe(is_enable); + tdmin_lb_clk_enalbe(tdm_index, is_enable); audiobus_update_bits( EE_AUDIO_TDMIN_LB_CTRL, diff --git a/sound/soc/amlogic/auge/loopback_hw.h b/sound/soc/amlogic/auge/loopback_hw.h index c3fd3a666fc9..f58dee3e3d4e 100644 --- a/sound/soc/amlogic/auge/loopback_hw.h +++ b/sound/soc/amlogic/auge/loopback_hw.h @@ -65,7 +65,7 @@ extern void lb_enable(bool is_enable); extern void lb_mode(int mode); -extern void tdmin_lb_enable(int in_enable); +extern void tdmin_lb_enable(int tdm_index, int in_enable); extern void tdmin_lb_fifo_enable(int is_enable); #endif