summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-05-27 10:24:18 +0200
committerMark Brown <broonie@linaro.org>2014-06-01 12:55:07 +0200
commitfcdbadef378bc9cc64cb8cbfd96c23fc15812923 (patch)
tree8653171ca7facc25a719939a3392dfb4c8f21bf5 /sound
parentASoC: fsl_ssi: Add suspend/resume support (diff)
downloadlinux-fcdbadef378bc9cc64cb8cbfd96c23fc15812923.tar.xz
linux-fcdbadef378bc9cc64cb8cbfd96c23fc15812923.zip
ASoC: fsl-ssi: introduce SoC specific data
Introduce a SoC data struct which contains the differences between the different SoCs this driver supports. This makes it easy to support more differences without having to introduce a new switch/case each time. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Markus Pargmann <mpa@pengutronix.de> Tested-By: Michael Grzeschik <mgr@pengutronix.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_ssi.c125
1 files changed, 57 insertions, 68 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index ef504257e105..fa650112925a 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -132,6 +132,12 @@ struct fsl_ssi_rxtx_reg_val {
struct fsl_ssi_reg_val tx;
};
+struct fsl_ssi_soc_data {
+ bool imx;
+ bool offline_config;
+ u32 sisr_write_mask;
+};
+
/**
* fsl_ssi_private: per-SSI private data
*
@@ -153,7 +159,6 @@ struct fsl_ssi_private {
struct platform_device *pdev;
unsigned int dai_fmt;
- enum fsl_ssi_type hw_type;
bool use_dma;
bool baudclk_locked;
bool use_dual_fifo;
@@ -168,35 +173,9 @@ struct fsl_ssi_private {
struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
struct fsl_ssi_dbg dbg_stats;
-};
-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},
- {}
+ const struct fsl_ssi_soc_data *soc;
};
-MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
-
-static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
-{
- return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
-}
-
-static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private)
-{
- switch (ssi_private->hw_type) {
- case FSL_SSI_MX21:
- case FSL_SSI_MX35:
- case FSL_SSI_MX51:
- return true;
- case FSL_SSI_MCP8610:
- return false;
- }
-
- return false;
-}
/*
* imx51 and later SoCs have a slightly different IP that allows the
@@ -213,18 +192,48 @@ static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private)
* while the SSI unit is running (SSIEN). So we support the necessary
* online configuration of fsl-ssi starting at imx51.
*/
-static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private)
-{
- switch (ssi_private->hw_type) {
- case FSL_SSI_MCP8610:
- case FSL_SSI_MX21:
- case FSL_SSI_MX35:
- return true;
- case FSL_SSI_MX51:
- return false;
- }
- return true;
+static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
+ .imx = false,
+ .offline_config = true,
+ .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,
+};
+
+static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
+ .imx = true,
+ .offline_config = true,
+ .sisr_write_mask = 0,
+};
+
+static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
+ .imx = true,
+ .offline_config = true,
+ .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,
+};
+
+static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
+ .imx = true,
+ .offline_config = false,
+ .sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
+ CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
+};
+
+static const struct of_device_id fsl_ssi_ids[] = {
+ { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 },
+ { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 },
+ { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 },
+ { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 },
+ {}
+};
+MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
+
+static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
+{
+ return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
}
/**
@@ -245,25 +254,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
__be32 sisr;
__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
@@ -271,7 +261,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
*/
sisr = read_ssi(&ssi->sisr);
- sisr2 = sisr & sisr_write_mask;
+ sisr2 = sisr & ssi_private->soc->sisr_write_mask;
/* Clear the bits that we set */
if (sisr2)
write_ssi(sisr2, &ssi->sisr);
@@ -359,7 +349,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
* reconfiguration, so we have to enable all necessary flags at once
* even if we do not use them later (capture and playback configuration)
*/
- if (fsl_ssi_offline_config(ssi_private)) {
+ if (ssi_private->soc->offline_config) {
if ((enable && !nr_active_streams) ||
(!enable && !keep_active))
fsl_ssi_rxtx_config(ssi_private, enable);
@@ -915,7 +905,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
{
struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
- if (fsl_ssi_on_imx(ssi_private) && ssi_private->use_dma) {
+ if (ssi_private->soc->imx && ssi_private->use_dma) {
dai->playback_dma_data = &ssi_private->dma_params_tx;
dai->capture_dma_data = &ssi_private->dma_params_rx;
}
@@ -1141,7 +1131,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
int ret = 0;
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;
@@ -1156,9 +1145,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
return -ENODEV;
of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
- if (!of_id)
+ if (!of_id || !of_id->data)
return -EINVAL;
- hw_type = (enum fsl_ssi_type) of_id->data;
sprop = of_get_property(np, "fsl,mode", NULL);
if (!sprop) {
@@ -1175,9 +1163,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ ssi_private->soc = of_id->data;
+
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,
@@ -1232,7 +1221,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, ssi_private);
- if (fsl_ssi_on_imx(ssi_private)) {
+ if (ssi_private->soc->imx) {
ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi);
if (ret)
goto error_irqmap;
@@ -1299,7 +1288,7 @@ error_irq:
snd_soc_unregister_component(&pdev->dev);
error_asoc_register:
- if (fsl_ssi_on_imx(ssi_private))
+ if (ssi_private->soc->imx)
fsl_ssi_imx_clean(pdev, ssi_private);
error_irqmap:
@@ -1319,7 +1308,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
platform_device_unregister(ssi_private->pdev);
snd_soc_unregister_component(&pdev->dev);
- if (fsl_ssi_on_imx(ssi_private))
+ if (ssi_private->soc->imx)
fsl_ssi_imx_clean(pdev, ssi_private);
if (ssi_private->use_dma)