On 07/02/2014 03:48 PM, Lars-Peter Clausen wrote:
per discussion over the irc with Lars we could extend the masking to other widths as well, which would look something like this: u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); ... /*
- Prepare formats mask for valid/allowed sample types. If the dma does
- not have support for the given physical word size, it needs to be
- masked out so user space can not use the format which produces
- corrupted audio.
- In case the dma driver does not implement the slave_caps the default
- assumption is that it supports 1, 2 and 4 bytes widths.
*/ if (!dma_get_slave_caps(prtd->dma_chan, &dma_caps)) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) addr_widths = dma_caps.dstn_addr_widths; else addr_widths = dma_caps.src_addr_widths; }
for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { int bits = snd_pcm_format_physical_width(i);
switch (bits) { case 8: if (!(addr_widths & BIT(DMA_SLAVE_BUSWIDTH_1_BYTE))) fmt_mask |= (1LL << i); break; case 16: if (!(addr_widths & BIT(DMA_SLAVE_BUSWIDTH_2_BYTES))) fmt_mask |= (1LL << i); break; case 24: if (!(addr_widths & BIT(DMA_SLAVE_BUSWIDTH_3_BYTES))) fmt_mask |= (1LL << i); break; case 32: if (!(addr_widths & BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))) fmt_mask |= (1LL << i); break; case 64: if (!(addr_widths & BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))) fmt_mask |= (1LL << i); break; default: fmt_mask |= (1LL << i); break; }
}
Is this sounds better?
Sounds good. I think we can assume that DMA_SLAVE_BUSWIDTH_1_BYTE = 1, ... So (addr_width & BIT(bits / 8)) should work fine and we do not need to duplicate the case branches.
The other thing is this should go into dmaengine_pcm_set_runtime_hwparams() where we also restrict the other hardware parameters based on the dmaengine capabilities.
true