diff options
author | Markus Pargmann <mpa@pengutronix.de> | 2013-12-20 08:11:30 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-08 12:20:31 -0500 |
commit | c1953bfe1329eeb16991d430d574c4280697ad17 (patch) | |
tree | af82981e9e83987c2528bb0e389124d25edffc8c /sound/soc/fsl | |
parent | 9368acc4383bd8cca671fdc49c5f7e241b6909b3 (diff) |
ASoC: fsl-ssi: Add imx51-ssi and of_device_id matching
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>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index e483e9d84f8b..671be33aa9d2 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) | |||
123 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) | 123 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) |
124 | #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) | 124 | #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) |
125 | 125 | ||
126 | |||
127 | enum fsl_ssi_type { | ||
128 | FSL_SSI_MCP8610, | ||
129 | FSL_SSI_MX21, | ||
130 | FSL_SSI_MX51, | ||
131 | }; | ||
132 | |||
126 | /** | 133 | /** |
127 | * fsl_ssi_private: per-SSI private data | 134 | * fsl_ssi_private: per-SSI private data |
128 | * | 135 | * |
@@ -189,6 +196,14 @@ struct fsl_ssi_private { | |||
189 | char name[1]; | 196 | char name[1]; |
190 | }; | 197 | }; |
191 | 198 | ||
199 | static const struct of_device_id fsl_ssi_ids[] = { | ||
200 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, | ||
201 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, | ||
202 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, | ||
203 | {} | ||
204 | }; | ||
205 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | ||
206 | |||
192 | /** | 207 | /** |
193 | * fsl_ssi_isr: SSI interrupt handler | 208 | * fsl_ssi_isr: SSI interrupt handler |
194 | * | 209 | * |
@@ -1118,6 +1133,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1118 | int ret = 0; | 1133 | int ret = 0; |
1119 | struct device_attribute *dev_attr = NULL; | 1134 | struct device_attribute *dev_attr = NULL; |
1120 | struct device_node *np = pdev->dev.of_node; | 1135 | struct device_node *np = pdev->dev.of_node; |
1136 | const struct of_device_id *of_id; | ||
1137 | enum fsl_ssi_type hw_type; | ||
1121 | const char *p, *sprop; | 1138 | const char *p, *sprop; |
1122 | const uint32_t *iprop; | 1139 | const uint32_t *iprop; |
1123 | struct resource res; | 1140 | struct resource res; |
@@ -1132,6 +1149,11 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1132 | if (!of_device_is_available(np)) | 1149 | if (!of_device_is_available(np)) |
1133 | return -ENODEV; | 1150 | return -ENODEV; |
1134 | 1151 | ||
1152 | of_id = of_match_device(fsl_ssi_ids, &pdev->dev); | ||
1153 | if (!of_id) | ||
1154 | return -EINVAL; | ||
1155 | hw_type = (enum fsl_ssi_type) of_id->data; | ||
1156 | |||
1135 | /* We only support the SSI in "I2S Slave" mode */ | 1157 | /* We only support the SSI in "I2S Slave" mode */ |
1136 | sprop = of_get_property(np, "fsl,mode", NULL); | 1158 | sprop = of_get_property(np, "fsl,mode", NULL); |
1137 | if (!sprop) { | 1159 | if (!sprop) { |
@@ -1211,7 +1233,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1211 | ssi_private->baudclk_locked = false; | 1233 | ssi_private->baudclk_locked = false; |
1212 | spin_lock_init(&ssi_private->baudclk_lock); | 1234 | spin_lock_init(&ssi_private->baudclk_lock); |
1213 | 1235 | ||
1214 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { | 1236 | if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 || |
1237 | hw_type == FSL_SSI_MX35) { | ||
1215 | u32 dma_events[2]; | 1238 | u32 dma_events[2]; |
1216 | ssi_private->ssi_on_imx = true; | 1239 | ssi_private->ssi_on_imx = true; |
1217 | 1240 | ||
@@ -1414,13 +1437,6 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1414 | return 0; | 1437 | return 0; |
1415 | } | 1438 | } |
1416 | 1439 | ||
1417 | static const struct of_device_id fsl_ssi_ids[] = { | ||
1418 | { .compatible = "fsl,mpc8610-ssi", }, | ||
1419 | { .compatible = "fsl,imx21-ssi", }, | ||
1420 | {} | ||
1421 | }; | ||
1422 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | ||
1423 | |||
1424 | static struct platform_driver fsl_ssi_driver = { | 1440 | static struct platform_driver fsl_ssi_driver = { |
1425 | .driver = { | 1441 | .driver = { |
1426 | .name = "fsl-ssi-dai", | 1442 | .name = "fsl-ssi-dai", |