Skip to content

Commit 9906f57

Browse files
povikjannau
authored andcommitted
ASoC: apple: mca: Separate data & clock port setup
Up until now FEs were always the clock providers -- feeding the clocks on any ports (BEs) they are attached to. This will soon change and FEs will be allowed to be clock consumers. Once that happens, the routing of clocks and data will to some degree decouple. In advance of the change, make preparations: * Narrow down semantics of what was formerly the 'port_driver' field to refer to clocks only. * On 'startup' of BEs, separate the clock and data aspects of the port setup. Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
1 parent e0466e6 commit 9906f57

1 file changed

Lines changed: 40 additions & 27 deletions

File tree

sound/soc/apple/mca.c

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ struct mca_cluster {
133133
struct clk *clk_parent;
134134
struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
135135

136-
bool port_started[SNDRV_PCM_STREAM_LAST + 1];
137-
int port_driver; /* The cluster driving this cluster's port */
136+
bool port_clk_started[SNDRV_PCM_STREAM_LAST + 1];
137+
int port_clk_driver; /* The cluster driving this cluster's port */
138138

139139
bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
140140
struct device_link *pd_link;
@@ -157,7 +157,7 @@ struct mca_data {
157157
struct reset_control *rstc;
158158
struct device_link *pd_link;
159159

160-
/* Mutex for accessing port_driver of foreign clusters */
160+
/* Mutex for accessing port_clk_driver of foreign clusters */
161161
struct mutex port_mutex;
162162

163163
int nclusters;
@@ -311,7 +311,7 @@ static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
311311
for (i = 0; i < mca->nclusters; i++) {
312312
be_cl = &mca->clusters[i];
313313

314-
if (be_cl->port_driver != cl->no)
314+
if (be_cl->port_clk_driver != cl->no)
315315
continue;
316316

317317
for_each_pcm_streams(stream) {
@@ -333,10 +333,10 @@ static int mca_be_prepare(struct snd_pcm_substream *substream,
333333
struct mca_cluster *fe_cl;
334334
int ret;
335335

336-
if (cl->port_driver < 0)
336+
if (cl->port_clk_driver < 0)
337337
return -EINVAL;
338338

339-
fe_cl = &mca->clusters[cl->port_driver];
339+
fe_cl = &mca->clusters[cl->port_clk_driver];
340340

341341
/*
342342
* Typically the CODECs we are paired with will require clocks
@@ -683,12 +683,15 @@ static const struct snd_soc_dai_ops mca_fe_ops = {
683683
.trigger = mca_fe_trigger,
684684
};
685685

686-
static bool mca_be_started(struct mca_cluster *cl)
686+
/*
687+
* Is there a FE attached which will be feeding this port's clocks?
688+
*/
689+
static bool mca_be_clk_started(struct mca_cluster *cl)
687690
{
688691
int stream;
689692

690693
for_each_pcm_streams(stream)
691-
if (cl->port_started[stream])
694+
if (cl->port_clk_started[stream])
692695
return true;
693696
return false;
694697
}
@@ -719,29 +722,35 @@ static int mca_be_startup(struct snd_pcm_substream *substream,
719722

720723
fe_cl = mca_dai_to_cluster(snd_soc_rtd_to_cpu(fe, 0));
721724

722-
if (mca_be_started(cl)) {
725+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
726+
writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
727+
cl->base + REG_PORT_DATA_SEL);
728+
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA,
729+
PORT_ENABLES_TX_DATA);
730+
}
731+
732+
if (mca_be_clk_started(cl)) {
723733
/*
724734
* Port is already started in the other direction.
725735
* Make sure there isn't a conflict with another cluster
726-
* driving the port.
736+
* driving the port clocks.
727737
*/
728-
if (cl->port_driver != fe_cl->no)
738+
if (cl->port_clk_driver != fe_cl->no)
729739
return -EINVAL;
730740

731-
cl->port_started[substream->stream] = true;
741+
cl->port_clk_started[substream->stream] = true;
732742
return 0;
733743
}
734744

735-
writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
736-
cl->base + REG_PORT_ENABLES);
737745
writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
738746
cl->base + REG_PORT_CLOCK_SEL);
739-
writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
740-
cl->base + REG_PORT_DATA_SEL);
747+
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS,
748+
PORT_ENABLES_CLOCKS);
749+
741750
mutex_lock(&mca->port_mutex);
742-
cl->port_driver = fe_cl->no;
751+
cl->port_clk_driver = fe_cl->no;
743752
mutex_unlock(&mca->port_mutex);
744-
cl->port_started[substream->stream] = true;
753+
cl->port_clk_started[substream->stream] = true;
745754

746755
return 0;
747756
}
@@ -753,8 +762,8 @@ static void mca_be_shutdown(struct snd_pcm_substream *substream,
753762
struct mca_data *mca = cl->host;
754763

755764
if (cl->clocks_in_use[substream->stream] &&
756-
!WARN_ON(cl->port_driver < 0)) {
757-
struct mca_cluster *fe_cl = &mca->clusters[cl->port_driver];
765+
!WARN_ON(cl->port_clk_driver < 0)) {
766+
struct mca_cluster *fe_cl = &mca->clusters[cl->port_clk_driver];
758767

759768
/*
760769
* Typically the CODECs we are paired with will require clocks
@@ -772,17 +781,21 @@ static void mca_be_shutdown(struct snd_pcm_substream *substream,
772781
mca_fe_disable_clocks(fe_cl);
773782
}
774783

775-
cl->port_started[substream->stream] = false;
784+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
785+
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA, 0);
786+
writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
787+
}
776788

777-
if (!mca_be_started(cl)) {
789+
cl->port_clk_started[substream->stream] = false;
790+
if (!mca_be_clk_started(cl)) {
778791
/*
779792
* Were we the last direction to shutdown?
780-
* Turn off the lights.
793+
* Turn off the lights (clocks).
781794
*/
782-
writel_relaxed(0, cl->base + REG_PORT_ENABLES);
783-
writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
795+
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS, 0);
796+
writel_relaxed(0, cl->base + REG_PORT_CLOCK_SEL);
784797
mutex_lock(&mca->port_mutex);
785-
cl->port_driver = -1;
798+
cl->port_clk_driver = -1;
786799
mutex_unlock(&mca->port_mutex);
787800
}
788801
}
@@ -1088,7 +1101,7 @@ static int apple_mca_probe(struct platform_device *pdev)
10881101
cl->host = mca;
10891102
cl->no = i;
10901103
cl->base = base + CLUSTER_STRIDE * i;
1091-
cl->port_driver = -1;
1104+
cl->port_clk_driver = -1;
10921105
cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
10931106
if (IS_ERR(cl->clk_parent)) {
10941107
dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",

0 commit comments

Comments
 (0)