diff options
| -rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 671be33aa9d2..bc904696d820 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) | |||
| 127 | enum fsl_ssi_type { | 127 | enum fsl_ssi_type { |
| 128 | FSL_SSI_MCP8610, | 128 | FSL_SSI_MCP8610, |
| 129 | FSL_SSI_MX21, | 129 | FSL_SSI_MX21, |
| 130 | FSL_SSI_MX35, | ||
| 130 | FSL_SSI_MX51, | 131 | FSL_SSI_MX51, |
| 131 | }; | 132 | }; |
| 132 | 133 | ||
| @@ -151,6 +152,7 @@ struct fsl_ssi_private { | |||
| 151 | struct snd_soc_dai_driver cpu_dai_drv; | 152 | struct snd_soc_dai_driver cpu_dai_drv; |
| 152 | struct platform_device *pdev; | 153 | struct platform_device *pdev; |
| 153 | 154 | ||
| 155 | enum fsl_ssi_type hw_type; | ||
| 154 | bool new_binding; | 156 | bool new_binding; |
| 155 | bool ssi_on_imx; | 157 | bool ssi_on_imx; |
| 156 | bool imx_ac97; | 158 | bool imx_ac97; |
| @@ -199,6 +201,7 @@ struct fsl_ssi_private { | |||
| 199 | static const struct of_device_id fsl_ssi_ids[] = { | 201 | static const struct of_device_id fsl_ssi_ids[] = { |
| 200 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, | 202 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, |
| 201 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, | 203 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, |
| 204 | { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35}, | ||
| 202 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, | 205 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, |
| 203 | {} | 206 | {} |
| 204 | }; | 207 | }; |
| @@ -222,7 +225,26 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
| 222 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 225 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
| 223 | irqreturn_t ret = IRQ_NONE; | 226 | irqreturn_t ret = IRQ_NONE; |
| 224 | __be32 sisr; | 227 | __be32 sisr; |
| 225 | __be32 sisr2 = 0; | 228 | __be32 sisr2; |
| 229 | __be32 sisr_write_mask = 0; | ||
| 230 | |||
| 231 | switch (ssi_private->hw_type) { | ||
| 232 | case FSL_SSI_MX21: | ||
| 233 | sisr_write_mask = 0; | ||
| 234 | break; | ||
| 235 | |||
| 236 | case FSL_SSI_MCP8610: | ||
| 237 | case FSL_SSI_MX35: | ||
| 238 | sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | ||
| 239 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
| 240 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
| 241 | break; | ||
| 242 | |||
| 243 | case FSL_SSI_MX51: | ||
| 244 | sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
| 245 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
| 246 | break; | ||
| 247 | } | ||
| 226 | 248 | ||
| 227 | /* We got an interrupt, so read the status register to see what we | 249 | /* We got an interrupt, so read the status register to see what we |
| 228 | were interrupted for. We mask it with the Interrupt Enable register | 250 | 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) | |||
| 232 | 254 | ||
| 233 | if (sisr & CCSR_SSI_SISR_RFRC) { | 255 | if (sisr & CCSR_SSI_SISR_RFRC) { |
| 234 | ssi_private->stats.rfrc++; | 256 | ssi_private->stats.rfrc++; |
| 235 | sisr2 |= CCSR_SSI_SISR_RFRC; | ||
| 236 | ret = IRQ_HANDLED; | 257 | ret = IRQ_HANDLED; |
| 237 | } | 258 | } |
| 238 | 259 | ||
| 239 | if (sisr & CCSR_SSI_SISR_TFRC) { | 260 | if (sisr & CCSR_SSI_SISR_TFRC) { |
| 240 | ssi_private->stats.tfrc++; | 261 | ssi_private->stats.tfrc++; |
| 241 | sisr2 |= CCSR_SSI_SISR_TFRC; | ||
| 242 | ret = IRQ_HANDLED; | 262 | ret = IRQ_HANDLED; |
| 243 | } | 263 | } |
| 244 | 264 | ||
| @@ -279,25 +299,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
| 279 | 299 | ||
| 280 | if (sisr & CCSR_SSI_SISR_ROE1) { | 300 | if (sisr & CCSR_SSI_SISR_ROE1) { |
| 281 | ssi_private->stats.roe1++; | 301 | ssi_private->stats.roe1++; |
| 282 | sisr2 |= CCSR_SSI_SISR_ROE1; | ||
| 283 | ret = IRQ_HANDLED; | 302 | ret = IRQ_HANDLED; |
| 284 | } | 303 | } |
| 285 | 304 | ||
| 286 | if (sisr & CCSR_SSI_SISR_ROE0) { | 305 | if (sisr & CCSR_SSI_SISR_ROE0) { |
| 287 | ssi_private->stats.roe0++; | 306 | ssi_private->stats.roe0++; |
| 288 | sisr2 |= CCSR_SSI_SISR_ROE0; | ||
| 289 | ret = IRQ_HANDLED; | 307 | ret = IRQ_HANDLED; |
| 290 | } | 308 | } |
| 291 | 309 | ||
| 292 | if (sisr & CCSR_SSI_SISR_TUE1) { | 310 | if (sisr & CCSR_SSI_SISR_TUE1) { |
| 293 | ssi_private->stats.tue1++; | 311 | ssi_private->stats.tue1++; |
| 294 | sisr2 |= CCSR_SSI_SISR_TUE1; | ||
| 295 | ret = IRQ_HANDLED; | 312 | ret = IRQ_HANDLED; |
| 296 | } | 313 | } |
| 297 | 314 | ||
| 298 | if (sisr & CCSR_SSI_SISR_TUE0) { | 315 | if (sisr & CCSR_SSI_SISR_TUE0) { |
| 299 | ssi_private->stats.tue0++; | 316 | ssi_private->stats.tue0++; |
| 300 | sisr2 |= CCSR_SSI_SISR_TUE0; | ||
| 301 | ret = IRQ_HANDLED; | 317 | ret = IRQ_HANDLED; |
| 302 | } | 318 | } |
| 303 | 319 | ||
| @@ -341,6 +357,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
| 341 | ret = IRQ_HANDLED; | 357 | ret = IRQ_HANDLED; |
| 342 | } | 358 | } |
| 343 | 359 | ||
| 360 | sisr2 = sisr & sisr_write_mask; | ||
| 344 | /* Clear the bits that we set */ | 361 | /* Clear the bits that we set */ |
| 345 | if (sisr2) | 362 | if (sisr2) |
| 346 | write_ssi(sisr2, &ssi->sisr); | 363 | write_ssi(sisr2, &ssi->sisr); |
| @@ -1180,6 +1197,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
| 1180 | 1197 | ||
| 1181 | ssi_private->use_dma = !of_property_read_bool(np, | 1198 | ssi_private->use_dma = !of_property_read_bool(np, |
| 1182 | "fsl,fiq-stream-filter"); | 1199 | "fsl,fiq-stream-filter"); |
| 1200 | ssi_private->hw_type = hw_type; | ||
| 1183 | 1201 | ||
| 1184 | if (ac97) { | 1202 | if (ac97) { |
| 1185 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, | 1203 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, |
| @@ -1299,7 +1317,13 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
| 1299 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1317 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); |
| 1300 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, | 1318 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, |
| 1301 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1319 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); |
| 1302 | } else if (ssi_private->use_dma) { | 1320 | } |
| 1321 | |||
| 1322 | /* | ||
| 1323 | * Enable interrupts only for MCP8610 and MX51. The other MXs have | ||
| 1324 | * different writeable interrupt status registers. | ||
| 1325 | */ | ||
| 1326 | if (ssi_private->use_dma) { | ||
| 1303 | /* The 'name' should not have any slashes in it. */ | 1327 | /* The 'name' should not have any slashes in it. */ |
| 1304 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, | 1328 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, |
| 1305 | fsl_ssi_isr, 0, ssi_private->name, | 1329 | fsl_ssi_isr, 0, ssi_private->name, |
