aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcbsp.c
diff options
context:
space:
mode:
authorEduardo Valentin <eduardo.valentin@nokia.com>2009-08-20 09:18:25 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-20 15:10:29 -0400
commitcaebc0cb3ba1e88f5311fbe7aa58b8dff18dd763 (patch)
tree875d14cdc7603da1fba730b2ac419cdb642afd73 /sound/soc/omap/omap-mcbsp.c
parentca6e2ce08679c094878d7f39a0349a7db1d13675 (diff)
ASoC: OMAP: Use McBSP threshold to playback and capture
This patch changes the way DMA is done in omap-pcm.c in order to reduce power consumption. There is no need to have so much SW control in order to have DMA in idle state during audio streaming. Configuring McBSP threshold value and DMA to FRAME_SYNC are sufficient. Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
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) {