* [PATCH v4 1/9] ASoC: fsl-ssi: Fix probe error handling
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2014-01-08 17:18 ` Mark Brown
2013-12-20 13:11 ` [PATCH v4 2/9] ASoC: fsl-ssi: Move sysfs stats to debugfs Markus Pargmann
` (8 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
This patch fixes the error handling in the fsl-ssi probe function.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index b2ebaf8..878a3b2 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -141,6 +141,7 @@ struct fsl_ssi_private {
bool imx_ac97;
bool use_dma;
bool baudclk_locked;
+ bool irq_stats;
u8 i2s_mode;
spinlock_t baudclk_lock;
struct clk *baudclk;
@@ -1223,6 +1224,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, ssi_private->irq,
fsl_ssi_isr, 0, ssi_private->name,
ssi_private);
+ ssi_private->irq_stats = true;
if (ret < 0) {
dev_err(&pdev->dev, "could not claim irq %u\n",
ssi_private->irq);
@@ -1273,11 +1275,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
if (ret)
- goto error_dev;
+ goto error_pcm;
} else {
ret = imx_pcm_dma_init(pdev);
if (ret)
- goto error_dev;
+ goto error_pcm;
}
}
@@ -1319,6 +1321,10 @@ done:
return 0;
error_dai:
+ if (ssi_private->ssi_on_imx && !ssi_private->use_dma)
+ imx_pcm_fiq_exit(pdev);
+
+error_pcm:
snd_soc_unregister_component(&pdev->dev);
error_dev:
@@ -1332,7 +1338,8 @@ error_clk:
}
error_irqmap:
- irq_dispose_mapping(ssi_private->irq);
+ if (ssi_private->irq_stats)
+ irq_dispose_mapping(ssi_private->irq);
return ret;
}
@@ -1350,7 +1357,8 @@ static int fsl_ssi_remove(struct platform_device *pdev)
clk_disable_unprepare(ssi_private->baudclk);
clk_disable_unprepare(ssi_private->clk);
}
- irq_dispose_mapping(ssi_private->irq);
+ if (ssi_private->irq_stats)
+ irq_dispose_mapping(ssi_private->irq);
return 0;
}
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 2/9] ASoC: fsl-ssi: Move sysfs stats to debugfs
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 1/9] ASoC: fsl-ssi: Fix probe error handling Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2014-01-08 17:18 ` Mark Brown
2013-12-20 13:11 ` [PATCH v4 3/9] ASoC: fsl-ssi: Add imx51-ssi and of_device_id matching Markus Pargmann
` (7 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
Interrupt statistics of fsl_ssi are mainly for debugging purpose. Most
of those interrupts show error states, e.g. under/overflow.
The stats should be exposed via debugfs instead of sysfs.
This patch moves the statistics file to debugfs.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 184 ++++++++++++++++++++++++++++++------------------
1 file changed, 117 insertions(+), 67 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 878a3b2..702c63d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/slab.h>
@@ -114,6 +115,14 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
+#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
+ CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
+ CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
+#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
+ CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
+ CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
+#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
+
/**
* fsl_ssi_private: per-SSI private data
*
@@ -133,7 +142,6 @@ struct fsl_ssi_private {
unsigned int irq;
unsigned int fifo_depth;
struct snd_soc_dai_driver cpu_dai_drv;
- struct device_attribute dev_attr;
struct platform_device *pdev;
bool new_binding;
@@ -175,6 +183,8 @@ struct fsl_ssi_private {
unsigned int tfe1;
unsigned int tfe0;
} stats;
+ struct dentry *dbg_dir;
+ struct dentry *dbg_stats;
char name[1];
};
@@ -203,7 +213,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
were interrupted for. We mask it with the Interrupt Enable register
so that we only check for events that we're interested in.
*/
- sisr = read_ssi(&ssi->sisr) & SIER_FLAGS;
+ sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK;
if (sisr & CCSR_SSI_SISR_RFRC) {
ssi_private->stats.rfrc++;
@@ -323,6 +333,102 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
return ret;
}
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+/* Show the statistics of a flag only if its interrupt is enabled. The
+ * compiler will optimze this code to a no-op if the interrupt is not
+ * enabled.
+ */
+#define SIER_SHOW(flag, name) \
+ do { \
+ if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \
+ seq_printf(s, #name "=%u\n", ssi_private->stats.name); \
+ } while (0)
+
+
+/**
+ * fsl_sysfs_ssi_show: display SSI statistics
+ *
+ * Display the statistics for the current SSI device. To avoid confusion,
+ * we only show those counts that are enabled.
+ */
+static ssize_t fsl_ssi_stats_show(struct seq_file *s, void *unused)
+{
+ struct fsl_ssi_private *ssi_private = s->private;
+
+ SIER_SHOW(RFRC_EN, rfrc);
+ SIER_SHOW(TFRC_EN, tfrc);
+ SIER_SHOW(CMDAU_EN, cmdau);
+ SIER_SHOW(CMDDU_EN, cmddu);
+ SIER_SHOW(RXT_EN, rxt);
+ SIER_SHOW(RDR1_EN, rdr1);
+ SIER_SHOW(RDR0_EN, rdr0);
+ SIER_SHOW(TDE1_EN, tde1);
+ SIER_SHOW(TDE0_EN, tde0);
+ SIER_SHOW(ROE1_EN, roe1);
+ SIER_SHOW(ROE0_EN, roe0);
+ SIER_SHOW(TUE1_EN, tue1);
+ SIER_SHOW(TUE0_EN, tue0);
+ SIER_SHOW(TFS_EN, tfs);
+ SIER_SHOW(RFS_EN, rfs);
+ SIER_SHOW(TLS_EN, tls);
+ SIER_SHOW(RLS_EN, rls);
+ SIER_SHOW(RFF1_EN, rff1);
+ SIER_SHOW(RFF0_EN, rff0);
+ SIER_SHOW(TFE1_EN, tfe1);
+ SIER_SHOW(TFE0_EN, tfe0);
+
+ return 0;
+}
+
+static int fsl_ssi_stats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fsl_ssi_stats_show, inode->i_private);
+}
+
+static const struct file_operations fsl_ssi_stats_ops = {
+ .open = fsl_ssi_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
+ struct device *dev)
+{
+ ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
+ if (!ssi_private->dbg_dir)
+ return -ENOMEM;
+
+ ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO,
+ ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops);
+ if (!ssi_private->dbg_stats) {
+ debugfs_remove(ssi_private->dbg_dir);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
+{
+ debugfs_remove(ssi_private->dbg_stats);
+ debugfs_remove(ssi_private->dbg_dir);
+}
+
+#else
+
+static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
+ struct device *dev)
+{
+ return 0;
+}
+
+static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
+
static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
{
struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -991,56 +1097,6 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
.write = fsl_ssi_ac97_write,
};
-/* Show the statistics of a flag only if its interrupt is enabled. The
- * compiler will optimze this code to a no-op if the interrupt is not
- * enabled.
- */
-#define SIER_SHOW(flag, name) \
- do { \
- if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
- length += sprintf(buf + length, #name "=%u\n", \
- ssi_private->stats.name); \
- } while (0)
-
-
-/**
- * fsl_sysfs_ssi_show: display SSI statistics
- *
- * Display the statistics for the current SSI device. To avoid confusion,
- * we only show those counts that are enabled.
- */
-static ssize_t fsl_sysfs_ssi_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct fsl_ssi_private *ssi_private =
- container_of(attr, struct fsl_ssi_private, dev_attr);
- ssize_t length = 0;
-
- SIER_SHOW(RFRC_EN, rfrc);
- SIER_SHOW(TFRC_EN, tfrc);
- SIER_SHOW(CMDAU_EN, cmdau);
- SIER_SHOW(CMDDU_EN, cmddu);
- SIER_SHOW(RXT_EN, rxt);
- SIER_SHOW(RDR1_EN, rdr1);
- SIER_SHOW(RDR0_EN, rdr0);
- SIER_SHOW(TDE1_EN, tde1);
- SIER_SHOW(TDE0_EN, tde0);
- SIER_SHOW(ROE1_EN, roe1);
- SIER_SHOW(ROE0_EN, roe0);
- SIER_SHOW(TUE1_EN, tue1);
- SIER_SHOW(TUE0_EN, tue0);
- SIER_SHOW(TFS_EN, tfs);
- SIER_SHOW(RFS_EN, rfs);
- SIER_SHOW(TLS_EN, tls);
- SIER_SHOW(RLS_EN, rls);
- SIER_SHOW(RFF1_EN, rff1);
- SIER_SHOW(RFF0_EN, rff0);
- SIER_SHOW(TFE1_EN, tfe1);
- SIER_SHOW(TFE0_EN, tfe0);
-
- return length;
-}
-
/**
* Make every character in a string lower-case
*/
@@ -1232,20 +1288,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
}
}
- /* Initialize the the device_attribute structure */
- dev_attr = &ssi_private->dev_attr;
- sysfs_attr_init(&dev_attr->attr);
- dev_attr->attr.name = "statistics";
- dev_attr->attr.mode = S_IRUGO;
- dev_attr->show = fsl_sysfs_ssi_show;
-
- ret = device_create_file(&pdev->dev, dev_attr);
- if (ret) {
- dev_err(&pdev->dev, "could not create sysfs %s file\n",
- ssi_private->dev_attr.attr.name);
- goto error_clk;
- }
-
/* Register with ASoC */
dev_set_drvdata(&pdev->dev, ssi_private);
@@ -1256,6 +1298,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
goto error_dev;
}
+ ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev);
+ if (ret)
+ goto error_dbgfs;
+
if (ssi_private->ssi_on_imx) {
if (!ssi_private->use_dma) {
@@ -1325,6 +1371,9 @@ error_dai:
imx_pcm_fiq_exit(pdev);
error_pcm:
+ fsl_ssi_debugfs_remove(ssi_private);
+
+error_dbgfs:
snd_soc_unregister_component(&pdev->dev);
error_dev:
@@ -1348,10 +1397,11 @@ static int fsl_ssi_remove(struct platform_device *pdev)
{
struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
+ fsl_ssi_debugfs_remove(ssi_private);
+
if (!ssi_private->new_binding)
platform_device_unregister(ssi_private->pdev);
snd_soc_unregister_component(&pdev->dev);
- device_remove_file(&pdev->dev, &ssi_private->dev_attr);
if (ssi_private->ssi_on_imx) {
if (!IS_ERR(ssi_private->baudclk))
clk_disable_unprepare(ssi_private->baudclk);
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 3/9] ASoC: fsl-ssi: Add imx51-ssi and of_device_id matching
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 1/9] ASoC: fsl-ssi: Fix probe error handling Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 2/9] ASoC: fsl-ssi: Move sysfs stats to debugfs Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2014-01-08 17:18 ` Mark Brown
2013-12-20 13:11 ` [PATCH v4 4/9] ASoC: fsl-ssi: Fix interrupt stats for imx Markus Pargmann
` (6 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
There is a small but significant difference between imx21-ssi and
imx51-ssi and above. imx21-ssi does not allow online reconfiguration of
some registers. They have to be configured at the beginning.
imx51-ssi has to reconfigure the SSI unit while it is running. Otherwise
it would not be possible to have two streams in parallel. The new SDMA
unit in imx51 and above has to be configured before the first DMA
request arrives. Therefor we need to setup TDMAE/RDMAE just before
starting the stream.
This patch introduces distinct imx51-ssi as compatible and adds
of_device_id matching in the probe function.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 702c63d..39ad516 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -123,6 +123,13 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
+
+enum fsl_ssi_type {
+ FSL_SSI_MCP8610,
+ FSL_SSI_MX21,
+ FSL_SSI_MX51,
+};
+
/**
* fsl_ssi_private: per-SSI private data
*
@@ -189,6 +196,14 @@ struct fsl_ssi_private {
char name[1];
};
+static const struct of_device_id fsl_ssi_ids[] = {
+ { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
+ { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
+ { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21},
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
+
/**
* fsl_ssi_isr: SSI interrupt handler
*
@@ -1118,6 +1133,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
int ret = 0;
struct device_attribute *dev_attr = NULL;
struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id;
+ enum fsl_ssi_type hw_type;
const char *p, *sprop;
const uint32_t *iprop;
struct resource res;
@@ -1132,6 +1149,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
if (!of_device_is_available(np))
return -ENODEV;
+ of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
+ if (!of_id)
+ return -EINVAL;
+ hw_type = (enum fsl_ssi_type) of_id->data;
+
/* We only support the SSI in "I2S Slave" mode */
sprop = of_get_property(np, "fsl,mode", NULL);
if (!sprop) {
@@ -1211,7 +1233,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->baudclk_locked = false;
spin_lock_init(&ssi_private->baudclk_lock);
- if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
+ if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
+ hw_type == FSL_SSI_MX35) {
u32 dma_events[2];
ssi_private->ssi_on_imx = true;
@@ -1413,13 +1436,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id fsl_ssi_ids[] = {
- { .compatible = "fsl,mpc8610-ssi", },
- { .compatible = "fsl,imx21-ssi", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
-
static struct platform_driver fsl_ssi_driver = {
.driver = {
.name = "fsl-ssi-dai",
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 4/9] ASoC: fsl-ssi: Fix interrupt stats for imx
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (2 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 3/9] ASoC: fsl-ssi: Add imx51-ssi and of_device_id matching Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2014-01-08 17:19 ` Mark Brown
2013-12-20 13:11 ` [PATCH v4 5/9] ASoC: fsl-ssi: Add offline_config flag Markus Pargmann
` (5 subsequent siblings)
9 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
irqs should only be requested/released with enabled DMA. Previously
interrupt statistics where disabled for IMX Processors because of
different writeable SISR bits.
This patch introduces support for irqstats on imx processors again by
creating a sisr writeback mask and introducing a imx35-ssi compatible.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 39ad516..f37bcbe 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -127,6 +127,7 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
enum fsl_ssi_type {
FSL_SSI_MCP8610,
FSL_SSI_MX21,
+ FSL_SSI_MX35,
FSL_SSI_MX51,
};
@@ -151,6 +152,7 @@ struct fsl_ssi_private {
struct snd_soc_dai_driver cpu_dai_drv;
struct platform_device *pdev;
+ enum fsl_ssi_type hw_type;
bool new_binding;
bool ssi_on_imx;
bool imx_ac97;
@@ -199,6 +201,7 @@ struct fsl_ssi_private {
static const struct of_device_id fsl_ssi_ids[] = {
{ .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
{ .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
+ { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35},
{ .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21},
{}
};
@@ -222,7 +225,26 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
irqreturn_t ret = IRQ_NONE;
__be32 sisr;
- __be32 sisr2 = 0;
+ __be32 sisr2;
+ __be32 sisr_write_mask = 0;
+
+ switch (ssi_private->hw_type) {
+ case FSL_SSI_MX21:
+ sisr_write_mask = 0;
+ break;
+
+ case FSL_SSI_MCP8610:
+ case FSL_SSI_MX35:
+ sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
+ CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
+ CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
+ break;
+
+ case FSL_SSI_MX51:
+ sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
+ CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
+ break;
+ }
/* We got an interrupt, so read the status register to see what we
were interrupted for. We mask it with the Interrupt Enable register
@@ -232,13 +254,11 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
if (sisr & CCSR_SSI_SISR_RFRC) {
ssi_private->stats.rfrc++;
- sisr2 |= CCSR_SSI_SISR_RFRC;
ret = IRQ_HANDLED;
}
if (sisr & CCSR_SSI_SISR_TFRC) {
ssi_private->stats.tfrc++;
- sisr2 |= CCSR_SSI_SISR_TFRC;
ret = IRQ_HANDLED;
}
@@ -279,25 +299,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
if (sisr & CCSR_SSI_SISR_ROE1) {
ssi_private->stats.roe1++;
- sisr2 |= CCSR_SSI_SISR_ROE1;
ret = IRQ_HANDLED;
}
if (sisr & CCSR_SSI_SISR_ROE0) {
ssi_private->stats.roe0++;
- sisr2 |= CCSR_SSI_SISR_ROE0;
ret = IRQ_HANDLED;
}
if (sisr & CCSR_SSI_SISR_TUE1) {
ssi_private->stats.tue1++;
- sisr2 |= CCSR_SSI_SISR_TUE1;
ret = IRQ_HANDLED;
}
if (sisr & CCSR_SSI_SISR_TUE0) {
ssi_private->stats.tue0++;
- sisr2 |= CCSR_SSI_SISR_TUE0;
ret = IRQ_HANDLED;
}
@@ -341,6 +357,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
ret = IRQ_HANDLED;
}
+ sisr2 = sisr & sisr_write_mask;
/* Clear the bits that we set */
if (sisr2)
write_ssi(sisr2, &ssi->sisr);
@@ -1180,6 +1197,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->use_dma = !of_property_read_bool(np,
"fsl,fiq-stream-filter");
+ ssi_private->hw_type = hw_type;
if (ac97) {
memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
@@ -1298,7 +1316,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
- } else if (ssi_private->use_dma) {
+ }
+
+ /*
+ * Enable interrupts only for MCP8610 and MX51. The other MXs have
+ * different writeable interrupt status registers.
+ */
+ if (ssi_private->use_dma) {
/* The 'name' should not have any slashes in it. */
ret = devm_request_irq(&pdev->dev, ssi_private->irq,
fsl_ssi_isr, 0, ssi_private->name,
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 5/9] ASoC: fsl-ssi: Add offline_config flag
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (3 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 4/9] ASoC: fsl-ssi: Fix interrupt stats for imx Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 6/9] ASoC: fsl-ssi: Add configuration helper functions Markus Pargmann
` (4 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
imx50-ssi and later versions of this IP support online reconfiguration
of all registers. The reference manual does not list any registers that
can only be configured while the SSI unit is disabled. This patch
introduces the flag for later use.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f37bcbe..2f25525 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -159,6 +159,7 @@ struct fsl_ssi_private {
bool use_dma;
bool baudclk_locked;
bool irq_stats;
+ bool offline_config;
u8 i2s_mode;
spinlock_t baudclk_lock;
struct clk *baudclk;
@@ -1251,6 +1252,32 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ssi_private->baudclk_locked = false;
spin_lock_init(&ssi_private->baudclk_lock);
+ /*
+ * imx51 and later SoCs have a slightly different IP that allows the
+ * SSI configuration while the SSI unit is running.
+ *
+ * More important, it is necessary on those SoCs to configure the
+ * sperate TX/RX DMA bits just before starting the stream
+ * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
+ * sends any DMA requests to the SDMA unit, otherwise it is not defined
+ * how the SDMA unit handles the DMA request.
+ *
+ * SDMA units are present on devices starting at imx35 but the imx35
+ * reference manual states that the DMA bits should not be changed
+ * while the SSI unit is running (SSIEN). So we support the necessary
+ * online configuration of fsl-ssi starting at imx51.
+ */
+ switch (hw_type) {
+ case FSL_SSI_MCP8610:
+ case FSL_SSI_MX21:
+ case FSL_SSI_MX35:
+ ssi_private->offline_config = true;
+ break;
+ case FSL_SSI_MX51:
+ ssi_private->offline_config = false;
+ break;
+ }
+
if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
hw_type == FSL_SSI_MX35) {
u32 dma_events[2];
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 6/9] ASoC: fsl-ssi: Add configuration helper functions
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (4 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 5/9] ASoC: fsl-ssi: Add offline_config flag Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 7/9] ASoC: fsl-ssi: Move RX/TX configuration to seperate functions Markus Pargmann
` (3 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
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 2f25525..70bb466 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -131,6 +131,18 @@ enum fsl_ssi_type {
FSL_SSI_MX51,
};
+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
*
@@ -169,6 +181,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;
@@ -462,6 +476,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.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 7/9] ASoC: fsl-ssi: Move RX/TX configuration to seperate functions
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (5 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 6/9] ASoC: fsl-ssi: Add configuration helper functions Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 8/9] ASoC: fsl-ssi: Drop ac97 specific trigger function Markus Pargmann
` (2 subsequent siblings)
9 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
This patch defines the appropriate register values for different
oparation modes and IP versions. We have to handle DMA/FIQ, AC97,
DEBUG-IRQs and offline/online configuration support.
With this patch we cleanup some driver code that was not reference
manual conform and try to cleanup the whole trigger function to seperate
the actual register values from the enable/disable logic, which is now
hidden in fsl_ssi_config helpers.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 89 +++++++++++++++++++++++++------------------------
1 file changed, 46 insertions(+), 43 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 70bb466..c25f593 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -108,13 +108,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
#endif
-/* SIER bitflag of interrupts to enable */
-#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
- CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
- CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
- CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
- CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
-
#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
@@ -584,6 +577,41 @@ 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);
}
+/*
+ * Setup rx/tx register values used to enable/disable the streams. These will
+ * be used later in fsl_ssi_config to setup the streams without the need to
+ * check for all different SSI modes.
+ */
+static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
+{
+ struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
+
+ reg->rx.sier = CCSR_SSI_SIER_RFF0_EN;
+ reg->rx.srcr = CCSR_SSI_SRCR_RFEN0;
+ reg->rx.scr = 0;
+ reg->tx.sier = CCSR_SSI_SIER_TFE0_EN;
+ reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
+ reg->tx.scr = 0;
+
+ if (!ssi_private->imx_ac97) {
+ reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
+ reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
+ reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
+ reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN;
+ }
+
+ if (ssi_private->use_dma) {
+ reg->rx.sier |= CCSR_SSI_SIER_RDMAE;
+ reg->tx.sier |= CCSR_SSI_SIER_TDMAE;
+ } else {
+ reg->rx.sier |= CCSR_SSI_SIER_RIE;
+ reg->tx.sier |= CCSR_SSI_SIER_TIE;
+ }
+
+ reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS;
+ reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS;
+}
+
static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
{
struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -620,6 +648,8 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
u8 wm;
int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
+ fsl_ssi_setup_reg_vals(ssi_private);
+
if (ssi_private->imx_ac97)
ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
else
@@ -643,13 +673,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
ssi_private->i2s_mode |
(synchronous ? CCSR_SSI_SCR_SYN : 0));
- write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
- CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
- CCSR_SSI_STCR_TSCKP, &ssi->stcr);
+ write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
+ CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
+
+ write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI |
+ CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
- write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
- CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
- CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
/*
* The DC and PM bits are only used if the SSI is the clock master.
*/
@@ -1023,51 +1052,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
- unsigned int sier_bits;
unsigned long flags;
- /*
- * Enable only the interrupts and DMA requests
- * that are needed for the channel. As the fiq
- * is polling for this bits, we have to ensure
- * that this are aligned with the preallocated
- * buffers
- */
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (ssi_private->use_dma)
- sier_bits = SIER_FLAGS;
- else
- sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
- } else {
- if (ssi_private->use_dma)
- sier_bits = SIER_FLAGS;
- else
- sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
- }
-
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- write_ssi_mask(&ssi->scr, 0,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
+ fsl_ssi_tx_config(ssi_private, true);
else
- write_ssi_mask(&ssi->scr, 0,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
+ fsl_ssi_rx_config(ssi_private, true);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0);
+ fsl_ssi_tx_config(ssi_private, false);
else
- write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
+ fsl_ssi_rx_config(ssi_private, false);
if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
(CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
- write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
ssi_private->baudclk_locked = false;
spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -1078,7 +1082,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
return -EINVAL;
}
- write_ssi(sier_bits, &ssi->sier);
return 0;
}
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 8/9] ASoC: fsl-ssi: Drop ac97 specific trigger function
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (6 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 7/9] ASoC: fsl-ssi: Move RX/TX configuration to seperate functions Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2013-12-20 13:11 ` [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi Markus Pargmann
2014-01-08 17:21 ` [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Mark Brown
9 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
The normal trigger function can now be used for AC97. Drop AC97 trigger
function.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 61 +++++++------------------------------------------
1 file changed, 8 insertions(+), 53 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index c25f593..e40bce1 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1052,6 +1052,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+ struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
unsigned long flags;
switch (cmd) {
@@ -1082,6 +1083,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
return -EINVAL;
}
+ if (ssi_private->imx_ac97) {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
+ else
+ write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
+ }
return 0;
}
@@ -1129,58 +1136,6 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
.name = "fsl-ssi",
};
-/**
- * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
- *
- * This function is called by ALSA to start, stop, pause, and resume the
- * transfer of data.
- */
-static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
- rtd->cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
- CCSR_SSI_SIER_TFE0_EN);
- else
- write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
- CCSR_SSI_SIER_RFF0_EN);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
- CCSR_SSI_SIER_TFE0_EN, 0);
- else
- write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
- CCSR_SSI_SIER_RFF0_EN, 0);
- break;
-
- default:
- return -EINVAL;
- }
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
- else
- write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
-
- return 0;
-}
-
-static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
- .startup = fsl_ssi_startup,
- .trigger = fsl_ssi_ac97_trigger,
-};
-
static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
.ac97_control = 1,
.playback = {
@@ -1197,7 +1152,7 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
- .ops = &fsl_ssi_ac97_dai_ops,
+ .ops = &fsl_ssi_dai_ops,
};
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (7 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 8/9] ASoC: fsl-ssi: Drop ac97 specific trigger function Markus Pargmann
@ 2013-12-20 13:11 ` Markus Pargmann
2014-01-16 15:55 ` Markus Pargmann
2014-01-08 17:21 ` [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Mark Brown
9 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2013-12-20 13:11 UTC (permalink / raw)
To: linux-arm-kernel
imx51-ssi and imx21-ssi are different IPs. imx51-ssi supports online
reconfiguration and needs this for correct interaction with SDMA. This
patch adds imx51-ssi before each imx21-ssi for all imx5/imx6 SoCs.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
arch/arm/boot/dts/imx53.dtsi | 10 +++++++---
arch/arm/boot/dts/imx6qdl.dtsi | 12 +++++++++---
arch/arm/boot/dts/imx6sl.dtsi | 12 +++++++++---
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 4307e80..034b8b0 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -149,7 +149,9 @@
};
ssi2: ssi at 50014000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x50014000 0x4000>;
interrupts = <30>;
clocks = <&clks 49>;
@@ -1049,7 +1051,8 @@
};
ssi1: ssi at 63fcc000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x63fcc000 0x4000>;
interrupts = <29>;
clocks = <&clks 48>;
@@ -1076,7 +1079,8 @@
};
ssi3: ssi at 63fe8000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x63fe8000 0x4000>;
interrupts = <96>;
clocks = <&clks 50>;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 59154dc..c51440b 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -232,7 +232,9 @@
};
ssi1: ssi at 02028000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
clocks = <&clks 178>;
@@ -245,7 +247,9 @@
};
ssi2: ssi at 0202c000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
clocks = <&clks 179>;
@@ -258,7 +262,9 @@
};
ssi3: ssi at 02030000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
clocks = <&clks 180>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 28558f1..1e7b712 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -195,7 +195,9 @@
};
ssi1: ssi at 02028000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
clocks = <&clks IMX6SL_CLK_SSI1>;
@@ -207,7 +209,9 @@
};
ssi2: ssi at 0202c000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
clocks = <&clks IMX6SL_CLK_SSI2>;
@@ -219,7 +223,9 @@
};
ssi3: ssi at 02030000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
clocks = <&clks IMX6SL_CLK_SSI3>;
--
1.8.5.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi
2013-12-20 13:11 ` [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi Markus Pargmann
@ 2014-01-16 15:55 ` Markus Pargmann
2014-01-17 5:32 ` Shawn Guo
0 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2014-01-16 15:55 UTC (permalink / raw)
To: linux-arm-kernel
Hi Shawn,
On Fri, Dec 20, 2013 at 02:11:36PM +0100, Markus Pargmann wrote:
> imx51-ssi and imx21-ssi are different IPs. imx51-ssi supports online
> reconfiguration and needs this for correct interaction with SDMA. This
> patch adds imx51-ssi before each imx21-ssi for all imx5/imx6 SoCs.
>
Mark Brown applied all other patches of this series. Could you please
take this one?
Thanks,
Markus
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi
2014-01-16 15:55 ` Markus Pargmann
@ 2014-01-17 5:32 ` Shawn Guo
0 siblings, 0 replies; 21+ messages in thread
From: Shawn Guo @ 2014-01-17 5:32 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jan 16, 2014 at 04:55:14PM +0100, Markus Pargmann wrote:
> Hi Shawn,
>
> On Fri, Dec 20, 2013 at 02:11:36PM +0100, Markus Pargmann wrote:
> > imx51-ssi and imx21-ssi are different IPs. imx51-ssi supports online
> > reconfiguration and needs this for correct interaction with SDMA. This
> > patch adds imx51-ssi before each imx21-ssi for all imx5/imx6 SoCs.
> >
>
> Mark Brown applied all other patches of this series. Could you please
> take this one?
Can you please regenerate the patch against my for-next branch to get
imx50 SSI nodes covered as well?
Shawn
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups
2013-12-20 13:11 [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Markus Pargmann
` (8 preceding siblings ...)
2013-12-20 13:11 ` [PATCH v4 9/9] ARM: DTS: imx5* imx6*, use imx51-ssi Markus Pargmann
@ 2014-01-08 17:21 ` Mark Brown
2014-01-09 10:16 ` [PATCH 0/2] fsl-ssi fixups Markus Pargmann
9 siblings, 1 reply; 21+ messages in thread
From: Mark Brown @ 2014-01-08 17:21 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Dec 20, 2013 at 02:11:27PM +0100, Markus Pargmann wrote:
> Hi,
>
> This patch series fixes some fsl-ssi code that does not act exactly as it is
> described in the reference manuals.
I went ahead and applied all of the ASoC patches here however as I noted
on a couple of patches the new compatible strings need documenting. Can
you please send a followup patch adding that?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140108/9b888b58/attachment.sig>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 0/2] fsl-ssi fixups
2014-01-08 17:21 ` [PATCH v4 0/9] ASoC: fsl-ssi: offline/online configuration and cleanups Mark Brown
@ 2014-01-09 10:16 ` Markus Pargmann
2014-01-09 10:16 ` [PATCH 1/2] ASoC: fsl-ssi doc: Add list of supported compatibles Markus Pargmann
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Markus Pargmann @ 2014-01-09 10:16 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Thanks, here are the two fixups for the series. The binding documentation did
not contain a list of compatibles yet, so I added it.
Regards,
Markus
Markus Pargmann (2):
ASoC: fsl-ssi doc: Add list of supported compatibles
ASoC: fsl-ssi: Fix stats compile warning
Documentation/devicetree/bindings/sound/fsl,ssi.txt | 7 ++++++-
sound/soc/fsl/fsl_ssi.c | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
--
1.8.5.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/2] ASoC: fsl-ssi doc: Add list of supported compatibles
2014-01-09 10:16 ` [PATCH 0/2] fsl-ssi fixups Markus Pargmann
@ 2014-01-09 10:16 ` Markus Pargmann
2014-01-09 10:16 ` [PATCH 2/2] ASoC: fsl-ssi: Fix stats compile warning Markus Pargmann
2014-01-09 13:55 ` [PATCH 0/2] fsl-ssi fixups Mark Brown
2 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2014-01-09 10:16 UTC (permalink / raw)
To: linux-arm-kernel
There is no list of compatibles that are supported. This patch adds a
list of compatibles to the documentation.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
Documentation/devicetree/bindings/sound/fsl,ssi.txt | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
index 4303b6a..b93e9a9 100644
--- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt
@@ -4,7 +4,12 @@ The SSI is a serial device that communicates with audio codecs. It can
be programmed in AC97, I2S, left-justified, or right-justified modes.
Required properties:
-- compatible: Compatible list, contains "fsl,ssi".
+- compatible: Compatible list, should contain one of the following
+ compatibles:
+ fsl,mpc8610-ssi
+ fsl,imx51-ssi
+ fsl,imx35-ssi
+ fsl,imx21-ssi
- cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on.
- reg: Offset and length of the register set for the device.
- interrupts: <a b> where a is the interrupt number and b is a
--
1.8.5.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/2] ASoC: fsl-ssi: Fix stats compile warning
2014-01-09 10:16 ` [PATCH 0/2] fsl-ssi fixups Markus Pargmann
2014-01-09 10:16 ` [PATCH 1/2] ASoC: fsl-ssi doc: Add list of supported compatibles Markus Pargmann
@ 2014-01-09 10:16 ` Markus Pargmann
2014-01-09 13:55 ` [PATCH 0/2] fsl-ssi fixups Mark Brown
2 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2014-01-09 10:16 UTC (permalink / raw)
To: linux-arm-kernel
single_open requires a function with signature
'int (*)(struct seq_file *, void *)'. This patch fixes the warning by
fixing the wrong return type of fsl_ssi_stats_show.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
sound/soc/fsl/fsl_ssi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index e40bce1..cb4c2e0 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -391,7 +391,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
* Display the statistics for the current SSI device. To avoid confusion,
* we only show those counts that are enabled.
*/
-static ssize_t fsl_ssi_stats_show(struct seq_file *s, void *unused)
+static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
{
struct fsl_ssi_private *ssi_private = s->private;
--
1.8.5.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 0/2] fsl-ssi fixups
2014-01-09 10:16 ` [PATCH 0/2] fsl-ssi fixups Markus Pargmann
2014-01-09 10:16 ` [PATCH 1/2] ASoC: fsl-ssi doc: Add list of supported compatibles Markus Pargmann
2014-01-09 10:16 ` [PATCH 2/2] ASoC: fsl-ssi: Fix stats compile warning Markus Pargmann
@ 2014-01-09 13:55 ` Mark Brown
2 siblings, 0 replies; 21+ messages in thread
From: Mark Brown @ 2014-01-09 13:55 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jan 09, 2014 at 11:16:09AM +0100, Markus Pargmann wrote:
> Hi,
>
> Thanks, here are the two fixups for the series. The binding documentation did
> not contain a list of compatibles yet, so I added it.
Applied both, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140109/dec1c2c7/attachment.sig>
^ permalink raw reply [flat|nested] 21+ messages in thread