Merge branch 'topic/dmaengine' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-bcm2835
This commit is contained in:
commit
cc70666c25
|
@ -51,6 +51,16 @@ struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
|
||||||
void *filter_data);
|
void *filter_data);
|
||||||
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
|
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The DAI supports packed transfers, eg 2 16-bit samples in a 32-bit word.
|
||||||
|
* If this flag is set the dmaengine driver won't put any restriction on
|
||||||
|
* the supported sample formats and set the DMA transfer size to undefined.
|
||||||
|
* The DAI driver is responsible to disable any unsupported formats in it's
|
||||||
|
* configuration and catch corner cases that are not already handled in
|
||||||
|
* the ALSA core.
|
||||||
|
*/
|
||||||
|
#define SND_DMAENGINE_PCM_DAI_FLAG_PACK BIT(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
|
* struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
|
||||||
* @addr: Address of the DAI data source or destination register.
|
* @addr: Address of the DAI data source or destination register.
|
||||||
|
@ -63,6 +73,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
|
||||||
* requesting the DMA channel.
|
* requesting the DMA channel.
|
||||||
* @chan_name: Custom channel name to use when requesting DMA channel.
|
* @chan_name: Custom channel name to use when requesting DMA channel.
|
||||||
* @fifo_size: FIFO size of the DAI controller in bytes
|
* @fifo_size: FIFO size of the DAI controller in bytes
|
||||||
|
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
|
||||||
*/
|
*/
|
||||||
struct snd_dmaengine_dai_dma_data {
|
struct snd_dmaengine_dai_dma_data {
|
||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
|
@ -72,6 +83,7 @@ struct snd_dmaengine_dai_dma_data {
|
||||||
void *filter_data;
|
void *filter_data;
|
||||||
const char *chan_name;
|
const char *chan_name;
|
||||||
unsigned int fifo_size;
|
unsigned int fifo_size;
|
||||||
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||||
|
|
|
@ -106,8 +106,9 @@ EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
|
||||||
* direction of the substream. If the substream is a playback stream the dst
|
* direction of the substream. If the substream is a playback stream the dst
|
||||||
* fields will be initialized, if it is a capture stream the src fields will be
|
* fields will be initialized, if it is a capture stream the src fields will be
|
||||||
* initialized. The {dst,src}_addr_width field will only be initialized if the
|
* initialized. The {dst,src}_addr_width field will only be initialized if the
|
||||||
* addr_width field of the DAI DMA data struct is not equal to
|
* SND_DMAENGINE_PCM_DAI_FLAG_PACK flag is set or if the addr_width field of
|
||||||
* DMA_SLAVE_BUSWIDTH_UNDEFINED.
|
* the DAI DMA data struct is not equal to DMA_SLAVE_BUSWIDTH_UNDEFINED. If
|
||||||
|
* both conditions are met the latter takes priority.
|
||||||
*/
|
*/
|
||||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||||
const struct snd_pcm_substream *substream,
|
const struct snd_pcm_substream *substream,
|
||||||
|
@ -117,11 +118,17 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
slave_config->dst_addr = dma_data->addr;
|
slave_config->dst_addr = dma_data->addr;
|
||||||
slave_config->dst_maxburst = dma_data->maxburst;
|
slave_config->dst_maxburst = dma_data->maxburst;
|
||||||
|
if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
|
||||||
|
slave_config->dst_addr_width =
|
||||||
|
DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
||||||
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||||
slave_config->dst_addr_width = dma_data->addr_width;
|
slave_config->dst_addr_width = dma_data->addr_width;
|
||||||
} else {
|
} else {
|
||||||
slave_config->src_addr = dma_data->addr;
|
slave_config->src_addr = dma_data->addr;
|
||||||
slave_config->src_maxburst = dma_data->maxburst;
|
slave_config->src_maxburst = dma_data->maxburst;
|
||||||
|
if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
|
||||||
|
slave_config->src_addr_width =
|
||||||
|
DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
||||||
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||||
slave_config->src_addr_width = dma_data->addr_width;
|
slave_config->src_addr_width = dma_data->addr_width;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,31 +163,42 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare formats mask for valid/allowed sample types. If the dma does
|
* If SND_DMAENGINE_PCM_DAI_FLAG_PACK is set keep
|
||||||
* not have support for the given physical word size, it needs to be
|
* hw.formats set to 0, meaning no restrictions are in place.
|
||||||
* masked out so user space can not use the format which produces
|
* In this case it's the responsibility of the DAI driver to
|
||||||
* corrupted audio.
|
* provide the supported format information.
|
||||||
* In case the dma driver does not implement the slave_caps the default
|
|
||||||
* assumption is that it supports 1, 2 and 4 bytes widths.
|
|
||||||
*/
|
*/
|
||||||
for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
|
if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK))
|
||||||
int bits = snd_pcm_format_physical_width(i);
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
|
||||||
|
int bits = snd_pcm_format_physical_width(i);
|
||||||
|
|
||||||
/* Enable only samples with DMA supported physical widths */
|
/*
|
||||||
switch (bits) {
|
* Enable only samples with DMA supported physical
|
||||||
case 8:
|
* widths
|
||||||
case 16:
|
*/
|
||||||
case 24:
|
switch (bits) {
|
||||||
case 32:
|
case 8:
|
||||||
case 64:
|
case 16:
|
||||||
if (addr_widths & (1 << (bits / 8)))
|
case 24:
|
||||||
hw.formats |= (1LL << i);
|
case 32:
|
||||||
break;
|
case 64:
|
||||||
default:
|
if (addr_widths & (1 << (bits / 8)))
|
||||||
/* Unsupported types */
|
hw.formats |= (1LL << i);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
/* Unsupported types */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return snd_soc_set_runtime_hwparams(substream, &hw);
|
return snd_soc_set_runtime_hwparams(substream, &hw);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue