aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/omap-mcbsp.c')
-rw-r--r--sound/soc/omap/omap-mcbsp.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8485a8a9d0ff..ec5e18a78758 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -36,9 +36,7 @@
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38 38
39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_44100 | \ 39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
40 SNDRV_PCM_RATE_48000 | \
41 SNDRV_PCM_RATE_KNOT)
42 40
43struct omap_mcbsp_data { 41struct omap_mcbsp_data {
44 unsigned int bus_id; 42 unsigned int bus_id;
@@ -140,7 +138,8 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
140static const unsigned long omap34xx_mcbsp_port[][2] = {}; 138static const unsigned long omap34xx_mcbsp_port[][2] = {};
141#endif 139#endif
142 140
143static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 141static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
142 struct snd_soc_dai *dai)
144{ 143{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -153,7 +152,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
153 return err; 152 return err;
154} 153}
155 154
156static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) 155static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
156 struct snd_soc_dai *dai)
157{ 157{
158 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -165,7 +165,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
165 } 165 }
166} 166}
167 167
168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) 168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
169 struct snd_soc_dai *dai)
169{ 170{
170 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
171 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 172 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -194,14 +195,15 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
194} 195}
195 196
196static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 197static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
197 struct snd_pcm_hw_params *params) 198 struct snd_pcm_hw_params *params,
199 struct snd_soc_dai *dai)
198{ 200{
199 struct snd_soc_pcm_runtime *rtd = substream->private_data; 201 struct snd_soc_pcm_runtime *rtd = substream->private_data;
200 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 202 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
201 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 203 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
202 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 204 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
203 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 205 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
204 int wlen; 206 int wlen, channels;
205 unsigned long port; 207 unsigned long port;
206 208
207 if (cpu_class_is_omap1()) { 209 if (cpu_class_is_omap1()) {
@@ -230,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
230 return 0; 232 return 0;
231 } 233 }
232 234
233 switch (params_channels(params)) { 235 channels = params_channels(params);
236 switch (channels) {
234 case 2: 237 case 2:
235 /* Set 1 word per (McBPSP) frame and use dual-phase frames */ 238 /* Use dual-phase frames */
236 regs->rcr2 |= RFRLEN2(1 - 1) | RPHASE; 239 regs->rcr2 |= RPHASE;
240 regs->xcr2 |= XPHASE;
241 case 1:
242 /* Set 1 word per (McBSP) frame */
243 regs->rcr2 |= RFRLEN2(1 - 1);
237 regs->rcr1 |= RFRLEN1(1 - 1); 244 regs->rcr1 |= RFRLEN1(1 - 1);
238 regs->xcr2 |= XFRLEN2(1 - 1) | XPHASE; 245 regs->xcr2 |= XFRLEN2(1 - 1);
239 regs->xcr1 |= XFRLEN1(1 - 1); 246 regs->xcr1 |= XFRLEN1(1 - 1);
240 break; 247 break;
241 default: 248 default:
@@ -263,9 +270,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
263 regs->srgr2 |= FPER(wlen * 2 - 1); 270 regs->srgr2 |= FPER(wlen * 2 - 1);
264 regs->srgr1 |= FWID(wlen - 1); 271 regs->srgr1 |= FWID(wlen - 1);
265 break; 272 break;
266 case SND_SOC_DAIFMT_DSP_A: 273 case SND_SOC_DAIFMT_DSP_B:
267 regs->srgr2 |= FPER(wlen * 2 - 1); 274 regs->srgr2 |= FPER(wlen * channels - 1);
268 regs->srgr1 |= FWID(wlen * 2 - 2); 275 regs->srgr1 |= FWID(wlen * channels - 2);
269 break; 276 break;
270 } 277 }
271 278
@@ -302,7 +309,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
302 regs->rcr2 |= RDATDLY(1); 309 regs->rcr2 |= RDATDLY(1);
303 regs->xcr2 |= XDATDLY(1); 310 regs->xcr2 |= XDATDLY(1);
304 break; 311 break;
305 case SND_SOC_DAIFMT_DSP_A: 312 case SND_SOC_DAIFMT_DSP_B:
306 /* 0-bit data delay */ 313 /* 0-bit data delay */
307 regs->rcr2 |= RDATDLY(0); 314 regs->rcr2 |= RDATDLY(0);
308 regs->xcr2 |= XDATDLY(0); 315 regs->xcr2 |= XDATDLY(0);
@@ -452,17 +459,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
452 459
453#define OMAP_MCBSP_DAI_BUILDER(link_id) \ 460#define OMAP_MCBSP_DAI_BUILDER(link_id) \
454{ \ 461{ \
455 .name = "omap-mcbsp-dai-(link_id)", \ 462 .name = "omap-mcbsp-dai-"#link_id, \
456 .id = (link_id), \ 463 .id = (link_id), \
457 .type = SND_SOC_DAI_I2S, \
458 .playback = { \ 464 .playback = { \
459 .channels_min = 2, \ 465 .channels_min = 1, \
460 .channels_max = 2, \ 466 .channels_max = 2, \
461 .rates = OMAP_MCBSP_RATES, \ 467 .rates = OMAP_MCBSP_RATES, \
462 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
463 }, \ 469 }, \
464 .capture = { \ 470 .capture = { \
465 .channels_min = 2, \ 471 .channels_min = 1, \
466 .channels_max = 2, \ 472 .channels_max = 2, \
467 .rates = OMAP_MCBSP_RATES, \ 473 .rates = OMAP_MCBSP_RATES, \
468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 474 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
@@ -472,8 +478,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
472 .shutdown = omap_mcbsp_dai_shutdown, \ 478 .shutdown = omap_mcbsp_dai_shutdown, \
473 .trigger = omap_mcbsp_dai_trigger, \ 479 .trigger = omap_mcbsp_dai_trigger, \
474 .hw_params = omap_mcbsp_dai_hw_params, \ 480 .hw_params = omap_mcbsp_dai_hw_params, \
475 }, \
476 .dai_ops = { \
477 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \ 481 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
478 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \ 482 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
479 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \ 483 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
@@ -495,6 +499,19 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
495 499
496EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 500EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
497 501
502static int __init snd_omap_mcbsp_init(void)
503{
504 return snd_soc_register_dais(omap_mcbsp_dai,
505 ARRAY_SIZE(omap_mcbsp_dai));
506}
507module_init(snd_omap_mcbsp_init);
508
509static void __exit snd_omap_mcbsp_exit(void)
510{
511 snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai));
512}
513module_exit(snd_omap_mcbsp_exit);
514
498MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 515MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
499MODULE_DESCRIPTION("OMAP I2S SoC Interface"); 516MODULE_DESCRIPTION("OMAP I2S SoC Interface");
500MODULE_LICENSE("GPL"); 517MODULE_LICENSE("GPL");