summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Povišer <povik+lin@cutebit.org>2026-07-11 11:11:23 +1000
committerMark Brown <broonie@kernel.org>2026-07-13 13:22:40 +0100
commit108a14b20f958ad5cbb8f8bfaf4932dfd69bb0e5 (patch)
tree78f4e022ee2c8348fa6285395c3182b32334dd03
parent00309bfb1f54558a06b8aeeaedb2e54956b5182a (diff)
downloadlinux-108a14b20f958ad5cbb8f8bfaf4932dfd69bb0e5.tar.gz
linux-108a14b20f958ad5cbb8f8bfaf4932dfd69bb0e5.zip
ASoC: apple: mca: Support capture on multiples BEs
When multiple BEs are linked to a FE, the former behavior was to source the data line from the DIN pin of the first BE only. Change this to ORing the DIN inputs of all linked BEs. As long as the unused slots on each BE's line are zeroed out and the slots on the BEs don't overlap, this will work out well. Signed-off-by: Martin Povišer <povik+lin@cutebit.org> Signed-off-by: James Calligeros <jcalligeros99@gmail.com> Link: https://patch.msgid.link/20260711-apple-audio-redux-v4-5-2994d87c2f24@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/apple/mca.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
index 92c9f8df50d6..d8973e5611dd 100644
--- a/sound/soc/apple/mca.c
+++ b/sound/soc/apple/mca.c
@@ -261,22 +261,19 @@ static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
-static int mca_fe_get_port(struct snd_pcm_substream *substream)
+static int mca_fe_get_portmask(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *fe = snd_soc_substream_to_rtd(substream);
- struct snd_soc_pcm_runtime *be;
struct snd_soc_dpcm *dpcm;
+ int mask = 0;
- be = NULL;
for_each_dpcm_be(fe, substream->stream, dpcm) {
- be = dpcm->be;
- break;
- }
+ int no = mca_dai_to_cluster(snd_soc_rtd_to_cpu(dpcm->be, 0))->no;
- if (!be)
- return -EINVAL;
+ mask |= 1 << no;
+ }
- return mca_dai_to_cluster(snd_soc_rtd_to_cpu(be, 0))->no;
+ return mask;
}
static int mca_fe_enable_clocks(struct mca_cluster *cl)
@@ -417,7 +414,7 @@ static int mca_fe_prepare(struct snd_pcm_substream *substream,
/* Turn on the cluster power domain if not already in use */
if (!cl->syncgen_in_use) {
- int port = mca_fe_get_port(substream);
+ int port = ffs(mca_fe_get_portmask(substream));
cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
@@ -466,7 +463,7 @@ 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 portmask)
{
__iomem void *serdes_base = cl->base + serdes_unit;
u32 serdes_conf, serdes_conf_mask;
@@ -525,7 +522,7 @@ static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
serdes_base + REG_RX_SERDES_SLOTMASK);
writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
- writel_relaxed(1 << port,
+ writel_relaxed(portmask,
serdes_base + REG_RX_SERDES_PORT);
}
@@ -662,7 +659,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
unsigned long bclk_ratio;
unsigned int tdm_slots, tdm_slot_width, tdm_mask;
u32 regval, pad;
- int ret, port, nchans_ceiled;
+ int ret, portmask, nchans_ceiled;
if (!cl->tdm_slot_width) {
/*
@@ -711,13 +708,13 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
tdm_mask = (1 << tdm_slots) - 1;
}
- port = mca_fe_get_port(substream);
- if (port < 0)
- return port;
+ portmask = mca_fe_get_portmask(substream);
+ if (!portmask)
+ return -EINVAL;
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, portmask);
if (ret)
return ret;