.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * sst_mfld_platform.c - Intel MID Platform driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * Author: Vinod Koul <vinod.koul@intel.com> |
---|
6 | 7 | * Author: Harsha Priya <priya.harsha@intel.com> |
---|
7 | 8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License as published by |
---|
11 | | - * the Free Software Foundation; version 2 of the License. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, but |
---|
14 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
16 | | - * General Public License for more details. |
---|
17 | 9 | * |
---|
18 | 10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
19 | 11 | */ |
---|
.. | .. |
---|
190 | 182 | map = ctx->pdata->pdev_strm_map; |
---|
191 | 183 | map_size = ctx->pdata->strm_map_size; |
---|
192 | 184 | |
---|
193 | | - if (is_compress == true) |
---|
| 185 | + if (is_compress) |
---|
194 | 186 | cstream = (struct snd_compr_stream *)substream; |
---|
195 | 187 | else |
---|
196 | 188 | pstream = (struct snd_pcm_substream *)substream; |
---|
.. | .. |
---|
281 | 273 | { |
---|
282 | 274 | struct sst_runtime_stream *stream = |
---|
283 | 275 | substream->runtime->private_data; |
---|
284 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 276 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
285 | 277 | int ret_val; |
---|
286 | 278 | |
---|
287 | 279 | dev_dbg(rtd->dev, "setting buffer ptr param\n"); |
---|
.. | .. |
---|
340 | 332 | if (ret_val < 0) |
---|
341 | 333 | goto out_power_up; |
---|
342 | 334 | |
---|
| 335 | + /* |
---|
| 336 | + * Make sure the period to be multiple of 1ms to align the |
---|
| 337 | + * design of firmware. Apply same rule to buffer size to make |
---|
| 338 | + * sure alsa could always find a value for period size |
---|
| 339 | + * regardless the buffer size given by user space. |
---|
| 340 | + */ |
---|
| 341 | + snd_pcm_hw_constraint_step(substream->runtime, 0, |
---|
| 342 | + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48); |
---|
| 343 | + snd_pcm_hw_constraint_step(substream->runtime, 0, |
---|
| 344 | + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48); |
---|
| 345 | + |
---|
343 | 346 | /* Make sure, that the period size is always even */ |
---|
344 | 347 | snd_pcm_hw_constraint_step(substream->runtime, 0, |
---|
345 | 348 | SNDRV_PCM_HW_PARAM_PERIODS, 2); |
---|
.. | .. |
---|
373 | 376 | struct snd_soc_dai *dai) |
---|
374 | 377 | { |
---|
375 | 378 | struct sst_runtime_stream *stream; |
---|
376 | | - int ret_val = 0, str_id; |
---|
| 379 | + int ret_val, str_id; |
---|
377 | 380 | |
---|
378 | 381 | stream = substream->runtime->private_data; |
---|
379 | 382 | str_id = stream->stream_info.str_id; |
---|
.. | .. |
---|
392 | 395 | if (ret_val) |
---|
393 | 396 | return ret_val; |
---|
394 | 397 | substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER; |
---|
395 | | - return ret_val; |
---|
396 | | -} |
---|
397 | | - |
---|
398 | | -static int sst_media_hw_params(struct snd_pcm_substream *substream, |
---|
399 | | - struct snd_pcm_hw_params *params, |
---|
400 | | - struct snd_soc_dai *dai) |
---|
401 | | -{ |
---|
402 | | - int ret; |
---|
403 | | - |
---|
404 | | - ret = |
---|
405 | | - snd_pcm_lib_malloc_pages(substream, |
---|
406 | | - params_buffer_bytes(params)); |
---|
407 | | - if (ret) |
---|
408 | | - return ret; |
---|
409 | | - memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); |
---|
410 | 398 | return 0; |
---|
411 | | -} |
---|
412 | | - |
---|
413 | | -static int sst_media_hw_free(struct snd_pcm_substream *substream, |
---|
414 | | - struct snd_soc_dai *dai) |
---|
415 | | -{ |
---|
416 | | - return snd_pcm_lib_free_pages(substream); |
---|
417 | 399 | } |
---|
418 | 400 | |
---|
419 | 401 | static int sst_enable_ssp(struct snd_pcm_substream *substream, |
---|
.. | .. |
---|
421 | 403 | { |
---|
422 | 404 | int ret = 0; |
---|
423 | 405 | |
---|
424 | | - if (!dai->active) { |
---|
| 406 | + if (!snd_soc_dai_active(dai)) { |
---|
425 | 407 | ret = sst_handle_vb_timer(dai, true); |
---|
426 | 408 | sst_fill_ssp_defaults(dai); |
---|
427 | 409 | } |
---|
.. | .. |
---|
434 | 416 | { |
---|
435 | 417 | int ret = 0; |
---|
436 | 418 | |
---|
437 | | - if (dai->active == 1) |
---|
| 419 | + if (snd_soc_dai_active(dai) == 1) |
---|
438 | 420 | ret = send_ssp_cmd(dai, dai->name, 1); |
---|
439 | 421 | return ret; |
---|
440 | 422 | } |
---|
.. | .. |
---|
443 | 425 | { |
---|
444 | 426 | int ret = 0; |
---|
445 | 427 | |
---|
446 | | - if (!dai->active) |
---|
| 428 | + if (!snd_soc_dai_active(dai)) |
---|
447 | 429 | return 0; |
---|
448 | 430 | |
---|
449 | 431 | ret = sst_fill_ssp_config(dai, fmt); |
---|
.. | .. |
---|
458 | 440 | int slots, int slot_width) { |
---|
459 | 441 | int ret = 0; |
---|
460 | 442 | |
---|
461 | | - if (!dai->active) |
---|
| 443 | + if (!snd_soc_dai_active(dai)) |
---|
462 | 444 | return ret; |
---|
463 | 445 | |
---|
464 | 446 | ret = sst_fill_ssp_slot(dai, tx_mask, rx_mask, slots, slot_width); |
---|
.. | .. |
---|
471 | 453 | static void sst_disable_ssp(struct snd_pcm_substream *substream, |
---|
472 | 454 | struct snd_soc_dai *dai) |
---|
473 | 455 | { |
---|
474 | | - if (!dai->active) { |
---|
| 456 | + if (!snd_soc_dai_active(dai)) { |
---|
475 | 457 | send_ssp_cmd(dai, dai->name, 0); |
---|
476 | 458 | sst_handle_vb_timer(dai, false); |
---|
477 | 459 | } |
---|
.. | .. |
---|
481 | 463 | .startup = sst_media_open, |
---|
482 | 464 | .shutdown = sst_media_close, |
---|
483 | 465 | .prepare = sst_media_prepare, |
---|
484 | | - .hw_params = sst_media_hw_params, |
---|
485 | | - .hw_free = sst_media_hw_free, |
---|
486 | 466 | .mute_stream = sst_media_digital_mute, |
---|
487 | 467 | }; |
---|
488 | 468 | |
---|
.. | .. |
---|
594 | 574 | }, |
---|
595 | 575 | }; |
---|
596 | 576 | |
---|
597 | | -static int sst_platform_open(struct snd_pcm_substream *substream) |
---|
| 577 | +static int sst_soc_open(struct snd_soc_component *component, |
---|
| 578 | + struct snd_pcm_substream *substream) |
---|
598 | 579 | { |
---|
599 | 580 | struct snd_pcm_runtime *runtime; |
---|
600 | 581 | |
---|
.. | .. |
---|
606 | 587 | return 0; |
---|
607 | 588 | } |
---|
608 | 589 | |
---|
609 | | -static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, |
---|
610 | | - int cmd) |
---|
| 590 | +static int sst_soc_trigger(struct snd_soc_component *component, |
---|
| 591 | + struct snd_pcm_substream *substream, int cmd) |
---|
611 | 592 | { |
---|
612 | 593 | int ret_val = 0, str_id; |
---|
613 | 594 | struct sst_runtime_stream *stream; |
---|
614 | 595 | int status; |
---|
615 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 596 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
616 | 597 | |
---|
617 | | - dev_dbg(rtd->dev, "sst_platform_pcm_trigger called\n"); |
---|
| 598 | + dev_dbg(rtd->dev, "%s called\n", __func__); |
---|
618 | 599 | if (substream->pcm->internal) |
---|
619 | 600 | return 0; |
---|
620 | 601 | stream = substream->runtime->private_data; |
---|
.. | .. |
---|
654 | 635 | } |
---|
655 | 636 | |
---|
656 | 637 | |
---|
657 | | -static snd_pcm_uframes_t sst_platform_pcm_pointer |
---|
658 | | - (struct snd_pcm_substream *substream) |
---|
| 638 | +static snd_pcm_uframes_t sst_soc_pointer(struct snd_soc_component *component, |
---|
| 639 | + struct snd_pcm_substream *substream) |
---|
659 | 640 | { |
---|
660 | 641 | struct sst_runtime_stream *stream; |
---|
661 | 642 | int ret_val, status; |
---|
662 | 643 | struct pcm_stream_info *str_info; |
---|
663 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 644 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
664 | 645 | |
---|
665 | 646 | stream = substream->runtime->private_data; |
---|
666 | 647 | status = sst_get_stream_status(stream); |
---|
.. | .. |
---|
676 | 657 | return str_info->buffer_ptr; |
---|
677 | 658 | } |
---|
678 | 659 | |
---|
679 | | -static const struct snd_pcm_ops sst_platform_ops = { |
---|
680 | | - .open = sst_platform_open, |
---|
681 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
682 | | - .trigger = sst_platform_pcm_trigger, |
---|
683 | | - .pointer = sst_platform_pcm_pointer, |
---|
684 | | -}; |
---|
685 | | - |
---|
686 | | -static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) |
---|
| 660 | +static int sst_soc_pcm_new(struct snd_soc_component *component, |
---|
| 661 | + struct snd_soc_pcm_runtime *rtd) |
---|
687 | 662 | { |
---|
688 | | - struct snd_soc_dai *dai = rtd->cpu_dai; |
---|
| 663 | + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); |
---|
689 | 664 | struct snd_pcm *pcm = rtd->pcm; |
---|
690 | | - int retval = 0; |
---|
691 | 665 | |
---|
692 | 666 | if (dai->driver->playback.channels_min || |
---|
693 | 667 | dai->driver->capture.channels_min) { |
---|
694 | | - retval = snd_pcm_lib_preallocate_pages_for_all(pcm, |
---|
| 668 | + snd_pcm_set_managed_buffer_all(pcm, |
---|
695 | 669 | SNDRV_DMA_TYPE_CONTINUOUS, |
---|
696 | 670 | snd_dma_continuous_data(GFP_DMA), |
---|
697 | 671 | SST_MIN_BUFFER, SST_MAX_BUFFER); |
---|
698 | | - if (retval) { |
---|
699 | | - dev_err(rtd->dev, "dma buffer allocation failure\n"); |
---|
700 | | - return retval; |
---|
701 | | - } |
---|
702 | 672 | } |
---|
703 | | - return retval; |
---|
| 673 | + return 0; |
---|
704 | 674 | } |
---|
705 | 675 | |
---|
706 | 676 | static int sst_soc_probe(struct snd_soc_component *component) |
---|
.. | .. |
---|
722 | 692 | .name = DRV_NAME, |
---|
723 | 693 | .probe = sst_soc_probe, |
---|
724 | 694 | .remove = sst_soc_remove, |
---|
725 | | - .ops = &sst_platform_ops, |
---|
726 | | - .compr_ops = &sst_platform_compr_ops, |
---|
727 | | - .pcm_new = sst_pcm_new, |
---|
| 695 | + .open = sst_soc_open, |
---|
| 696 | + .trigger = sst_soc_trigger, |
---|
| 697 | + .pointer = sst_soc_pointer, |
---|
| 698 | + .compress_ops = &sst_platform_compress_ops, |
---|
| 699 | + .pcm_construct = sst_soc_pcm_new, |
---|
728 | 700 | }; |
---|
729 | 701 | |
---|
730 | 702 | static int sst_platform_probe(struct platform_device *pdev) |
---|
.. | .. |
---|
779 | 751 | snd_soc_poweroff(drv->soc_card->dev); |
---|
780 | 752 | |
---|
781 | 753 | /* set the SSPs to idle */ |
---|
782 | | - list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) { |
---|
783 | | - struct snd_soc_dai *dai = rtd->cpu_dai; |
---|
| 754 | + for_each_card_rtds(drv->soc_card, rtd) { |
---|
| 755 | + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); |
---|
784 | 756 | |
---|
785 | | - if (dai->active) { |
---|
| 757 | + if (snd_soc_dai_active(dai)) { |
---|
786 | 758 | send_ssp_cmd(dai, dai->name, 0); |
---|
787 | 759 | sst_handle_vb_timer(dai, false); |
---|
788 | 760 | } |
---|
.. | .. |
---|
800 | 772 | return; |
---|
801 | 773 | |
---|
802 | 774 | /* restart SSPs */ |
---|
803 | | - list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) { |
---|
804 | | - struct snd_soc_dai *dai = rtd->cpu_dai; |
---|
| 775 | + for_each_card_rtds(drv->soc_card, rtd) { |
---|
| 776 | + struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); |
---|
805 | 777 | |
---|
806 | | - if (dai->active) { |
---|
| 778 | + if (snd_soc_dai_active(dai)) { |
---|
807 | 779 | sst_handle_vb_timer(dai, true); |
---|
808 | 780 | send_ssp_cmd(dai, dai->name, 1); |
---|
809 | 781 | } |
---|