soc-pcm.c (4f2bd18b191a10660782f2f1ccc989b000b2be63) | soc-pcm.c (4febced15ac8ddb9cf3e603edb111842e4863d9a) |
---|---|
1/* 2 * soc-pcm.c -- ALSA SoC PCM 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Copyright 2005 Openedhand Ltd. 6 * Copyright (C) 2010 Slimlogic Ltd. 7 * Copyright (C) 2010 Texas Instruments Inc. 8 * --- 434 unchanged lines hidden (view full) --- 443 snd_pcm_limit_hw_rates(runtime); 444 445 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min); 446 hw->rate_min = max(hw->rate_min, rate_min); 447 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max); 448 hw->rate_max = min_not_zero(hw->rate_max, rate_max); 449} 450 | 1/* 2 * soc-pcm.c -- ALSA SoC PCM 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Copyright 2005 Openedhand Ltd. 6 * Copyright (C) 2010 Slimlogic Ltd. 7 * Copyright (C) 2010 Texas Instruments Inc. 8 * --- 434 unchanged lines hidden (view full) --- 443 snd_pcm_limit_hw_rates(runtime); 444 445 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min); 446 hw->rate_min = max(hw->rate_min, rate_min); 447 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max); 448 hw->rate_max = min_not_zero(hw->rate_max, rate_max); 449} 450 |
451static int soc_pcm_components_close(struct snd_pcm_substream *substream, 452 struct snd_soc_component *last) 453{ 454 struct snd_soc_pcm_runtime *rtd = substream->private_data; 455 struct snd_soc_rtdcom_list *rtdcom; 456 struct snd_soc_component *component; 457 458 for_each_rtdcom(rtd, rtdcom) { 459 component = rtdcom->component; 460 461 if (component == last) 462 break; 463 464 if (!component->driver->ops || 465 !component->driver->ops->close) 466 continue; 467 468 component->driver->ops->close(substream); 469 } 470 471 return 0; 472} 473 | |
474/* 475 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 476 * then initialized and any private data can be allocated. This also calls 477 * startup for the cpu DAI, component, machine and codec DAI. 478 */ 479static int soc_pcm_open(struct snd_pcm_substream *substream) 480{ 481 struct snd_soc_pcm_runtime *rtd = substream->private_data; 482 struct snd_pcm_runtime *runtime = substream->runtime; 483 struct snd_soc_component *component; 484 struct snd_soc_rtdcom_list *rtdcom; 485 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 486 struct snd_soc_dai *codec_dai; 487 const char *codec_dai_name = "multicodec"; | 451/* 452 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 453 * then initialized and any private data can be allocated. This also calls 454 * startup for the cpu DAI, component, machine and codec DAI. 455 */ 456static int soc_pcm_open(struct snd_pcm_substream *substream) 457{ 458 struct snd_soc_pcm_runtime *rtd = substream->private_data; 459 struct snd_pcm_runtime *runtime = substream->runtime; 460 struct snd_soc_component *component; 461 struct snd_soc_rtdcom_list *rtdcom; 462 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 463 struct snd_soc_dai *codec_dai; 464 const char *codec_dai_name = "multicodec"; |
488 int i, ret = 0; | 465 int i, ret = 0, __ret; |
489 490 pinctrl_pm_select_default_state(cpu_dai->dev); 491 for (i = 0; i < rtd->num_codecs; i++) 492 pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev); 493 494 for_each_rtdcom(rtd, rtdcom) { 495 component = rtdcom->component; 496 --- 7 unchanged lines hidden (view full) --- 504 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 505 if (ret < 0) { 506 dev_err(cpu_dai->dev, "ASoC: can't open interface" 507 " %s: %d\n", cpu_dai->name, ret); 508 goto out; 509 } 510 } 511 | 466 467 pinctrl_pm_select_default_state(cpu_dai->dev); 468 for (i = 0; i < rtd->num_codecs; i++) 469 pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev); 470 471 for_each_rtdcom(rtd, rtdcom) { 472 component = rtdcom->component; 473 --- 7 unchanged lines hidden (view full) --- 481 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 482 if (ret < 0) { 483 dev_err(cpu_dai->dev, "ASoC: can't open interface" 484 " %s: %d\n", cpu_dai->name, ret); 485 goto out; 486 } 487 } 488 |
489 ret = 0; |
|
512 for_each_rtdcom(rtd, rtdcom) { 513 component = rtdcom->component; 514 515 if (!component->driver->ops || 516 !component->driver->ops->open) 517 continue; 518 | 490 for_each_rtdcom(rtd, rtdcom) { 491 component = rtdcom->component; 492 493 if (!component->driver->ops || 494 !component->driver->ops->open) 495 continue; 496 |
519 ret = component->driver->ops->open(substream); 520 if (ret < 0) { | 497 __ret = component->driver->ops->open(substream); 498 if (__ret < 0) { |
521 dev_err(component->dev, 522 "ASoC: can't open component %s: %d\n", | 499 dev_err(component->dev, 500 "ASoC: can't open component %s: %d\n", |
523 component->name, ret); 524 goto component_err; | 501 component->name, __ret); 502 ret = __ret; |
525 } 526 } | 503 } 504 } |
527 component = NULL; | 505 if (ret < 0) 506 goto component_err; |
528 529 for (i = 0; i < rtd->num_codecs; i++) { 530 codec_dai = rtd->codec_dais[i]; 531 if (codec_dai->driver->ops->startup) { 532 ret = codec_dai->driver->ops->startup(substream, 533 codec_dai); 534 if (ret < 0) { 535 dev_err(codec_dai->dev, --- 92 unchanged lines hidden (view full) --- 628codec_dai_err: 629 while (--i >= 0) { 630 codec_dai = rtd->codec_dais[i]; 631 if (codec_dai->driver->ops->shutdown) 632 codec_dai->driver->ops->shutdown(substream, codec_dai); 633 } 634 635component_err: | 507 508 for (i = 0; i < rtd->num_codecs; i++) { 509 codec_dai = rtd->codec_dais[i]; 510 if (codec_dai->driver->ops->startup) { 511 ret = codec_dai->driver->ops->startup(substream, 512 codec_dai); 513 if (ret < 0) { 514 dev_err(codec_dai->dev, --- 92 unchanged lines hidden (view full) --- 607codec_dai_err: 608 while (--i >= 0) { 609 codec_dai = rtd->codec_dais[i]; 610 if (codec_dai->driver->ops->shutdown) 611 codec_dai->driver->ops->shutdown(substream, codec_dai); 612 } 613 614component_err: |
636 soc_pcm_components_close(substream, component); | 615 for_each_rtdcom(rtd, rtdcom) { 616 component = rtdcom->component; |
637 | 617 |
618 if (!component->driver->ops || 619 !component->driver->ops->close) 620 continue; 621 622 component->driver->ops->close(substream); 623 } 624 |
|
638 if (cpu_dai->driver->ops->shutdown) 639 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 640out: 641 mutex_unlock(&rtd->pcm_mutex); 642 643 for_each_rtdcom(rtd, rtdcom) { 644 component = rtdcom->component; 645 --- 76 unchanged lines hidden (view full) --- 722 codec_dai = rtd->codec_dais[i]; 723 if (codec_dai->driver->ops->shutdown) 724 codec_dai->driver->ops->shutdown(substream, codec_dai); 725 } 726 727 if (rtd->dai_link->ops->shutdown) 728 rtd->dai_link->ops->shutdown(substream); 729 | 625 if (cpu_dai->driver->ops->shutdown) 626 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 627out: 628 mutex_unlock(&rtd->pcm_mutex); 629 630 for_each_rtdcom(rtd, rtdcom) { 631 component = rtdcom->component; 632 --- 76 unchanged lines hidden (view full) --- 709 codec_dai = rtd->codec_dais[i]; 710 if (codec_dai->driver->ops->shutdown) 711 codec_dai->driver->ops->shutdown(substream, codec_dai); 712 } 713 714 if (rtd->dai_link->ops->shutdown) 715 rtd->dai_link->ops->shutdown(substream); 716 |
730 soc_pcm_components_close(substream, NULL); | 717 for_each_rtdcom(rtd, rtdcom) { 718 component = rtdcom->component; |
731 | 719 |
720 if (!component->driver->ops || 721 !component->driver->ops->close) 722 continue; 723 724 component->driver->ops->close(substream); 725 } 726 |
|
732 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 733 if (snd_soc_runtime_ignore_pmdown_time(rtd)) { 734 /* powered down playback stream now */ 735 snd_soc_dapm_stream_event(rtd, 736 SNDRV_PCM_STREAM_PLAYBACK, 737 SND_SOC_DAPM_STREAM_STOP); 738 } else { 739 /* start delayed pop wq here for playback streams */ --- 134 unchanged lines hidden (view full) --- 874 dai->name, ret); 875 return ret; 876 } 877 } 878 879 return 0; 880} 881 | 727 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 728 if (snd_soc_runtime_ignore_pmdown_time(rtd)) { 729 /* powered down playback stream now */ 730 snd_soc_dapm_stream_event(rtd, 731 SNDRV_PCM_STREAM_PLAYBACK, 732 SND_SOC_DAPM_STREAM_STOP); 733 } else { 734 /* start delayed pop wq here for playback streams */ --- 134 unchanged lines hidden (view full) --- 869 dai->name, ret); 870 return ret; 871 } 872 } 873 874 return 0; 875} 876 |
882static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream, 883 struct snd_soc_component *last) 884{ 885 struct snd_soc_pcm_runtime *rtd = substream->private_data; 886 struct snd_soc_rtdcom_list *rtdcom; 887 struct snd_soc_component *component; 888 889 for_each_rtdcom(rtd, rtdcom) { 890 component = rtdcom->component; 891 892 if (component == last) 893 break; 894 895 if (!component->driver->ops || 896 !component->driver->ops->hw_free) 897 continue; 898 899 component->driver->ops->hw_free(substream); 900 } 901 902 return 0; 903} 904 | |
905/* 906 * Called by ALSA when the hardware params are set by application. This 907 * function can also be called multiple times and can allocate buffers 908 * (using snd_pcm_lib_* ). It's non-atomic. 909 */ 910static int soc_pcm_hw_params(struct snd_pcm_substream *substream, 911 struct snd_pcm_hw_params *params) 912{ 913 struct snd_soc_pcm_runtime *rtd = substream->private_data; 914 struct snd_soc_component *component; 915 struct snd_soc_rtdcom_list *rtdcom; 916 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 877/* 878 * Called by ALSA when the hardware params are set by application. This 879 * function can also be called multiple times and can allocate buffers 880 * (using snd_pcm_lib_* ). It's non-atomic. 881 */ 882static int soc_pcm_hw_params(struct snd_pcm_substream *substream, 883 struct snd_pcm_hw_params *params) 884{ 885 struct snd_soc_pcm_runtime *rtd = substream->private_data; 886 struct snd_soc_component *component; 887 struct snd_soc_rtdcom_list *rtdcom; 888 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
917 int i, ret = 0; | 889 int i, ret = 0, __ret; |
918 919 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 920 if (rtd->dai_link->ops->hw_params) { 921 ret = rtd->dai_link->ops->hw_params(substream, params); 922 if (ret < 0) { 923 dev_err(rtd->card->dev, "ASoC: machine hw_params" 924 " failed: %d\n", ret); 925 goto out; --- 41 unchanged lines hidden (view full) --- 967 codec_dai->sample_bits = snd_pcm_format_physical_width( 968 params_format(&codec_params)); 969 } 970 971 ret = soc_dai_hw_params(substream, params, cpu_dai); 972 if (ret < 0) 973 goto interface_err; 974 | 890 891 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 892 if (rtd->dai_link->ops->hw_params) { 893 ret = rtd->dai_link->ops->hw_params(substream, params); 894 if (ret < 0) { 895 dev_err(rtd->card->dev, "ASoC: machine hw_params" 896 " failed: %d\n", ret); 897 goto out; --- 41 unchanged lines hidden (view full) --- 939 codec_dai->sample_bits = snd_pcm_format_physical_width( 940 params_format(&codec_params)); 941 } 942 943 ret = soc_dai_hw_params(substream, params, cpu_dai); 944 if (ret < 0) 945 goto interface_err; 946 |
947 ret = 0; |
|
975 for_each_rtdcom(rtd, rtdcom) { 976 component = rtdcom->component; 977 978 if (!component->driver->ops || 979 !component->driver->ops->hw_params) 980 continue; 981 | 948 for_each_rtdcom(rtd, rtdcom) { 949 component = rtdcom->component; 950 951 if (!component->driver->ops || 952 !component->driver->ops->hw_params) 953 continue; 954 |
982 ret = component->driver->ops->hw_params(substream, params); 983 if (ret < 0) { | 955 __ret = component->driver->ops->hw_params(substream, params); 956 if (__ret < 0) { |
984 dev_err(component->dev, 985 "ASoC: %s hw params failed: %d\n", | 957 dev_err(component->dev, 958 "ASoC: %s hw params failed: %d\n", |
986 component->name, ret); 987 goto component_err; | 959 component->name, __ret); 960 ret = __ret; |
988 } 989 } | 961 } 962 } |
990 component = NULL; | 963 if (ret < 0) 964 goto component_err; |
991 992 /* store the parameters for each DAIs */ 993 cpu_dai->rate = params_rate(params); 994 cpu_dai->channels = params_channels(params); 995 cpu_dai->sample_bits = 996 snd_pcm_format_physical_width(params_format(params)); 997 998 ret = soc_pcm_params_symmetry(substream, params); 999 if (ret) 1000 goto component_err; 1001out: 1002 mutex_unlock(&rtd->pcm_mutex); 1003 return ret; 1004 1005component_err: | 965 966 /* store the parameters for each DAIs */ 967 cpu_dai->rate = params_rate(params); 968 cpu_dai->channels = params_channels(params); 969 cpu_dai->sample_bits = 970 snd_pcm_format_physical_width(params_format(params)); 971 972 ret = soc_pcm_params_symmetry(substream, params); 973 if (ret) 974 goto component_err; 975out: 976 mutex_unlock(&rtd->pcm_mutex); 977 return ret; 978 979component_err: |
1006 soc_pcm_components_hw_free(substream, component); | 980 for_each_rtdcom(rtd, rtdcom) { 981 component = rtdcom->component; |
1007 | 982 |
983 if (!component->driver->ops || 984 !component->driver->ops->hw_free) 985 continue; 986 987 component->driver->ops->hw_free(substream); 988 } 989 |
|
1008 if (cpu_dai->driver->ops->hw_free) 1009 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 1010 1011interface_err: 1012 i = rtd->num_codecs; 1013 1014codec_err: 1015 while (--i >= 0) { --- 11 unchanged lines hidden (view full) --- 1027} 1028 1029/* 1030 * Frees resources allocated by hw_params, can be called multiple times 1031 */ 1032static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 1033{ 1034 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 990 if (cpu_dai->driver->ops->hw_free) 991 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 992 993interface_err: 994 i = rtd->num_codecs; 995 996codec_err: 997 while (--i >= 0) { --- 11 unchanged lines hidden (view full) --- 1009} 1010 1011/* 1012 * Frees resources allocated by hw_params, can be called multiple times 1013 */ 1014static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 1015{ 1016 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1017 struct snd_soc_component *component; 1018 struct snd_soc_rtdcom_list *rtdcom; |
|
1035 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1036 struct snd_soc_dai *codec_dai; 1037 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 1038 int i; 1039 1040 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 1041 1042 /* clear the corresponding DAIs parameters when going to be inactive */ --- 20 unchanged lines hidden (view full) --- 1063 substream->stream); 1064 } 1065 1066 /* free any machine hw params */ 1067 if (rtd->dai_link->ops->hw_free) 1068 rtd->dai_link->ops->hw_free(substream); 1069 1070 /* free any component resources */ | 1019 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1020 struct snd_soc_dai *codec_dai; 1021 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 1022 int i; 1023 1024 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 1025 1026 /* clear the corresponding DAIs parameters when going to be inactive */ --- 20 unchanged lines hidden (view full) --- 1047 substream->stream); 1048 } 1049 1050 /* free any machine hw params */ 1051 if (rtd->dai_link->ops->hw_free) 1052 rtd->dai_link->ops->hw_free(substream); 1053 1054 /* free any component resources */ |
1071 soc_pcm_components_hw_free(substream, NULL); | 1055 for_each_rtdcom(rtd, rtdcom) { 1056 component = rtdcom->component; |
1072 | 1057 |
1058 if (!component->driver->ops || 1059 !component->driver->ops->hw_free) 1060 continue; 1061 1062 component->driver->ops->hw_free(substream); 1063 } 1064 |
|
1073 /* now free hw params for the DAIs */ 1074 for (i = 0; i < rtd->num_codecs; i++) { 1075 codec_dai = rtd->codec_dais[i]; 1076 if (codec_dai->driver->ops->hw_free) 1077 codec_dai->driver->ops->hw_free(substream, codec_dai); 1078 } 1079 1080 if (cpu_dai->driver->ops->hw_free) --- 616 unchanged lines hidden (view full) --- 1697 1698 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1699 struct snd_soc_pcm_runtime *be = dpcm->be; 1700 struct snd_soc_dai_driver *codec_dai_drv; 1701 struct snd_soc_pcm_stream *codec_stream; 1702 int i; 1703 1704 for (i = 0; i < be->num_codecs; i++) { | 1065 /* now free hw params for the DAIs */ 1066 for (i = 0; i < rtd->num_codecs; i++) { 1067 codec_dai = rtd->codec_dais[i]; 1068 if (codec_dai->driver->ops->hw_free) 1069 codec_dai->driver->ops->hw_free(substream, codec_dai); 1070 } 1071 1072 if (cpu_dai->driver->ops->hw_free) --- 616 unchanged lines hidden (view full) --- 1689 1690 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1691 struct snd_soc_pcm_runtime *be = dpcm->be; 1692 struct snd_soc_dai_driver *codec_dai_drv; 1693 struct snd_soc_pcm_stream *codec_stream; 1694 int i; 1695 1696 for (i = 0; i < be->num_codecs; i++) { |
1697 /* 1698 * Skip CODECs which don't support the current stream 1699 * type. See soc_pcm_init_runtime_hw() for more details 1700 */ 1701 if (!snd_soc_dai_stream_valid(be->codec_dais[i], 1702 stream)) 1703 continue; 1704 |
|
1705 codec_dai_drv = be->codec_dais[i]->driver; 1706 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1707 codec_stream = &codec_dai_drv->playback; 1708 else 1709 codec_stream = &codec_dai_drv->capture; 1710 1711 formats &= codec_stream->formats; 1712 } 1713 } 1714 1715 return formats; 1716} 1717 | 1705 codec_dai_drv = be->codec_dais[i]->driver; 1706 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1707 codec_stream = &codec_dai_drv->playback; 1708 else 1709 codec_stream = &codec_dai_drv->capture; 1710 1711 formats &= codec_stream->formats; 1712 } 1713 } 1714 1715 return formats; 1716} 1717 |
1718static void dpcm_runtime_base_chan(struct snd_pcm_substream *substream, 1719 unsigned int *channels_min, 1720 unsigned int *channels_max) 1721{ 1722 struct snd_soc_pcm_runtime *fe = substream->private_data; 1723 struct snd_soc_dpcm *dpcm; 1724 int stream = substream->stream; 1725 1726 if (!fe->dai_link->dpcm_merged_chan) 1727 return; 1728 1729 *channels_min = 0; 1730 *channels_max = UINT_MAX; 1731 1732 /* 1733 * It returns merged BE codec channel; 1734 * if FE want to use it (= dpcm_merged_chan) 1735 */ 1736 1737 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1738 struct snd_soc_pcm_runtime *be = dpcm->be; 1739 struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver; 1740 struct snd_soc_dai_driver *codec_dai_drv; 1741 struct snd_soc_pcm_stream *codec_stream; 1742 struct snd_soc_pcm_stream *cpu_stream; 1743 1744 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1745 cpu_stream = &cpu_dai_drv->playback; 1746 else 1747 cpu_stream = &cpu_dai_drv->capture; 1748 1749 *channels_min = max(*channels_min, cpu_stream->channels_min); 1750 *channels_max = min(*channels_max, cpu_stream->channels_max); 1751 1752 /* 1753 * chan min/max cannot be enforced if there are multiple CODEC 1754 * DAIs connected to a single CPU DAI, use CPU DAI's directly 1755 */ 1756 if (be->num_codecs == 1) { 1757 codec_dai_drv = be->codec_dais[0]->driver; 1758 1759 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1760 codec_stream = &codec_dai_drv->playback; 1761 else 1762 codec_stream = &codec_dai_drv->capture; 1763 1764 *channels_min = max(*channels_min, 1765 codec_stream->channels_min); 1766 *channels_max = min(*channels_max, 1767 codec_stream->channels_max); 1768 } 1769 } 1770} 1771 | |
1772static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) 1773{ 1774 struct snd_pcm_runtime *runtime = substream->runtime; 1775 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1776 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1777 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 1778 u64 format = dpcm_runtime_base_format(substream); | 1718static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) 1719{ 1720 struct snd_pcm_runtime *runtime = substream->runtime; 1721 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1722 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1723 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 1724 u64 format = dpcm_runtime_base_format(substream); |
1779 unsigned int channels_min = 0, channels_max = UINT_MAX; | |
1780 1781 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1782 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format); 1783 else 1784 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format); | 1725 1726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1727 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format); 1728 else 1729 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format); |
1785 1786 dpcm_runtime_base_chan(substream, &channels_min, &channels_max); 1787 1788 runtime->hw.channels_min = max(channels_min, runtime->hw.channels_min); 1789 runtime->hw.channels_max = min(channels_max, runtime->hw.channels_max); | |
1790} 1791 1792static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); 1793 1794/* Set FE's runtime_update state; the state is protected via PCM stream lock 1795 * for avoiding the race with trigger callback. 1796 * If the state is unset and a trigger is pending while the previous operation, 1797 * process the pending trigger action here. --- 808 unchanged lines hidden (view full) --- 2606 ret = dpcm_run_update_shutdown(fe, stream); 2607 if (ret < 0) 2608 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); 2609 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2610 2611 return ret; 2612} 2613 | 1730} 1731 1732static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); 1733 1734/* Set FE's runtime_update state; the state is protected via PCM stream lock 1735 * for avoiding the race with trigger callback. 1736 * If the state is unset and a trigger is pending while the previous operation, 1737 * process the pending trigger action here. --- 808 unchanged lines hidden (view full) --- 2546 ret = dpcm_run_update_shutdown(fe, stream); 2547 if (ret < 0) 2548 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); 2549 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 2550 2551 return ret; 2552} 2553 |
2614static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) | 2554/* Called by DAPM mixer/mux changes to update audio routing between PCMs and 2555 * any DAI links. 2556 */ 2557int soc_dpcm_runtime_update(struct snd_soc_card *card) |
2615{ | 2558{ |
2616 struct snd_soc_dapm_widget_list *list; 2617 int count, paths; | 2559 struct snd_soc_pcm_runtime *fe; 2560 int old, new, paths; |
2618 | 2561 |
2619 if (!fe->dai_link->dynamic) 2620 return 0; | 2562 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2563 list_for_each_entry(fe, &card->rtd_list, list) { 2564 struct snd_soc_dapm_widget_list *list; |
2621 | 2565 |
2622 /* only check active links */ 2623 if (!fe->cpu_dai->active) 2624 return 0; | 2566 /* make sure link is FE */ 2567 if (!fe->dai_link->dynamic) 2568 continue; |
2625 | 2569 |
2626 /* DAPM sync will call this to update DSP paths */ 2627 dev_dbg(fe->dev, "ASoC: DPCM %s runtime update for FE %s\n", 2628 new ? "new" : "old", fe->dai_link->name); | 2570 /* only check active links */ 2571 if (!fe->cpu_dai->active) 2572 continue; |
2629 | 2573 |
2630 /* skip if FE doesn't have playback capability */ 2631 if (!fe->cpu_dai->driver->playback.channels_min || 2632 !fe->codec_dai->driver->playback.channels_min) 2633 goto capture; | 2574 /* DAPM sync will call this to update DSP paths */ 2575 dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n", 2576 fe->dai_link->name); |
2634 | 2577 |
2635 /* skip if FE isn't currently playing */ 2636 if (!fe->cpu_dai->playback_active || !fe->codec_dai->playback_active) 2637 goto capture; | 2578 /* skip if FE doesn't have playback capability */ 2579 if (!fe->cpu_dai->driver->playback.channels_min 2580 || !fe->codec_dai->driver->playback.channels_min) 2581 goto capture; |
2638 | 2582 |
2639 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); 2640 if (paths < 0) { 2641 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2642 fe->dai_link->name, "playback"); 2643 return paths; 2644 } | 2583 /* skip if FE isn't currently playing */ 2584 if (!fe->cpu_dai->playback_active 2585 || !fe->codec_dai->playback_active) 2586 goto capture; |
2645 | 2587 |
2646 /* update any playback paths */ 2647 count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, new); 2648 if (count) { 2649 if (new) | 2588 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); 2589 if (paths < 0) { 2590 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2591 fe->dai_link->name, "playback"); 2592 mutex_unlock(&card->mutex); 2593 return paths; 2594 } 2595 2596 /* update any new playback paths */ 2597 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 1); 2598 if (new) { |
2650 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK); | 2599 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK); |
2651 else | 2600 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK); 2601 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); 2602 } 2603 2604 /* update any old playback paths */ 2605 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 0); 2606 if (old) { |
2652 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK); | 2607 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK); |
2608 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK); 2609 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); 2610 } |
|
2653 | 2611 |
2654 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK); 2655 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK); 2656 } 2657 2658 dpcm_path_put(&list); 2659 | 2612 dpcm_path_put(&list); |
2660capture: | 2613capture: |
2661 /* skip if FE doesn't have capture capability */ 2662 if (!fe->cpu_dai->driver->capture.channels_min || 2663 !fe->codec_dai->driver->capture.channels_min) 2664 return 0; | 2614 /* skip if FE doesn't have capture capability */ 2615 if (!fe->cpu_dai->driver->capture.channels_min 2616 || !fe->codec_dai->driver->capture.channels_min) 2617 continue; |
2665 | 2618 |
2666 /* skip if FE isn't currently capturing */ 2667 if (!fe->cpu_dai->capture_active || !fe->codec_dai->capture_active) 2668 return 0; | 2619 /* skip if FE isn't currently capturing */ 2620 if (!fe->cpu_dai->capture_active 2621 || !fe->codec_dai->capture_active) 2622 continue; |
2669 | 2623 |
2670 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); 2671 if (paths < 0) { 2672 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2673 fe->dai_link->name, "capture"); 2674 return paths; 2675 } | 2624 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); 2625 if (paths < 0) { 2626 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", 2627 fe->dai_link->name, "capture"); 2628 mutex_unlock(&card->mutex); 2629 return paths; 2630 } |
2676 | 2631 |
2677 /* update any old capture paths */ 2678 count = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, new); 2679 if (count) { 2680 if (new) | 2632 /* update any new capture paths */ 2633 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 1); 2634 if (new) { |
2681 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE); | 2635 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE); |
2682 else | 2636 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE); 2637 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); 2638 } 2639 2640 /* update any old capture paths */ 2641 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 0); 2642 if (old) { |
2683 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE); | 2643 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE); |
2644 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE); 2645 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); 2646 } |
|
2684 | 2647 |
2685 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE); 2686 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE); | 2648 dpcm_path_put(&list); |
2687 } 2688 | 2649 } 2650 |
2689 dpcm_path_put(&list); 2690 | 2651 mutex_unlock(&card->mutex); |
2691 return 0; 2692} | 2652 return 0; 2653} |
2693 2694/* Called by DAPM mixer/mux changes to update audio routing between PCMs and 2695 * any DAI links. 2696 */ 2697int soc_dpcm_runtime_update(struct snd_soc_card *card) 2698{ 2699 struct snd_soc_pcm_runtime *fe; 2700 int ret = 0; 2701 2702 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2703 /* shutdown all old paths first */ 2704 list_for_each_entry(fe, &card->rtd_list, list) { 2705 ret = soc_dpcm_fe_runtime_update(fe, 0); 2706 if (ret) 2707 goto out; 2708 } 2709 2710 /* bring new paths up */ 2711 list_for_each_entry(fe, &card->rtd_list, list) { 2712 ret = soc_dpcm_fe_runtime_update(fe, 1); 2713 if (ret) 2714 goto out; 2715 } 2716 2717out: 2718 mutex_unlock(&card->mutex); 2719 return ret; 2720} | |
2721int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) 2722{ 2723 struct snd_soc_dpcm *dpcm; 2724 struct list_head *clients = 2725 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients; 2726 2727 list_for_each_entry(dpcm, clients, list_be) { 2728 --- 618 unchanged lines hidden --- | 2654int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) 2655{ 2656 struct snd_soc_dpcm *dpcm; 2657 struct list_head *clients = 2658 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients; 2659 2660 list_for_each_entry(dpcm, clients, list_be) { 2661 --- 618 unchanged lines hidden --- |