From fc6c215786db0d67a30a601ea2a3b5d0438db0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 13 Sep 2022 10:29:38 +0200 Subject: [PATCH] ASoC: apple: mca: Apply feedback path from DAPM routing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See if there is a BE feedback path in the DAPM routing map, that is if there is a path from playback to capture widget of the BE. If there is, apply it in hardware. Signed-off-by: Martin PoviĊĦer --- sound/soc/apple/mca.c | 44 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c index a482220a191d..e5e7ed35194e 100644 --- a/sound/soc/apple/mca.c +++ b/sound/soc/apple/mca.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #define USE_RXB_FOR_CAPTURE @@ -138,6 +139,7 @@ struct mca_cluster { bool port_clk_started[SNDRV_PCM_STREAM_LAST + 1]; int port_clk_driver; /* The cluster driving this cluster's port */ + bool port_feedback; bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1]; struct device_link *pd_link; @@ -445,7 +447,8 @@ static unsigned int mca_crop_mask(unsigned int mask, int nchans) static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit, unsigned int mask, int slots, int nchans, - int slot_width, bool is_tx, int port) + int slot_width, bool is_tx, int port, + bool feedback) { __iomem void *serdes_base = cl->base + serdes_unit; u32 serdes_conf, serdes_conf_mask; @@ -482,7 +485,7 @@ static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit, SERDES_CONF_UNK3 | SERDES_CONF_NO_DATA_FEEDBACK; serdes_conf |= SERDES_CONF_UNK1 | SERDES_CONF_UNK2 | - SERDES_CONF_NO_DATA_FEEDBACK; + (feedback ? 0 : SERDES_CONF_NO_DATA_FEEDBACK); } mca_modify(cl, @@ -674,7 +677,8 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream, ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF, tdm_mask, tdm_slots, params_channels(params), - tdm_slot_width, is_tx, port); + tdm_slot_width, is_tx, port, + mca->clusters[port].port_feedback); if (ret) return ret; @@ -746,6 +750,38 @@ static bool mca_be_clk_started(struct mca_cluster *cl) return false; } +static bool mca_is_noncard_widget(struct snd_soc_dapm_widget *widget, + enum snd_soc_dapm_direction dir) +{ + struct snd_soc_dapm_context *dapm = widget->dapm; + + return dapm != &dapm->card->dapm; +} + +static bool mca_be_has_feedback(struct snd_soc_dai *dai) +{ + struct snd_soc_dapm_widget_list *list; + struct snd_soc_dapm_widget *widget; + bool feedback; + int i, ret; + + ret = snd_soc_dapm_dai_get_connected_widgets(dai, SNDRV_PCM_STREAM_CAPTURE, + &list, mca_is_noncard_widget); + if (ret < 0) { + dev_err(dai->dev, "dapm get paths: %d\n", ret); + return false; + } + + feedback = false; + for_each_dapm_widgets(list, i, widget) + if (widget == dai->playback_widget) + feedback = true; + + snd_soc_dapm_dai_free_widgets(&list); + + return feedback; +} + static struct snd_soc_pcm_runtime *mca_be_get_fe(struct snd_soc_pcm_runtime *be, int stream) { @@ -782,6 +818,8 @@ static int mca_be_startup(struct snd_pcm_substream *substream, cl->base + REG_PORT_DATA_SEL); mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA, PORT_ENABLES_TX_DATA); + } else { + cl->port_feedback = mca_be_has_feedback(dai); } if (!fe_cl->clk_provider) -- 2.32.0 (Apple Git-132)