diff options
Diffstat (limited to 'sound/soc/omap/omap-mcbsp.c')
-rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 181 |
1 files changed, 127 insertions, 54 deletions
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 35310e16d7f3..0a063a98a661 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -59,12 +59,7 @@ static struct omap_mcbsp_data mcbsp_data[NUM_LINKS]; | |||
59 | * Stream DMA parameters. DMA request line and port address are set runtime | 59 | * Stream DMA parameters. DMA request line and port address are set runtime |
60 | * since they are different between OMAP1 and later OMAPs | 60 | * since they are different between OMAP1 and later OMAPs |
61 | */ | 61 | */ |
62 | static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2] = { | 62 | static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2]; |
63 | { | ||
64 | { .name = "I2S PCM Stereo out", }, | ||
65 | { .name = "I2S PCM Stereo in", }, | ||
66 | }, | ||
67 | }; | ||
68 | 63 | ||
69 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | 64 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) |
70 | static const int omap1_dma_reqs[][2] = { | 65 | static const int omap1_dma_reqs[][2] = { |
@@ -84,11 +79,22 @@ static const unsigned long omap1_mcbsp_port[][2] = { | |||
84 | static const int omap1_dma_reqs[][2] = {}; | 79 | static const int omap1_dma_reqs[][2] = {}; |
85 | static const unsigned long omap1_mcbsp_port[][2] = {}; | 80 | static const unsigned long omap1_mcbsp_port[][2] = {}; |
86 | #endif | 81 | #endif |
87 | #if defined(CONFIG_ARCH_OMAP2420) | 82 | |
88 | static const int omap2420_dma_reqs[][2] = { | 83 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
84 | static const int omap24xx_dma_reqs[][2] = { | ||
89 | { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, | 85 | { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, |
90 | { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, | 86 | { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, |
87 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) | ||
88 | { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, | ||
89 | { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, | ||
90 | { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, | ||
91 | #endif | ||
91 | }; | 92 | }; |
93 | #else | ||
94 | static const int omap24xx_dma_reqs[][2] = {}; | ||
95 | #endif | ||
96 | |||
97 | #if defined(CONFIG_ARCH_OMAP2420) | ||
92 | static const unsigned long omap2420_mcbsp_port[][2] = { | 98 | static const unsigned long omap2420_mcbsp_port[][2] = { |
93 | { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, | 99 | { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, |
94 | OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, | 100 | OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, |
@@ -96,10 +102,43 @@ static const unsigned long omap2420_mcbsp_port[][2] = { | |||
96 | OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, | 102 | OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, |
97 | }; | 103 | }; |
98 | #else | 104 | #else |
99 | static const int omap2420_dma_reqs[][2] = {}; | ||
100 | static const unsigned long omap2420_mcbsp_port[][2] = {}; | 105 | static const unsigned long omap2420_mcbsp_port[][2] = {}; |
101 | #endif | 106 | #endif |
102 | 107 | ||
108 | #if defined(CONFIG_ARCH_OMAP2430) | ||
109 | static const unsigned long omap2430_mcbsp_port[][2] = { | ||
110 | { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, | ||
111 | OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, | ||
112 | { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, | ||
113 | OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, | ||
114 | { OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, | ||
115 | OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, | ||
116 | { OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, | ||
117 | OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, | ||
118 | { OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, | ||
119 | OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, | ||
120 | }; | ||
121 | #else | ||
122 | static const unsigned long omap2430_mcbsp_port[][2] = {}; | ||
123 | #endif | ||
124 | |||
125 | #if defined(CONFIG_ARCH_OMAP34XX) | ||
126 | static const unsigned long omap34xx_mcbsp_port[][2] = { | ||
127 | { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, | ||
128 | OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, | ||
129 | { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, | ||
130 | OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, | ||
131 | { OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, | ||
132 | OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, | ||
133 | { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, | ||
134 | OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, | ||
135 | { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, | ||
136 | OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, | ||
137 | }; | ||
138 | #else | ||
139 | static const unsigned long omap34xx_mcbsp_port[][2] = {}; | ||
140 | #endif | ||
141 | |||
103 | static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) | 142 | static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) |
104 | { | 143 | { |
105 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 144 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -167,14 +206,19 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
167 | dma = omap1_dma_reqs[bus_id][substream->stream]; | 206 | dma = omap1_dma_reqs[bus_id][substream->stream]; |
168 | port = omap1_mcbsp_port[bus_id][substream->stream]; | 207 | port = omap1_mcbsp_port[bus_id][substream->stream]; |
169 | } else if (cpu_is_omap2420()) { | 208 | } else if (cpu_is_omap2420()) { |
170 | dma = omap2420_dma_reqs[bus_id][substream->stream]; | 209 | dma = omap24xx_dma_reqs[bus_id][substream->stream]; |
171 | port = omap2420_mcbsp_port[bus_id][substream->stream]; | 210 | port = omap2420_mcbsp_port[bus_id][substream->stream]; |
211 | } else if (cpu_is_omap2430()) { | ||
212 | dma = omap24xx_dma_reqs[bus_id][substream->stream]; | ||
213 | port = omap2430_mcbsp_port[bus_id][substream->stream]; | ||
214 | } else if (cpu_is_omap343x()) { | ||
215 | dma = omap24xx_dma_reqs[bus_id][substream->stream]; | ||
216 | port = omap34xx_mcbsp_port[bus_id][substream->stream]; | ||
172 | } else { | 217 | } else { |
173 | /* | ||
174 | * TODO: Add support for 2430 and 3430 | ||
175 | */ | ||
176 | return -ENODEV; | 218 | return -ENODEV; |
177 | } | 219 | } |
220 | omap_mcbsp_dai_dma_params[id][substream->stream].name = | ||
221 | substream->stream ? "Audio Capture" : "Audio Playback"; | ||
178 | omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; | 222 | omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; |
179 | omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; | 223 | omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; |
180 | cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; | 224 | cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; |
@@ -245,6 +289,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
245 | regs->rcr2 |= RDATDLY(1); | 289 | regs->rcr2 |= RDATDLY(1); |
246 | regs->xcr2 |= XDATDLY(1); | 290 | regs->xcr2 |= XDATDLY(1); |
247 | break; | 291 | break; |
292 | case SND_SOC_DAIFMT_DSP_A: | ||
293 | /* 0-bit data delay */ | ||
294 | regs->rcr2 |= RDATDLY(0); | ||
295 | regs->xcr2 |= XDATDLY(0); | ||
296 | break; | ||
248 | default: | 297 | default: |
249 | /* Unsupported data format */ | 298 | /* Unsupported data format */ |
250 | return -EINVAL; | 299 | return -EINVAL; |
@@ -310,7 +359,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data, | |||
310 | int clk_id) | 359 | int clk_id) |
311 | { | 360 | { |
312 | int sel_bit; | 361 | int sel_bit; |
313 | u16 reg; | 362 | u16 reg, reg_devconf1 = OMAP243X_CONTROL_DEVCONF1; |
314 | 363 | ||
315 | if (cpu_class_is_omap1()) { | 364 | if (cpu_class_is_omap1()) { |
316 | /* OMAP1's can use only external source clock */ | 365 | /* OMAP1's can use only external source clock */ |
@@ -320,6 +369,12 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data, | |||
320 | return 0; | 369 | return 0; |
321 | } | 370 | } |
322 | 371 | ||
372 | if (cpu_is_omap2420() && mcbsp_data->bus_id > 1) | ||
373 | return -EINVAL; | ||
374 | |||
375 | if (cpu_is_omap343x()) | ||
376 | reg_devconf1 = OMAP343X_CONTROL_DEVCONF1; | ||
377 | |||
323 | switch (mcbsp_data->bus_id) { | 378 | switch (mcbsp_data->bus_id) { |
324 | case 0: | 379 | case 0: |
325 | reg = OMAP2_CONTROL_DEVCONF0; | 380 | reg = OMAP2_CONTROL_DEVCONF0; |
@@ -329,20 +384,26 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data, | |||
329 | reg = OMAP2_CONTROL_DEVCONF0; | 384 | reg = OMAP2_CONTROL_DEVCONF0; |
330 | sel_bit = 6; | 385 | sel_bit = 6; |
331 | break; | 386 | break; |
332 | /* TODO: Support for ports 3 - 5 in OMAP2430 and OMAP34xx */ | 387 | case 2: |
388 | reg = reg_devconf1; | ||
389 | sel_bit = 0; | ||
390 | break; | ||
391 | case 3: | ||
392 | reg = reg_devconf1; | ||
393 | sel_bit = 2; | ||
394 | break; | ||
395 | case 4: | ||
396 | reg = reg_devconf1; | ||
397 | sel_bit = 4; | ||
398 | break; | ||
333 | default: | 399 | default: |
334 | return -EINVAL; | 400 | return -EINVAL; |
335 | } | 401 | } |
336 | 402 | ||
337 | if (cpu_class_is_omap2()) { | 403 | if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK) |
338 | if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK) { | 404 | omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg); |
339 | omap_ctrl_writel(omap_ctrl_readl(reg) & | 405 | else |
340 | ~(1 << sel_bit), reg); | 406 | omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg); |
341 | } else { | ||
342 | omap_ctrl_writel(omap_ctrl_readl(reg) | | ||
343 | (1 << sel_bit), reg); | ||
344 | } | ||
345 | } | ||
346 | 407 | ||
347 | return 0; | 408 | return 0; |
348 | } | 409 | } |
@@ -376,37 +437,49 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
376 | return err; | 437 | return err; |
377 | } | 438 | } |
378 | 439 | ||
379 | struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = { | 440 | #define OMAP_MCBSP_DAI_BUILDER(link_id) \ |
380 | { | 441 | { \ |
381 | .name = "omap-mcbsp-dai", | 442 | .name = "omap-mcbsp-dai-(link_id)", \ |
382 | .id = 0, | 443 | .id = (link_id), \ |
383 | .type = SND_SOC_DAI_I2S, | 444 | .type = SND_SOC_DAI_I2S, \ |
384 | .playback = { | 445 | .playback = { \ |
385 | .channels_min = 2, | 446 | .channels_min = 2, \ |
386 | .channels_max = 2, | 447 | .channels_max = 2, \ |
387 | .rates = OMAP_MCBSP_RATES, | 448 | .rates = OMAP_MCBSP_RATES, \ |
388 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 449 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ |
389 | }, | 450 | }, \ |
390 | .capture = { | 451 | .capture = { \ |
391 | .channels_min = 2, | 452 | .channels_min = 2, \ |
392 | .channels_max = 2, | 453 | .channels_max = 2, \ |
393 | .rates = OMAP_MCBSP_RATES, | 454 | .rates = OMAP_MCBSP_RATES, \ |
394 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 455 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ |
395 | }, | 456 | }, \ |
396 | .ops = { | 457 | .ops = { \ |
397 | .startup = omap_mcbsp_dai_startup, | 458 | .startup = omap_mcbsp_dai_startup, \ |
398 | .shutdown = omap_mcbsp_dai_shutdown, | 459 | .shutdown = omap_mcbsp_dai_shutdown, \ |
399 | .trigger = omap_mcbsp_dai_trigger, | 460 | .trigger = omap_mcbsp_dai_trigger, \ |
400 | .hw_params = omap_mcbsp_dai_hw_params, | 461 | .hw_params = omap_mcbsp_dai_hw_params, \ |
401 | }, | 462 | }, \ |
402 | .dai_ops = { | 463 | .dai_ops = { \ |
403 | .set_fmt = omap_mcbsp_dai_set_dai_fmt, | 464 | .set_fmt = omap_mcbsp_dai_set_dai_fmt, \ |
404 | .set_clkdiv = omap_mcbsp_dai_set_clkdiv, | 465 | .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \ |
405 | .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, | 466 | .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \ |
406 | }, | 467 | }, \ |
407 | .private_data = &mcbsp_data[0].bus_id, | 468 | .private_data = &mcbsp_data[(link_id)].bus_id, \ |
408 | }, | 469 | } |
470 | |||
471 | struct snd_soc_dai omap_mcbsp_dai[] = { | ||
472 | OMAP_MCBSP_DAI_BUILDER(0), | ||
473 | OMAP_MCBSP_DAI_BUILDER(1), | ||
474 | #if NUM_LINKS >= 3 | ||
475 | OMAP_MCBSP_DAI_BUILDER(2), | ||
476 | #endif | ||
477 | #if NUM_LINKS == 5 | ||
478 | OMAP_MCBSP_DAI_BUILDER(3), | ||
479 | OMAP_MCBSP_DAI_BUILDER(4), | ||
480 | #endif | ||
409 | }; | 481 | }; |
482 | |||
410 | EXPORT_SYMBOL_GPL(omap_mcbsp_dai); | 483 | EXPORT_SYMBOL_GPL(omap_mcbsp_dai); |
411 | 484 | ||
412 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); | 485 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); |