@@ -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