]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - sound/soc/fsl/fsl_ssi.c
ASoC: fsl-ssi: introduce SoC specific data
[karo-tx-linux.git] / sound / soc / fsl / fsl_ssi.c
index ef504257e10598357055adc8659d834eb4f1aa7e..fa650112925a07e1e39af1a919a4f6f528fb1360 100644 (file)
@@ -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)