[v2,6/6] ASoC: atmel_ssc_dai: Enable shared FSYNC source in frame-slave mode
diff mbox series

Message ID b56ebac96ad232e2d9871067b13654eb9223f28f.1566677788.git.mirq-linux@rere.qmqm.pl
State New
Headers show
Series
  • ] ASoC: atmel: extend SSC support
Related show

Commit Message

Michał Mirosław Aug. 24, 2019, 8:26 p.m. UTC
SSC driver allows only synchronous TX and RX. In slave mode for BCLK
it uses only one of TK or RK pin, but for LRCLK it configured separate
inputs from TF and RF pins. Allow configuration with common FS signal.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>

---
 v2: use alternate DT binding
     split DT and drivers/misc changes

---
 sound/soc/atmel/atmel_ssc_dai.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

Comments

Codrin Ciubotariu Aug. 26, 2019, 3:05 p.m. UTC | #1
On 24.08.2019 23:26, Michał Mirosław wrote:
> SSC driver allows only synchronous TX and RX. In slave mode for BCLK
> it uses only one of TK or RK pin, but for LRCLK it configured separate
> inputs from TF and RF pins. Allow configuration with common FS signal.
> 
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> 
> ---
>   v2: use alternate DT binding
>       split DT and drivers/misc changes
> 
> ---
>   sound/soc/atmel/atmel_ssc_dai.c | 26 ++++++++++++++++++++++----
>   1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
> index 48e9eef34c0f..035d4da58f2b 100644
> --- a/sound/soc/atmel/atmel_ssc_dai.c
> +++ b/sound/soc/atmel/atmel_ssc_dai.c
> @@ -605,14 +605,32 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
>   		return -EINVAL;
>   	}
>   
> -	if (!atmel_ssc_cfs(ssc_p)) {
> +	if (atmel_ssc_cfs(ssc_p)) {
> +		/*
> +		 * SSC provides LRCLK
> +		 *
> +		 * Both TF and RF are generated, so use them directly.
> +		 */
> +		rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> +		tcmr |=	  SSC_BF(TCMR_START, fs_edge);

Hmm, how would this work if capture and playback start/run at the same time?

> +	} else {
>   		fslen = fslen_ext = 0;
>   		rcmr_period = tcmr_period = 0;
>   		fs_osync = SSC_FSOS_NONE;
> -	}
>   
> -	rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> -	tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> +		if (ssc->lrclk_from_tf_pin) {
> +			rcmr |=	  SSC_BF(RCMR_START, SSC_START_TX_RX);
> +			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> +		} else if (ssc->lrclk_from_rf_pin) {
> +			/* assume RF is to be used when RK is used as BCLK input */

This comment is not longer true...

> +			/* Note: won't work correctly on SAMA5D2 due to errata */
> +			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> +			tcmr |=	  SSC_BF(TCMR_START, SSC_START_TX_RX);
> +		} else {
> +			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> +			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> +		}
> +	}
>   
>   	if (atmel_ssc_cbs(ssc_p)) {
>   		/*
> 

Thanks and best regards,
Codrin
Michał Mirosław Sept. 8, 2019, 1:39 p.m. UTC | #2
On Mon, Aug 26, 2019 at 03:05:06PM +0000, Codrin.Ciubotariu@microchip.com wrote:
> On 24.08.2019 23:26, Michał Mirosław wrote:
> > SSC driver allows only synchronous TX and RX. In slave mode for BCLK
> > it uses only one of TK or RK pin, but for LRCLK it configured separate
> > inputs from TF and RF pins. Allow configuration with common FS signal.
> > 
> > Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> > 
> > ---
> >   v2: use alternate DT binding
> >       split DT and drivers/misc changes
> > 
> > ---
> >   sound/soc/atmel/atmel_ssc_dai.c | 26 ++++++++++++++++++++++----
> >   1 file changed, 22 insertions(+), 4 deletions(-)
> > 
> > diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
> > index 48e9eef34c0f..035d4da58f2b 100644
> > --- a/sound/soc/atmel/atmel_ssc_dai.c
> > +++ b/sound/soc/atmel/atmel_ssc_dai.c
> > @@ -605,14 +605,32 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
> >   		return -EINVAL;
> >   	}
> >   
> > -	if (!atmel_ssc_cfs(ssc_p)) {
> > +	if (atmel_ssc_cfs(ssc_p)) {
> > +		/*
> > +		 * SSC provides LRCLK
> > +		 *
> > +		 * Both TF and RF are generated, so use them directly.
> > +		 */
> > +		rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> > +		tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> 
> Hmm, how would this work if capture and playback start/run at the same time?

Same as it did before this patch: as there is only one bi-directional link
between SSC and codec, whichever stream starts first defines the rate.

> > +	} else {
> >   		fslen = fslen_ext = 0;
> >   		rcmr_period = tcmr_period = 0;
> >   		fs_osync = SSC_FSOS_NONE;
> > -	}
> >   
> > -	rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> > -	tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> > +		if (ssc->lrclk_from_tf_pin) {
> > +			rcmr |=	  SSC_BF(RCMR_START, SSC_START_TX_RX);
> > +			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> > +		} else if (ssc->lrclk_from_rf_pin) {
> > +			/* assume RF is to be used when RK is used as BCLK input */
> 
> This comment is not longer true...

Removed for next version.

> 
> > +			/* Note: won't work correctly on SAMA5D2 due to errata */
> > +			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> > +			tcmr |=	  SSC_BF(TCMR_START, SSC_START_TX_RX);
> > +		} else {
> > +			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
> > +			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
> > +		}
> > +	}
> >   
> >   	if (atmel_ssc_cbs(ssc_p)) {
> >   		/*
> > 
> 
> Thanks and best regards,
> Codrin

Best Regards,
Michał Mirosław

Patch
diff mbox series

diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 48e9eef34c0f..035d4da58f2b 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -605,14 +605,32 @@  static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	if (!atmel_ssc_cfs(ssc_p)) {
+	if (atmel_ssc_cfs(ssc_p)) {
+		/*
+		 * SSC provides LRCLK
+		 *
+		 * Both TF and RF are generated, so use them directly.
+		 */
+		rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+		tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+	} else {
 		fslen = fslen_ext = 0;
 		rcmr_period = tcmr_period = 0;
 		fs_osync = SSC_FSOS_NONE;
-	}
 
-	rcmr |=	  SSC_BF(RCMR_START, fs_edge);
-	tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+		if (ssc->lrclk_from_tf_pin) {
+			rcmr |=	  SSC_BF(RCMR_START, SSC_START_TX_RX);
+			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+		} else if (ssc->lrclk_from_rf_pin) {
+			/* assume RF is to be used when RK is used as BCLK input */
+			/* Note: won't work correctly on SAMA5D2 due to errata */
+			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+			tcmr |=	  SSC_BF(TCMR_START, SSC_START_TX_RX);
+		} else {
+			rcmr |=	  SSC_BF(RCMR_START, fs_edge);
+			tcmr |=	  SSC_BF(TCMR_START, fs_edge);
+		}
+	}
 
 	if (atmel_ssc_cbs(ssc_p)) {
 		/*