aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-05-27 04:24:18 -0400
committerMark Brown <broonie@linaro.org>2014-06-01 06:55:07 -0400
commitfcdbadef378bc9cc64cb8cbfd96c23fc15812923 (patch)
tree8653171ca7facc25a719939a3392dfb4c8f21bf5 /sound/soc/fsl
parentb20e53a826a7adc3bfd2772bd49a83b6f21b4cce (diff)
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/soc/fsl')
-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 {
132 struct fsl_ssi_reg_val tx; 132 struct fsl_ssi_reg_val tx;
133}; 133};
134 134
135struct fsl_ssi_soc_data {
136 bool imx;
137 bool offline_config;
138 u32 sisr_write_mask;
139};
140
135/** 141/**
136 * fsl_ssi_private: per-SSI private data 142 * fsl_ssi_private: per-SSI private data
137 * 143 *
@@ -153,7 +159,6 @@ struct fsl_ssi_private {
153 struct platform_device *pdev; 159 struct platform_device *pdev;
154 unsigned int dai_fmt; 160 unsigned int dai_fmt;
155 161
156 enum fsl_ssi_type hw_type;
157 bool use_dma; 162 bool use_dma;
158 bool baudclk_locked; 163 bool baudclk_locked;
159 bool use_dual_fifo; 164 bool use_dual_fifo;
@@ -168,35 +173,9 @@ struct fsl_ssi_private {
168 struct fsl_ssi_rxtx_reg_val rxtx_reg_val; 173 struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
169 174
170 struct fsl_ssi_dbg dbg_stats; 175 struct fsl_ssi_dbg dbg_stats;
171};
172 176
173static const struct of_device_id fsl_ssi_ids[] = { 177 const struct fsl_ssi_soc_data *soc;
174 { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
175 { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
176 { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35},
177 { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21},
178 {}
179}; 178};
180MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
181
182static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
183{
184 return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
185}
186
187static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private)
188{
189 switch (ssi_private->hw_type) {
190 case FSL_SSI_MX21:
191 case FSL_SSI_MX35:
192 case FSL_SSI_MX51:
193 return true;
194 case FSL_SSI_MCP8610:
195 return false;
196 }
197
198 return false;
199}
200 179
201/* 180/*
202 * imx51 and later SoCs have a slightly different IP that allows the 181 * 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)
213 * while the SSI unit is running (SSIEN). So we support the necessary 192 * while the SSI unit is running (SSIEN). So we support the necessary
214 * online configuration of fsl-ssi starting at imx51. 193 * online configuration of fsl-ssi starting at imx51.
215 */ 194 */
216static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private)
217{
218 switch (ssi_private->hw_type) {
219 case FSL_SSI_MCP8610:
220 case FSL_SSI_MX21:
221 case FSL_SSI_MX35:
222 return true;
223 case FSL_SSI_MX51:
224 return false;
225 }
226 195
227 return true; 196static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
197 .imx = false,
198 .offline_config = true,
199 .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
200 CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
201 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
202};
203
204static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
205 .imx = true,
206 .offline_config = true,
207 .sisr_write_mask = 0,
208};
209
210static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
211 .imx = true,
212 .offline_config = true,
213 .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
214 CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
215 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
216};
217
218static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
219 .imx = true,
220 .offline_config = false,
221 .sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
222 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
223};
224
225static const struct of_device_id fsl_ssi_ids[] = {
226 { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 },
227 { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 },
228 { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 },
229 { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 },
230 {}
231};
232MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
233
234static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
235{
236 return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
228} 237}
229 238
230/** 239/**
@@ -245,25 +254,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
245 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 254 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
246 __be32 sisr; 255 __be32 sisr;
247 __be32 sisr2; 256 __be32 sisr2;
248 __be32 sisr_write_mask = 0;
249
250 switch (ssi_private->hw_type) {
251 case FSL_SSI_MX21:
252 sisr_write_mask = 0;
253 break;
254
255 case FSL_SSI_MCP8610:
256 case FSL_SSI_MX35:
257 sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
258 CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
259 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
260 break;
261
262 case FSL_SSI_MX51:
263 sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
264 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
265 break;
266 }
267 257
268 /* We got an interrupt, so read the status register to see what we 258 /* We got an interrupt, so read the status register to see what we
269 were interrupted for. We mask it with the Interrupt Enable register 259 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)
271 */ 261 */
272 sisr = read_ssi(&ssi->sisr); 262 sisr = read_ssi(&ssi->sisr);
273 263
274 sisr2 = sisr & sisr_write_mask; 264 sisr2 = sisr & ssi_private->soc->sisr_write_mask;
275 /* Clear the bits that we set */ 265 /* Clear the bits that we set */
276 if (sisr2) 266 if (sisr2)
277 write_ssi(sisr2, &ssi->sisr); 267 write_ssi(sisr2, &ssi->sisr);
@@ -359,7 +349,7 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
359 * reconfiguration, so we have to enable all necessary flags at once 349 * reconfiguration, so we have to enable all necessary flags at once
360 * even if we do not use them later (capture and playback configuration) 350 * even if we do not use them later (capture and playback configuration)
361 */ 351 */
362 if (fsl_ssi_offline_config(ssi_private)) { 352 if (ssi_private->soc->offline_config) {
363 if ((enable && !nr_active_streams) || 353 if ((enable && !nr_active_streams) ||
364 (!enable && !keep_active)) 354 (!enable && !keep_active))
365 fsl_ssi_rxtx_config(ssi_private, enable); 355 fsl_ssi_rxtx_config(ssi_private, enable);
@@ -915,7 +905,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
915{ 905{
916 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); 906 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
917 907
918 if (fsl_ssi_on_imx(ssi_private) && ssi_private->use_dma) { 908 if (ssi_private->soc->imx && ssi_private->use_dma) {
919 dai->playback_dma_data = &ssi_private->dma_params_tx; 909 dai->playback_dma_data = &ssi_private->dma_params_tx;
920 dai->capture_dma_data = &ssi_private->dma_params_rx; 910 dai->capture_dma_data = &ssi_private->dma_params_rx;
921 } 911 }
@@ -1141,7 +1131,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1141 int ret = 0; 1131 int ret = 0;
1142 struct device_node *np = pdev->dev.of_node; 1132 struct device_node *np = pdev->dev.of_node;
1143 const struct of_device_id *of_id; 1133 const struct of_device_id *of_id;
1144 enum fsl_ssi_type hw_type;
1145 const char *p, *sprop; 1134 const char *p, *sprop;
1146 const uint32_t *iprop; 1135 const uint32_t *iprop;
1147 struct resource res; 1136 struct resource res;
@@ -1156,9 +1145,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1156 return -ENODEV; 1145 return -ENODEV;
1157 1146
1158 of_id = of_match_device(fsl_ssi_ids, &pdev->dev); 1147 of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
1159 if (!of_id) 1148 if (!of_id || !of_id->data)
1160 return -EINVAL; 1149 return -EINVAL;
1161 hw_type = (enum fsl_ssi_type) of_id->data;
1162 1150
1163 sprop = of_get_property(np, "fsl,mode", NULL); 1151 sprop = of_get_property(np, "fsl,mode", NULL);
1164 if (!sprop) { 1152 if (!sprop) {
@@ -1175,9 +1163,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1175 return -ENOMEM; 1163 return -ENOMEM;
1176 } 1164 }
1177 1165
1166 ssi_private->soc = of_id->data;
1167
1178 ssi_private->use_dma = !of_property_read_bool(np, 1168 ssi_private->use_dma = !of_property_read_bool(np,
1179 "fsl,fiq-stream-filter"); 1169 "fsl,fiq-stream-filter");
1180 ssi_private->hw_type = hw_type;
1181 1170
1182 if (ac97) { 1171 if (ac97) {
1183 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, 1172 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
@@ -1232,7 +1221,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1232 1221
1233 dev_set_drvdata(&pdev->dev, ssi_private); 1222 dev_set_drvdata(&pdev->dev, ssi_private);
1234 1223
1235 if (fsl_ssi_on_imx(ssi_private)) { 1224 if (ssi_private->soc->imx) {
1236 ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi); 1225 ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi);
1237 if (ret) 1226 if (ret)
1238 goto error_irqmap; 1227 goto error_irqmap;
@@ -1299,7 +1288,7 @@ error_irq:
1299 snd_soc_unregister_component(&pdev->dev); 1288 snd_soc_unregister_component(&pdev->dev);
1300 1289
1301error_asoc_register: 1290error_asoc_register:
1302 if (fsl_ssi_on_imx(ssi_private)) 1291 if (ssi_private->soc->imx)
1303 fsl_ssi_imx_clean(pdev, ssi_private); 1292 fsl_ssi_imx_clean(pdev, ssi_private);
1304 1293
1305error_irqmap: 1294error_irqmap:
@@ -1319,7 +1308,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1319 platform_device_unregister(ssi_private->pdev); 1308 platform_device_unregister(ssi_private->pdev);
1320 snd_soc_unregister_component(&pdev->dev); 1309 snd_soc_unregister_component(&pdev->dev);
1321 1310
1322 if (fsl_ssi_on_imx(ssi_private)) 1311 if (ssi_private->soc->imx)
1323 fsl_ssi_imx_clean(pdev, ssi_private); 1312 fsl_ssi_imx_clean(pdev, ssi_private);
1324 1313
1325 if (ssi_private->use_dma) 1314 if (ssi_private->use_dma)