aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/omap-mcbsp.c')
-rw-r--r--sound/soc/omap/omap-mcbsp.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6e855080e6ea..580de5a8dba6 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -139,28 +139,59 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
139static const unsigned long omap34xx_mcbsp_port[][2] = {}; 139static const unsigned long omap34xx_mcbsp_port[][2] = {};
140#endif 140#endif
141 141
142static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
143{
144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
146 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
147 int samples = snd_pcm_lib_period_bytes(substream) >> 1;
148
149 /* Configure McBSP internal buffer usage */
150 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
151 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples - 1);
152 else
153 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples - 1);
154}
155
142static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 156static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
143 struct snd_soc_dai *dai) 157 struct snd_soc_dai *dai)
144{ 158{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 160 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
147 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 161 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
162 int bus_id = mcbsp_data->bus_id;
148 int err = 0; 163 int err = 0;
149 164
150 if (cpu_is_omap343x() && mcbsp_data->bus_id == 1) { 165 if (!cpu_dai->active)
166 err = omap_mcbsp_request(bus_id);
167
168 if (cpu_is_omap343x()) {
169 int max_period;
170
151 /* 171 /*
152 * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. 172 * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer.
153 * Set constraint for minimum buffer size to the same than FIFO 173 * Set constraint for minimum buffer size to the same than FIFO
154 * size in order to avoid underruns in playback startup because 174 * size in order to avoid underruns in playback startup because
155 * HW is keeping the DMA request active until FIFO is filled. 175 * HW is keeping the DMA request active until FIFO is filled.
156 */ 176 */
177 if (bus_id == 1)
178 snd_pcm_hw_constraint_minmax(substream->runtime,
179 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
180 4096, UINT_MAX);
181
182 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
183 max_period = omap_mcbsp_get_max_tx_threshold(bus_id);
184 else
185 max_period = omap_mcbsp_get_max_rx_threshold(bus_id);
186
187 max_period++;
188 max_period <<= 1;
189
157 snd_pcm_hw_constraint_minmax(substream->runtime, 190 snd_pcm_hw_constraint_minmax(substream->runtime,
158 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4096, UINT_MAX); 191 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
192 32, max_period);
159 } 193 }
160 194
161 if (!cpu_dai->active)
162 err = omap_mcbsp_request(mcbsp_data->bus_id);
163
164 return err; 195 return err;
165} 196}
166 197
@@ -220,7 +251,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
220 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 251 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
221 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 252 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
222 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 253 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
223 int wlen, channels, wpf; 254 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
224 unsigned long port; 255 unsigned long port;
225 unsigned int format; 256 unsigned int format;
226 257
@@ -236,6 +267,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
236 } else if (cpu_is_omap343x()) { 267 } else if (cpu_is_omap343x()) {
237 dma = omap24xx_dma_reqs[bus_id][substream->stream]; 268 dma = omap24xx_dma_reqs[bus_id][substream->stream];
238 port = omap34xx_mcbsp_port[bus_id][substream->stream]; 269 port = omap34xx_mcbsp_port[bus_id][substream->stream];
270 omap_mcbsp_dai_dma_params[id][substream->stream].set_threshold =
271 omap_mcbsp_set_threshold;
272 sync_mode = OMAP_DMA_SYNC_FRAME;
239 } else { 273 } else {
240 return -ENODEV; 274 return -ENODEV;
241 } 275 }
@@ -243,6 +277,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
243 substream->stream ? "Audio Capture" : "Audio Playback"; 277 substream->stream ? "Audio Capture" : "Audio Playback";
244 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 278 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
245 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 279 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
280 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
246 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 281 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
247 282
248 if (mcbsp_data->configured) { 283 if (mcbsp_data->configured) {