On Wednesday 04 November 2009 19:53:55 ext Liam Girdwood wrote: > From: Graeme Gregory <gg@xxxxxxxxxxxxxxx> > > This patch increases the number of supported audio channels from 4 > to 16 and was sponsored by Shotspotter inc. > > Signed-off-by: Graeme Gregory <gg@xxxxxxxxxxxxxxx> > Signed-off-by: Liam Girdwood <lrg@xxxxxxxxxxxxxxx> > --- > sound/soc/omap/omap-mcbsp.c | 71 > +++++++++++++++++++++++++++++------------- 1 files changed, 49 > insertions(+), 22 deletions(-) > > diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c > index 3341f49..290ef2f 100644 > --- a/sound/soc/omap/omap-mcbsp.c > +++ b/sound/soc/omap/omap-mcbsp.c > @@ -49,6 +49,8 @@ struct omap_mcbsp_data { > */ > int active; > int configured; > + unsigned int in_freq; > + int clk_div; > }; > > #define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, > bus_id) @@ -257,7 +259,7 @@ static int omap_mcbsp_dai_hw_params(struct > snd_pcm_substream *substream, int dma, bus_id = mcbsp_data->bus_id, id = > cpu_dai->id; > int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; > unsigned long port; > - unsigned int format; > + unsigned int format, frame_size, div; > > if (cpu_class_is_omap1()) { > dma = omap1_dma_reqs[bus_id][substream->stream]; > @@ -294,27 +296,23 @@ static int omap_mcbsp_dai_hw_params(struct > snd_pcm_substream *substream, > > format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; > wpf = channels = params_channels(params); > - switch (channels) { > - case 2: > - if (format == SND_SOC_DAIFMT_I2S) { > - /* Use dual-phase frames */ > - regs->rcr2 |= RPHASE; > - regs->xcr2 |= XPHASE; > - /* Set 1 word per (McBSP) frame for phase1 and phase2 */ > - wpf--; > - regs->rcr2 |= RFRLEN2(wpf - 1); > - regs->xcr2 |= XFRLEN2(wpf - 1); > - } > - case 1: > - case 4: > + if (channels == 2 && format == SND_SOC_DAIFMT_I2S) { > + /* Use dual-phase frames */ > + regs->rcr2 |= RPHASE; > + regs->xcr2 |= XPHASE; > + /* Set 1 word per (McBSP) frame for phase1 and phase2 */ > + wpf--; > + regs->rcr2 |= RFRLEN2(wpf - 1); > + regs->xcr2 |= XFRLEN2(wpf - 1); > /* Set word per (McBSP) frame for phase1 */ > regs->rcr1 |= RFRLEN1(wpf - 1); > regs->xcr1 |= XFRLEN1(wpf - 1); > - break; > - default: > + } else if (channels > 0 && channels < 17) { > + regs->rcr1 |= RFRLEN1(wpf - 1); > + regs->xcr1 |= XFRLEN1(wpf - 1); > + } else > /* Unsupported number of channels */ > return -EINVAL; > - } I would have done this a bit differently: ... /* Check if the number of channels are valid */ if (channels < 1 || channels > 16) { /* Unsupported number of channels */ /* Probably would be good to have some error message about it? */ return -EINVAL; } format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; wpf = channels = params_channels(params); if (channels == 2 && format == SND_SOC_DAIFMT_I2S) { /* Use dual-phase frames */ regs->rcr2 |= RPHASE; regs->xcr2 |= XPHASE; /* Set 1 word per (McBSP) frame for phase1 and phase2 */ wpf--; regs->rcr2 |= RFRLEN2(wpf - 1); regs->xcr2 |= XFRLEN2(wpf - 1); } /* Set word per (McBSP) frame for phase1 */ regs->rcr1 |= RFRLEN1(wpf - 1); regs->xcr1 |= XFRLEN1(wpf - 1); > > switch (params_format(params)) { > case SNDRV_PCM_FORMAT_S16_LE: > @@ -330,6 +328,34 @@ static int omap_mcbsp_dai_hw_params(struct > snd_pcm_substream *substream, return -EINVAL; > } > > + /* Default div to 1 if it wasn't set by machine driver, otherwise > + * use set div as the maximum clock value > + */ > + div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1; > + > + /* calc best frame size for rate and clock divider */ > + do { > + frame_size = (mcbsp_data->in_freq / div) / params_rate(params); I think this as it is now will not work when McBSP is a slave. mcbsp_data->in_freq is going to be 0, since the sample rate generator is not in use. > + pr_debug("freq %d, rate %d, frame size %d, div %d\n", > + mcbsp_data->in_freq, params_rate(params), frame_size, div); > + > + if (frame_size > 256) > + div++; > + } while (frame_size > 256); > + > + /* Check we can fit the requested number of channels into our > + * calculated frame size > + */ > + if ((channels * wlen) > frame_size) { > + printk(KERN_ERR > + "OMAP-MCBSP: cannot fit channels in frame size\n"); > + return -EINVAL; > + } -- Péter _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel