| OLD | NEW |
| 1 /* | 1 /* |
| 2 * omap-mcbsp.c -- OMAP ALSA SoC DAI driver using McBSP port | 2 * omap-mcbsp.c -- OMAP ALSA SoC DAI driver using McBSP port |
| 3 * | 3 * |
| 4 * Copyright (C) 2008 Nokia Corporation | 4 * Copyright (C) 2008 Nokia Corporation |
| 5 * | 5 * |
| 6 * Contact: Jarkko Nikula <jhnikula@gmail.com> | 6 * Contact: Jarkko Nikula <jhnikula@gmail.com> |
| 7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> | 7 * Peter Ujfalusi <peter.ujfalusi@nokia.com> |
| 8 * | 8 * |
| 9 * This program is free software; you can redistribute it and/or | 9 * This program is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU General Public License | 10 * modify it under the terms of the GNU General Public License |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 95 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) |
| 96 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, | 96 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, |
| 97 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, | 97 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, |
| 98 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, | 98 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, |
| 99 #endif | 99 #endif |
| 100 }; | 100 }; |
| 101 #else | 101 #else |
| 102 static const int omap24xx_dma_reqs[][2] = {}; | 102 static const int omap24xx_dma_reqs[][2] = {}; |
| 103 #endif | 103 #endif |
| 104 | 104 |
| 105 #if defined(CONFIG_ARCH_OMAP4) |
| 106 static const int omap44xx_dma_reqs[][2] = { |
| 107 { OMAP44XX_DMA_MCBSP1_TX, OMAP44XX_DMA_MCBSP1_RX }, |
| 108 { OMAP44XX_DMA_MCBSP2_TX, OMAP44XX_DMA_MCBSP2_RX }, |
| 109 { OMAP44XX_DMA_MCBSP3_TX, OMAP44XX_DMA_MCBSP3_RX }, |
| 110 { OMAP44XX_DMA_MCBSP4_TX, OMAP44XX_DMA_MCBSP4_RX }, |
| 111 }; |
| 112 #else |
| 113 static const int omap44xx_dma_reqs[][2] = {}; |
| 114 #endif |
| 115 |
| 105 #if defined(CONFIG_ARCH_OMAP2420) | 116 #if defined(CONFIG_ARCH_OMAP2420) |
| 106 static const unsigned long omap2420_mcbsp_port[][2] = { | 117 static const unsigned long omap2420_mcbsp_port[][2] = { |
| 107 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, | 118 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, |
| 108 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, | 119 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, |
| 109 { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1, | 120 { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1, |
| 110 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, | 121 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, |
| 111 }; | 122 }; |
| 112 #else | 123 #else |
| 113 static const unsigned long omap2420_mcbsp_port[][2] = {}; | 124 static const unsigned long omap2420_mcbsp_port[][2] = {}; |
| 114 #endif | 125 #endif |
| (...skipping 25 matching lines...) Expand all Loading... |
| 140 OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, | 151 OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, |
| 141 { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, | 152 { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, |
| 142 OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, | 153 OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, |
| 143 { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, | 154 { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, |
| 144 OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, | 155 OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, |
| 145 }; | 156 }; |
| 146 #else | 157 #else |
| 147 static const unsigned long omap34xx_mcbsp_port[][2] = {}; | 158 static const unsigned long omap34xx_mcbsp_port[][2] = {}; |
| 148 #endif | 159 #endif |
| 149 | 160 |
| 161 #if defined(CONFIG_ARCH_OMAP4) |
| 162 static const unsigned long omap44xx_mcbsp_port[][2] = { |
| 163 { OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, |
| 164 OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, |
| 165 { OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, |
| 166 OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, |
| 167 { OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, |
| 168 OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, |
| 169 { OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, |
| 170 OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, |
| 171 }; |
| 172 #else |
| 173 static const unsigned long omap44xx_mcbsp_port[][2] = {}; |
| 174 #endif |
| 175 |
| 150 static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | 176 static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) |
| 151 { | 177 { |
| 152 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 178 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 153 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 179 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 154 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 180 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); |
| 155 struct omap_pcm_dma_data *dma_data; | 181 struct omap_pcm_dma_data *dma_data; |
| 156 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); | 182 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); |
| 157 int words; | 183 int words; |
| 158 | 184 |
| 159 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 185 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 * For example on McBSP3: | 243 * For example on McBSP3: |
| 218 * 16bit samples: size is 128 * 2 = 256 bytes | 244 * 16bit samples: size is 128 * 2 = 256 bytes |
| 219 * 32bit samples: size is 128 * 4 = 512 bytes | 245 * 32bit samples: size is 128 * 4 = 512 bytes |
| 220 * It is simpler to place constraint for buffer and period based on | 246 * It is simpler to place constraint for buffer and period based on |
| 221 * channels. | 247 * channels. |
| 222 * McBSP3 as example again (16 or 32 bit samples): | 248 * McBSP3 as example again (16 or 32 bit samples): |
| 223 * 1 channel (mono): size is 128 frames (128 words) | 249 * 1 channel (mono): size is 128 frames (128 words) |
| 224 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) | 250 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) |
| 225 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) | 251 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) |
| 226 */ | 252 */ |
| 227 » if (cpu_is_omap343x()) { | 253 » if (cpu_is_omap343x() || cpu_is_omap44xx()) { |
| 228 /* | 254 /* |
| 229 * Rule for the buffer size. We should not allow | 255 * Rule for the buffer size. We should not allow |
| 230 * smaller buffer than the FIFO size to avoid underruns | 256 * smaller buffer than the FIFO size to avoid underruns |
| 231 */ | 257 */ |
| 232 snd_pcm_hw_rule_add(substream->runtime, 0, | 258 snd_pcm_hw_rule_add(substream->runtime, 0, |
| 233 SNDRV_PCM_HW_PARAM_CHANNELS, | 259 SNDRV_PCM_HW_PARAM_CHANNELS, |
| 234 omap_mcbsp_hwrule_min_buffersize, | 260 omap_mcbsp_hwrule_min_buffersize, |
| 235 mcbsp_data, | 261 mcbsp_data, |
| 236 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); | 262 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); |
| 237 | 263 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 port = omap1_mcbsp_port[bus_id][substream->stream]; | 351 port = omap1_mcbsp_port[bus_id][substream->stream]; |
| 326 } else if (cpu_is_omap2420()) { | 352 } else if (cpu_is_omap2420()) { |
| 327 dma = omap24xx_dma_reqs[bus_id][substream->stream]; | 353 dma = omap24xx_dma_reqs[bus_id][substream->stream]; |
| 328 port = omap2420_mcbsp_port[bus_id][substream->stream]; | 354 port = omap2420_mcbsp_port[bus_id][substream->stream]; |
| 329 } else if (cpu_is_omap2430()) { | 355 } else if (cpu_is_omap2430()) { |
| 330 dma = omap24xx_dma_reqs[bus_id][substream->stream]; | 356 dma = omap24xx_dma_reqs[bus_id][substream->stream]; |
| 331 port = omap2430_mcbsp_port[bus_id][substream->stream]; | 357 port = omap2430_mcbsp_port[bus_id][substream->stream]; |
| 332 } else if (cpu_is_omap343x()) { | 358 } else if (cpu_is_omap343x()) { |
| 333 dma = omap24xx_dma_reqs[bus_id][substream->stream]; | 359 dma = omap24xx_dma_reqs[bus_id][substream->stream]; |
| 334 port = omap34xx_mcbsp_port[bus_id][substream->stream]; | 360 port = omap34xx_mcbsp_port[bus_id][substream->stream]; |
| 361 } else if (cpu_is_omap44xx()) { |
| 362 dma = omap44xx_dma_reqs[bus_id][substream->stream]; |
| 363 port = omap44xx_mcbsp_port[bus_id][substream->stream]; |
| 335 } else { | 364 } else { |
| 336 return -ENODEV; | 365 return -ENODEV; |
| 337 } | 366 } |
| 338 switch (params_format(params)) { | 367 switch (params_format(params)) { |
| 339 case SNDRV_PCM_FORMAT_S16_LE: | 368 case SNDRV_PCM_FORMAT_S16_LE: |
| 340 dma_data->data_type = OMAP_DMA_DATA_TYPE_S16; | 369 dma_data->data_type = OMAP_DMA_DATA_TYPE_S16; |
| 341 wlen = 16; | 370 wlen = 16; |
| 342 break; | 371 break; |
| 343 case SNDRV_PCM_FORMAT_S32_LE: | 372 case SNDRV_PCM_FORMAT_S32_LE: |
| 344 dma_data->data_type = OMAP_DMA_DATA_TYPE_S32; | 373 dma_data->data_type = OMAP_DMA_DATA_TYPE_S32; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 520 |
| 492 if (mcbsp_data->configured) | 521 if (mcbsp_data->configured) |
| 493 return 0; | 522 return 0; |
| 494 | 523 |
| 495 mcbsp_data->fmt = fmt; | 524 mcbsp_data->fmt = fmt; |
| 496 memset(regs, 0, sizeof(*regs)); | 525 memset(regs, 0, sizeof(*regs)); |
| 497 /* Generic McBSP register settings */ | 526 /* Generic McBSP register settings */ |
| 498 regs->spcr2 |= XINTM(3) | FREE; | 527 regs->spcr2 |= XINTM(3) | FREE; |
| 499 regs->spcr1 |= RINTM(3); | 528 regs->spcr1 |= RINTM(3); |
| 500 /* RFIG and XFIG are not defined in 34xx */ | 529 /* RFIG and XFIG are not defined in 34xx */ |
| 501 » if (!cpu_is_omap34xx()) { | 530 » if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { |
| 502 regs->rcr2 |= RFIG; | 531 regs->rcr2 |= RFIG; |
| 503 regs->xcr2 |= XFIG; | 532 regs->xcr2 |= XFIG; |
| 504 } | 533 } |
| 505 » if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 534 » if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { |
| 506 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; | 535 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; |
| 507 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; | 536 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; |
| 508 } | 537 } |
| 509 | 538 |
| 510 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 539 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 511 case SND_SOC_DAIFMT_I2S: | 540 case SND_SOC_DAIFMT_I2S: |
| 512 /* 1-bit data delay */ | 541 /* 1-bit data delay */ |
| 513 regs->rcr2 |= RDATDLY(1); | 542 regs->rcr2 |= RDATDLY(1); |
| 514 regs->xcr2 |= XDATDLY(1); | 543 regs->xcr2 |= XDATDLY(1); |
| 515 break; | 544 break; |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 | 894 |
| 866 static void __exit snd_omap_mcbsp_exit(void) | 895 static void __exit snd_omap_mcbsp_exit(void) |
| 867 { | 896 { |
| 868 platform_driver_unregister(&asoc_mcbsp_driver); | 897 platform_driver_unregister(&asoc_mcbsp_driver); |
| 869 } | 898 } |
| 870 module_exit(snd_omap_mcbsp_exit); | 899 module_exit(snd_omap_mcbsp_exit); |
| 871 | 900 |
| 872 MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>"); | 901 MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>"); |
| 873 MODULE_DESCRIPTION("OMAP I2S SoC Interface"); | 902 MODULE_DESCRIPTION("OMAP I2S SoC Interface"); |
| 874 MODULE_LICENSE("GPL"); | 903 MODULE_LICENSE("GPL"); |
| OLD | NEW |