diff options
author | Vinod Koul <vinod.koul@intel.com> | 2014-06-13 08:33:51 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-21 11:31:00 -0400 |
commit | 6cc0f4e63994a2b77fb6cd7c3bc1e25b7bdb9881 (patch) | |
tree | ba5172cd937e50a5ea3caf59f10897c1713d2cb0 | |
parent | c9a8e3bd3df0e25d4ac9f6be1ba294004bb0bc9a (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.c | 112 |
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 | ||
233 | static int sst_platform_open(struct snd_pcm_substream *substream) | 233 | static 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); | ||
268 | out_ops: | ||
269 | kfree(stream); | ||
270 | mutex_unlock(&sst_lock); | ||
271 | return ret_val; | ||
275 | } | 272 | } |
276 | 273 | ||
277 | static int sst_platform_close(struct snd_pcm_substream *substream) | 274 | static 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 | ||
292 | static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) | 289 | static 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 | ||
316 | static 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 | |||
325 | static 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 | |||
331 | static 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 | |||
339 | static 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 | |||
319 | static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, | 351 | static 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 | |||
383 | static 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 | |||
392 | static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream) | ||
393 | { | ||
394 | return snd_pcm_lib_free_pages(substream); | ||
395 | } | 413 | } |
396 | 414 | ||
397 | static struct snd_pcm_ops sst_platform_ops = { | 415 | static 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 | ||
408 | static void sst_pcm_free(struct snd_pcm *pcm) | 422 | static void sst_pcm_free(struct snd_pcm *pcm) |
@@ -413,15 +427,15 @@ static void sst_pcm_free(struct snd_pcm *pcm) | |||
413 | 427 | ||
414 | static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | 428 | static 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"); |