alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Markus Pargmann <mpa@pengutronix.de>
To: Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>, Timur Tabi <timur@tabi.org>
Cc: alsa-devel@alsa-project.org, kernel@pengutronix.de,
	Markus Pargmann <mpa@pengutronix.de>,
	Shawn Guo <shawn.guo@linaro.org>,
	Fabio Estevam <festevam@gmail.com>,
	linux-arm-kernel@lists.infradead.org
Subject: [RFC 6/9] ASoC: fsl-ssi: Add configuration helper functions
Date: Fri, 15 Nov 2013 16:49:41 +0100	[thread overview]
Message-ID: <1384530584-31273-7-git-send-email-mpa@pengutronix.de> (raw)
In-Reply-To: <1384530584-31273-1-git-send-email-mpa@pengutronix.de>

This patch adds a struct 'fsl_ssi_rxtx_reg_val' which holds register
values necessary to enable rx/tx. Based on those preset register values,
the added configuration functions will cleanly enable/disable different
parts of the SSI IP while supporting online/offline configuration.
Different operating modes can be setup directly as different register
values in fsl_ssi_reg_val.

These functions and structs will help to cleanup and simplify the
trigger function to support many different IP versions (online/offline
configuration) and different operating modes.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 sound/soc/fsl/fsl_ssi.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 32ee4d8..beb15da 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -125,6 +125,18 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
 #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
 #endif
 
+struct fsl_ssi_reg_val {
+	u32 sier;
+	u32 srcr;
+	u32 stcr;
+	u32 scr;
+};
+
+struct fsl_ssi_rxtx_reg_val {
+	struct fsl_ssi_reg_val rx;
+	struct fsl_ssi_reg_val tx;
+};
+
 /**
  * fsl_ssi_private: per-SSI private data
  *
@@ -161,6 +173,8 @@ struct fsl_ssi_private {
 	struct imx_dma_data filter_data_tx;
 	struct imx_dma_data filter_data_rx;
 	struct imx_pcm_fiq_params fiq_params;
+	/* Register values for rx/tx configuration */
+	struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
 
 	struct {
 		unsigned int rfrc;
@@ -445,6 +459,114 @@ static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
 
 #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
 
+/*
+ * Enable/Disable all rx/tx config flags at once.
+ */
+static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
+		bool enable)
+{
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val;
+
+	if (enable) {
+		write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier);
+		write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr);
+		write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr);
+	} else {
+		write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0);
+		write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0);
+		write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0);
+	}
+}
+
+/*
+ * Enable/Disable a ssi configuration. You have to pass either
+ * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
+ */
+static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
+		struct fsl_ssi_reg_val *vals)
+{
+	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
+	struct fsl_ssi_reg_val *avals;
+	u32 scr_val = read_ssi(&ssi->scr);
+	int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
+				!!(scr_val & CCSR_SSI_SCR_RE);
+
+	/* Find the other direction values rx or tx which we do not want to
+	 * modify */
+	if (&ssi_private->rxtx_reg_val.rx == vals)
+		avals = &ssi_private->rxtx_reg_val.tx;
+	else
+		avals = &ssi_private->rxtx_reg_val.rx;
+
+	/* If vals should be disabled, start with disabling the unit */
+	if (!enable) {
+		u32 scr = vals->scr & (vals->scr ^ avals->scr);
+		write_ssi_mask(&ssi->scr, scr, 0);
+	}
+
+	/*
+	 * We are running on a SoC which does not support online SSI
+	 * reconfiguration, so we have to enable all necessary flags at once
+	 * even if we do not use them later (capture and playback configuration)
+	 */
+	if (ssi_private->offline_config) {
+		if ((enable && !nr_active_streams) ||
+				(!enable && nr_active_streams == 1))
+			fsl_ssi_rxtx_config(ssi_private, enable);
+
+		goto config_done;
+	}
+
+	/*
+	 * Configure single direction units while the SSI unit is running
+	 * (online configuration)
+	 */
+	if (enable) {
+		write_ssi_mask(&ssi->sier, 0, vals->sier);
+		write_ssi_mask(&ssi->srcr, 0, vals->srcr);
+		write_ssi_mask(&ssi->stcr, 0, vals->stcr);
+	} else {
+		u32 sier;
+		u32 srcr;
+		u32 stcr;
+
+		/*
+		 * Disabling the necessary flags for one of rx/tx while the
+		 * other stream is active is a little bit more difficult. We
+		 * have to disable only those flags that differ between both
+		 * streams (rx XOR tx) and that are set in the stream that is
+		 * disabled now. Otherwise we could alter flags of the other
+		 * stream
+		 */
+
+		/* These assignments are simply vals without bits set in avals*/
+		sier = vals->sier & (vals->sier ^ avals->sier);
+		srcr = vals->srcr & (vals->srcr ^ avals->srcr);
+		stcr = vals->stcr & (vals->stcr ^ avals->stcr);
+
+		write_ssi_mask(&ssi->srcr, srcr, 0);
+		write_ssi_mask(&ssi->stcr, stcr, 0);
+		write_ssi_mask(&ssi->sier, sier, 0);
+	}
+
+config_done:
+	/* Enabling of subunits is done after configuration */
+	if (enable)
+		write_ssi_mask(&ssi->scr, 0, vals->scr);
+}
+
+
+static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable)
+{
+	fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx);
+}
+
+static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable)
+{
+	fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx);
+}
+
 static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
 {
 	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-- 
1.8.4.2

  parent reply	other threads:[~2013-11-15 15:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-15 15:49 [RFC 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
2013-11-15 15:49 ` [RFC 1/9] ASoC: fsl-ssi: Drop AC97 debug register usage Markus Pargmann
2013-11-15 15:49 ` [RFC 2/9] ASoC: fsl-ssi: Move ac97 specific setup to seperate function Markus Pargmann
2013-11-15 15:49 ` [RFC 3/9] ASoC: fsl-ssi: Move sysfs stats to debugfs Markus Pargmann
2013-11-15 15:49 ` [RFC 4/9] ASoC: fsl-ssi: Add imx50-ssi and of_device_id matching Markus Pargmann
2013-11-18  1:38   ` Shawn Guo
2013-11-15 15:49 ` [RFC 5/9] ASoC: fsl-ssi: Add offline_config flag Markus Pargmann
2013-11-15 15:49 ` Markus Pargmann [this message]
2013-11-15 15:49 ` [RFC 7/9] ASoC: fsl-ssi: Move RX/TX configuration to seperate functions Markus Pargmann
2013-11-15 15:49 ` [RFC 8/9] ASoC: fsl-ssi: Drop ac97 specific trigger function Markus Pargmann
2013-11-15 15:49 ` [RFC 9/9] ARM: DTS: imx5* imx6*, use imx50-ssi Markus Pargmann
2013-11-18  2:02   ` Shawn Guo
2013-11-18 13:42     ` Markus Pargmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1384530584-31273-7-git-send-email-mpa@pengutronix.de \
    --to=mpa@pengutronix.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=festevam@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=shawn.guo@linaro.org \
    --cc=timur@tabi.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).