On Monday 31 May 2010 11:16:50 Ujfalusi Peter (Nokia-D/Tampere) wrote: ... > @@ -185,33 +231,43 @@ static int omap_mcbsp_dai_startup(struct > snd_pcm_substream *substream, if (!cpu_dai->active) > err = omap_mcbsp_request(bus_id); > > + /* > + * OMAP McBSP FIFO is word structured. > + * McBSP2 has 1024 + 256 = 1280 word long buffer, > + * McBSP1,3,4,5 has 128 word long buffer > + * This means that the size of the FIFO depends on the sample format. > + * For example on McBSP3: > + * 16bit samples: size is 128 * 2 = 256 bytes > + * 32bit samples: size is 128 * 4 = 512 bytes > + * It is simpler to place constraint for buffer and period based on > + * channels. > + * McBSP3 as example again (16 or 32 bit samples): > + * 1 channel (mono): size is 128 frames (128 words) > + * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) > + * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) > + */ > + > + /* > + * The first rule is for the buffer size, we should not allow smaller > + * buffer than the FIFO size to avoid underruns > + */ > + snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, > + hw_rule_bsize_by_channels, mcbsp_data, > + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); > + Obviously this hw_rule must be moved after checking the CPU type, since it is only valid for OMAP3 class of devices. I'll fix this in the v2 series. I have been testing this on OMAP3... > if (cpu_is_omap343x()) { > int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id); > - int max_period; > > /* > - * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. > - * Set constraint for minimum buffer size to the same than FIFO > - * size in order to avoid underruns in playback startup because > - * HW is keeping the DMA request active until FIFO is filled. > + * In case os threshold mode, the rule will ensure, that the > + * period size is not bigger than the maximum allowed threshold > + * value. > */ > - if (bus_id == 1) > - snd_pcm_hw_constraint_minmax(substream->runtime, > - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, > - 4096, UINT_MAX); > - > - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) > - max_period = omap_mcbsp_get_max_tx_threshold(bus_id); > - else > - max_period = omap_mcbsp_get_max_rx_threshold(bus_id); > - > - max_period++; > - max_period <<= 1; > - > if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) > - snd_pcm_hw_constraint_minmax(substream->runtime, > - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, > - 32, max_period); > + snd_pcm_hw_rule_add(substream->runtime, 0, > + SNDRV_PCM_HW_PARAM_CHANNELS, > + hw_rule_psize_by_channels, substream, > + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); > } > > return err; -- Péter -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html