aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2014-06-13 08:33:51 -0400
committerMark Brown <broonie@linaro.org>2014-06-21 11:31:00 -0400
commit6cc0f4e63994a2b77fb6cd7c3bc1e25b7bdb9881 (patch)
treeba5172cd937e50a5ea3caf59f10897c1713d2cb0
parentc9a8e3bd3df0e25d4ac9f6be1ba294004bb0bc9a (diff)
ASoC: Intel: mfld_pcm: move stream handling to dai_ops
This helps us to handle pcm and compress ops seperately and per dai Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/intel/sst-mfld-platform-pcm.c112
1 files changed, 63 insertions, 49 deletions
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c
index 7c790f51d259..0d46005752bc 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/sst-mfld-platform-pcm.c
@@ -230,19 +230,12 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
230} 230}
231/* end -- helper functions */ 231/* end -- helper functions */
232 232
233static int sst_platform_open(struct snd_pcm_substream *substream) 233static int sst_media_open(struct snd_pcm_substream *substream,
234 struct snd_soc_dai *dai)
234{ 235{
236 int ret_val = 0;
235 struct snd_pcm_runtime *runtime = substream->runtime; 237 struct snd_pcm_runtime *runtime = substream->runtime;
236 struct sst_runtime_stream *stream; 238 struct sst_runtime_stream *stream;
237 int ret_val;
238
239 pr_debug("sst_platform_open called\n");
240
241 snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw);
242 ret_val = snd_pcm_hw_constraint_integer(runtime,
243 SNDRV_PCM_HW_PARAM_PERIODS);
244 if (ret_val < 0)
245 return ret_val;
246 239
247 stream = kzalloc(sizeof(*stream), GFP_KERNEL); 240 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
248 if (!stream) 241 if (!stream)
@@ -251,50 +244,54 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
251 244
252 /* get the sst ops */ 245 /* get the sst ops */
253 mutex_lock(&sst_lock); 246 mutex_lock(&sst_lock);
254 if (!sst) { 247 if (!sst ||
248 !try_module_get(sst->dev->driver->owner)) {
255 pr_err("no device available to run\n"); 249 pr_err("no device available to run\n");
256 mutex_unlock(&sst_lock); 250 ret_val = -ENODEV;
257 kfree(stream); 251 goto out_ops;
258 return -ENODEV;
259 }
260 if (!try_module_get(sst->dev->driver->owner)) {
261 mutex_unlock(&sst_lock);
262 kfree(stream);
263 return -ENODEV;
264 } 252 }
265 stream->ops = sst->ops; 253 stream->ops = sst->ops;
266 mutex_unlock(&sst_lock); 254 mutex_unlock(&sst_lock);
267 255
268 stream->stream_info.str_id = 0; 256 stream->stream_info.str_id = 0;
269 sst_set_stream_status(stream, SST_PLATFORM_INIT); 257
270 stream->stream_info.mad_substream = substream; 258 stream->stream_info.mad_substream = substream;
271 /* allocate memory for SST API set */ 259 /* allocate memory for SST API set */
272 runtime->private_data = stream; 260 runtime->private_data = stream;
273 261
274 return 0; 262 /* Make sure, that the period size is always even */
263 snd_pcm_hw_constraint_step(substream->runtime, 0,
264 SNDRV_PCM_HW_PARAM_PERIODS, 2);
265
266 return snd_pcm_hw_constraint_integer(runtime,
267 SNDRV_PCM_HW_PARAM_PERIODS);
268out_ops:
269 kfree(stream);
270 mutex_unlock(&sst_lock);
271 return ret_val;
275} 272}
276 273
277static int sst_platform_close(struct snd_pcm_substream *substream) 274static void sst_media_close(struct snd_pcm_substream *substream,
275 struct snd_soc_dai *dai)
278{ 276{
279 struct sst_runtime_stream *stream; 277 struct sst_runtime_stream *stream;
280 int ret_val = 0, str_id; 278 int ret_val = 0, str_id;
281 279
282 pr_debug("sst_platform_close called\n");
283 stream = substream->runtime->private_data; 280 stream = substream->runtime->private_data;
284 str_id = stream->stream_info.str_id; 281 str_id = stream->stream_info.str_id;
285 if (str_id) 282 if (str_id)
286 ret_val = stream->ops->close(str_id); 283 ret_val = stream->ops->close(str_id);
287 module_put(sst->dev->driver->owner); 284 module_put(sst->dev->driver->owner);
288 kfree(stream); 285 kfree(stream);
289 return ret_val; 286 return;
290} 287}
291 288
292static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) 289static int sst_media_prepare(struct snd_pcm_substream *substream,
290 struct snd_soc_dai *dai)
293{ 291{
294 struct sst_runtime_stream *stream; 292 struct sst_runtime_stream *stream;
295 int ret_val = 0, str_id; 293 int ret_val = 0, str_id;
296 294
297 pr_debug("sst_platform_pcm_prepare called\n");
298 stream = substream->runtime->private_data; 295 stream = substream->runtime->private_data;
299 str_id = stream->stream_info.str_id; 296 str_id = stream->stream_info.str_id;
300 if (stream->stream_info.str_id) { 297 if (stream->stream_info.str_id) {
@@ -316,6 +313,41 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
316 return ret_val; 313 return ret_val;
317} 314}
318 315
316static int sst_media_hw_params(struct snd_pcm_substream *substream,
317 struct snd_pcm_hw_params *params,
318 struct snd_soc_dai *dai)
319{
320 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
321 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
322 return 0;
323}
324
325static int sst_media_hw_free(struct snd_pcm_substream *substream,
326 struct snd_soc_dai *dai)
327{
328 return snd_pcm_lib_free_pages(substream);
329}
330
331static struct snd_soc_dai_ops sst_media_dai_ops = {
332 .startup = sst_media_open,
333 .shutdown = sst_media_close,
334 .prepare = sst_media_prepare,
335 .hw_params = sst_media_hw_params,
336 .hw_free = sst_media_hw_free,
337};
338
339static int sst_platform_open(struct snd_pcm_substream *substream)
340{
341 struct snd_pcm_runtime *runtime;
342
343 if (substream->pcm->internal)
344 return 0;
345
346 runtime = substream->runtime;
347 runtime->hw = sst_platform_pcm_hw;
348 return 0;
349}
350
319static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 351static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
320 int cmd) 352 int cmd)
321{ 353{
@@ -377,32 +409,14 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
377 pr_err("sst: error code = %d\n", ret_val); 409 pr_err("sst: error code = %d\n", ret_val);
378 return ret_val; 410 return ret_val;
379 } 411 }
380 return stream->stream_info.buffer_ptr; 412 return str_info->buffer_ptr;
381}
382
383static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
384 struct snd_pcm_hw_params *params)
385{
386 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
387 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
388
389 return 0;
390}
391
392static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream)
393{
394 return snd_pcm_lib_free_pages(substream);
395} 413}
396 414
397static struct snd_pcm_ops sst_platform_ops = { 415static struct snd_pcm_ops sst_platform_ops = {
398 .open = sst_platform_open, 416 .open = sst_platform_open,
399 .close = sst_platform_close,
400 .ioctl = snd_pcm_lib_ioctl, 417 .ioctl = snd_pcm_lib_ioctl,
401 .prepare = sst_platform_pcm_prepare,
402 .trigger = sst_platform_pcm_trigger, 418 .trigger = sst_platform_pcm_trigger,
403 .pointer = sst_platform_pcm_pointer, 419 .pointer = sst_platform_pcm_pointer,
404 .hw_params = sst_platform_pcm_hw_params,
405 .hw_free = sst_platform_pcm_hw_free,
406}; 420};
407 421
408static void sst_pcm_free(struct snd_pcm *pcm) 422static void sst_pcm_free(struct snd_pcm *pcm)
@@ -413,15 +427,15 @@ static void sst_pcm_free(struct snd_pcm *pcm)
413 427
414static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) 428static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
415{ 429{
430 struct snd_soc_dai *dai = rtd->cpu_dai;
416 struct snd_pcm *pcm = rtd->pcm; 431 struct snd_pcm *pcm = rtd->pcm;
417 int retval = 0; 432 int retval = 0;
418 433
419 pr_debug("sst_pcm_new called\n"); 434 if (dai->driver->playback.channels_min ||
420 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || 435 dai->driver->capture.channels_min) {
421 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
422 retval = snd_pcm_lib_preallocate_pages_for_all(pcm, 436 retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
423 SNDRV_DMA_TYPE_CONTINUOUS, 437 SNDRV_DMA_TYPE_CONTINUOUS,
424 snd_dma_continuous_data(GFP_KERNEL), 438 snd_dma_continuous_data(GFP_DMA),
425 SST_MIN_BUFFER, SST_MAX_BUFFER); 439 SST_MIN_BUFFER, SST_MAX_BUFFER);
426 if (retval) { 440 if (retval) {
427 pr_err("dma buffer allocationf fail\n"); 441 pr_err("dma buffer allocationf fail\n");