Patch adds support for mono audio link configuration to function omap_mcbsp_dai_hw_params but doesn't expose it in omap_mcbsp_dai table by default.
Main idea behind this is to allow operate with real mono codecs but not break compatibility with existing codecs which can expose their channels_min as 1. Machine driver can use functionality provided by this patch by re-configuring runtime DAI's channels_min and channel_max to 1 for a link having mono codec.
For mono link, the I2S signalling remains the same but only first frame (left channel) is transmitting audio data and second frame is having a null data. In DSP_A, only first frame is transmitted.
Signed-off-by: Jarkko Nikula jarkko.nikula@nokia.com --- sound/soc/omap/omap-mcbsp.c | 19 ++++++++++++------- 1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 2eeb135..bb05c76 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -203,7 +203,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; - int wlen; + int wlen, channels; unsigned long port;
if (cpu_class_is_omap1()) { @@ -232,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, return 0; }
- switch (params_channels(params)) { + channels = params_channels(params); + switch (channels) { case 2: - /* Set 1 word per (McBPSP) frame and use dual-phase frames */ - regs->rcr2 |= RFRLEN2(1 - 1) | RPHASE; + /* Use dual-phase frames */ + regs->rcr2 |= RPHASE; + regs->xcr2 |= XPHASE; + case 1: + /* Set 1 word per (McBSP) frame */ + regs->rcr2 |= RFRLEN2(1 - 1); regs->rcr1 |= RFRLEN1(1 - 1); - regs->xcr2 |= XFRLEN2(1 - 1) | XPHASE; + regs->xcr2 |= XFRLEN2(1 - 1); regs->xcr1 |= XFRLEN1(1 - 1); break; default: @@ -266,8 +271,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, regs->srgr1 |= FWID(wlen - 1); break; case SND_SOC_DAIFMT_DSP_A: - regs->srgr2 |= FPER(wlen * 2 - 1); - regs->srgr1 |= FWID(wlen * 2 - 2); + regs->srgr2 |= FPER(wlen * channels - 1); + regs->srgr1 |= FWID(wlen * channels - 2); break; }