aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-08-04 11:31:18 -0400
committerMark Brown <broonie@linaro.org>2014-08-04 11:31:18 -0400
commit3a2ac12f8eadaee97ad0337d81280547ab7a3311 (patch)
tree92f9a25f8cdac19cfe174de41a3751cc36fa6a57
parent7196be58ca832b6b37965921714849276f8996bc (diff)
parente4a899d9bd5d18f5568be88f7ec8edf4cd107a94 (diff)
Merge remote-tracking branch 'asoc/topic/dma' into asoc-next
-rw-r--r--drivers/dma/edma.c1
-rw-r--r--include/linux/dmaengine.h1
-rw-r--r--sound/core/pcm_dmaengine.c4
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c37
4 files changed, 41 insertions, 2 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index d08c4dedef35..b512caf46944 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -982,6 +982,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
982 982
983#define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ 983#define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
984 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ 984 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
985 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
985 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) 986 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
986 987
987static int edma_dma_device_slave_caps(struct dma_chan *dchan, 988static int edma_dma_device_slave_caps(struct dma_chan *dchan,
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index d2c5cc7c583c..3d1c2aa51530 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -299,6 +299,7 @@ enum dma_slave_buswidth {
299 DMA_SLAVE_BUSWIDTH_UNDEFINED = 0, 299 DMA_SLAVE_BUSWIDTH_UNDEFINED = 0,
300 DMA_SLAVE_BUSWIDTH_1_BYTE = 1, 300 DMA_SLAVE_BUSWIDTH_1_BYTE = 1,
301 DMA_SLAVE_BUSWIDTH_2_BYTES = 2, 301 DMA_SLAVE_BUSWIDTH_2_BYTES = 2,
302 DMA_SLAVE_BUSWIDTH_3_BYTES = 3,
302 DMA_SLAVE_BUSWIDTH_4_BYTES = 4, 303 DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
303 DMA_SLAVE_BUSWIDTH_8_BYTES = 8, 304 DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
304}; 305};
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 76cbb9ec953a..6542c4083594 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -65,13 +65,15 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
65 enum dma_slave_buswidth buswidth; 65 enum dma_slave_buswidth buswidth;
66 int bits; 66 int bits;
67 67
68 bits = snd_pcm_format_physical_width(params_format(params)); 68 bits = params_physical_width(params);
69 if (bits < 8 || bits > 64) 69 if (bits < 8 || bits > 64)
70 return -EINVAL; 70 return -EINVAL;
71 else if (bits == 8) 71 else if (bits == 8)
72 buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; 72 buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
73 else if (bits == 16) 73 else if (bits == 16)
74 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; 74 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
75 else if (bits == 24)
76 buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
75 else if (bits <= 32) 77 else if (bits <= 32)
76 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; 78 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
77 else 79 else
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 5bace124ef43..6307f85e871b 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -119,7 +119,10 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
119 struct snd_dmaengine_dai_dma_data *dma_data; 119 struct snd_dmaengine_dai_dma_data *dma_data;
120 struct dma_slave_caps dma_caps; 120 struct dma_slave_caps dma_caps;
121 struct snd_pcm_hardware hw; 121 struct snd_pcm_hardware hw;
122 int ret; 122 u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
123 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
124 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
125 int i, ret;
123 126
124 if (pcm->config && pcm->config->pcm_hardware) 127 if (pcm->config && pcm->config->pcm_hardware)
125 return snd_soc_set_runtime_hwparams(substream, 128 return snd_soc_set_runtime_hwparams(substream,
@@ -146,6 +149,38 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
146 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; 149 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
147 if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) 150 if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
148 hw.info |= SNDRV_PCM_INFO_BATCH; 151 hw.info |= SNDRV_PCM_INFO_BATCH;
152
153 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
154 addr_widths = dma_caps.dstn_addr_widths;
155 else
156 addr_widths = dma_caps.src_addr_widths;
157 }
158
159 /*
160 * Prepare formats mask for valid/allowed sample types. If the dma does
161 * not have support for the given physical word size, it needs to be
162 * masked out so user space can not use the format which produces
163 * corrupted audio.
164 * In case the dma driver does not implement the slave_caps the default
165 * assumption is that it supports 1, 2 and 4 bytes widths.
166 */
167 for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
168 int bits = snd_pcm_format_physical_width(i);
169
170 /* Enable only samples with DMA supported physical widths */
171 switch (bits) {
172 case 8:
173 case 16:
174 case 24:
175 case 32:
176 case 64:
177 if (addr_widths & (1 << (bits / 8)))
178 hw.formats |= (1LL << i);
179 break;
180 default:
181 /* Unsupported types */
182 break;
183 }
149 } 184 }
150 185
151 return snd_soc_set_runtime_hwparams(substream, &hw); 186 return snd_soc_set_runtime_hwparams(substream, &hw);