soc-pcm.c (57b8628bb0ac4e47c806e45c5bbd89282e93869b) | soc-pcm.c (01d7584cd2e5a93a2b959c9dddaa0d93ec205404) |
---|---|
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 * --- 8 unchanged lines hidden (view full) --- 17 */ 18 19#include <linux/kernel.h> 20#include <linux/init.h> 21#include <linux/delay.h> 22#include <linux/pm_runtime.h> 23#include <linux/slab.h> 24#include <linux/workqueue.h> | 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 * --- 8 unchanged lines hidden (view full) --- 17 */ 18 19#include <linux/kernel.h> 20#include <linux/init.h> 21#include <linux/delay.h> 22#include <linux/pm_runtime.h> 23#include <linux/slab.h> 24#include <linux/workqueue.h> |
25#include <linux/export.h> |
|
25#include <sound/core.h> 26#include <sound/pcm.h> 27#include <sound/pcm_params.h> 28#include <sound/soc.h> | 26#include <sound/core.h> 27#include <sound/pcm.h> 28#include <sound/pcm_params.h> 29#include <sound/soc.h> |
30#include <sound/soc-dpcm.h> |
|
29#include <sound/initval.h> 30 | 31#include <sound/initval.h> 32 |
33#define DPCM_MAX_BE_USERS 8 34 35/* DPCM stream event, send event to FE and all active BEs. */ 36static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, 37 int event) 38{ 39 struct snd_soc_dpcm *dpcm; 40 41 list_for_each_entry(dpcm, &fe->dpcm[dir].be_clients, list_be) { 42 43 struct snd_soc_pcm_runtime *be = dpcm->be; 44 45 dev_dbg(be->dev, "pm: BE %s event %d dir %d\n", 46 be->dai_link->name, event, dir); 47 48 snd_soc_dapm_stream_event(be, dir, event); 49 } 50 51 snd_soc_dapm_stream_event(fe, dir, event); 52 53 return 0; 54} 55 |
|
31static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, 32 struct snd_soc_dai *soc_dai) 33{ 34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 35 int ret; 36 37 if (!soc_dai->driver->symmetric_rates && 38 !rtd->dai_link->symmetric_rates) --- 112 unchanged lines hidden (view full) --- 151 ret = rtd->dai_link->ops->startup(substream); 152 if (ret < 0) { 153 pr_err("asoc: %s startup failed: %d\n", 154 rtd->dai_link->name, ret); 155 goto machine_err; 156 } 157 } 158 | 56static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, 57 struct snd_soc_dai *soc_dai) 58{ 59 struct snd_soc_pcm_runtime *rtd = substream->private_data; 60 int ret; 61 62 if (!soc_dai->driver->symmetric_rates && 63 !rtd->dai_link->symmetric_rates) --- 112 unchanged lines hidden (view full) --- 176 ret = rtd->dai_link->ops->startup(substream); 177 if (ret < 0) { 178 pr_err("asoc: %s startup failed: %d\n", 179 rtd->dai_link->name, ret); 180 goto machine_err; 181 } 182 } 183 |
184 /* Dynamic PCM DAI links compat checks use dynamic capabilities */ 185 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) 186 goto dynamic; 187 |
|
159 /* Check that the codec and cpu DAIs are compatible */ 160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 161 runtime->hw.rate_min = 162 max(codec_dai_drv->playback.rate_min, 163 cpu_dai_drv->playback.rate_min); 164 runtime->hw.rate_max = 165 min(codec_dai_drv->playback.rate_max, 166 cpu_dai_drv->playback.rate_max); --- 76 unchanged lines hidden (view full) --- 243 pr_debug("asoc: %s <-> %s info:\n", 244 codec_dai->name, cpu_dai->name); 245 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); 246 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 247 runtime->hw.channels_max); 248 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 249 runtime->hw.rate_max); 250 | 188 /* Check that the codec and cpu DAIs are compatible */ 189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 190 runtime->hw.rate_min = 191 max(codec_dai_drv->playback.rate_min, 192 cpu_dai_drv->playback.rate_min); 193 runtime->hw.rate_max = 194 min(codec_dai_drv->playback.rate_max, 195 cpu_dai_drv->playback.rate_max); --- 76 unchanged lines hidden (view full) --- 272 pr_debug("asoc: %s <-> %s info:\n", 273 codec_dai->name, cpu_dai->name); 274 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); 275 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 276 runtime->hw.channels_max); 277 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 278 runtime->hw.rate_max); 279 |
280dynamic: |
|
251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 252 cpu_dai->playback_active++; 253 codec_dai->playback_active++; 254 } else { 255 cpu_dai->capture_active++; 256 codec_dai->capture_active++; 257 } 258 cpu_dai->active++; --- 44 unchanged lines hidden (view full) --- 303 codec_dai->driver->playback.stream_name, 304 codec_dai->playback_active ? "active" : "inactive", 305 codec_dai->pop_wait ? "yes" : "no"); 306 307 /* are we waiting on this codec DAI stream */ 308 if (codec_dai->pop_wait == 1) { 309 codec_dai->pop_wait = 0; 310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, | 281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 282 cpu_dai->playback_active++; 283 codec_dai->playback_active++; 284 } else { 285 cpu_dai->capture_active++; 286 codec_dai->capture_active++; 287 } 288 cpu_dai->active++; --- 44 unchanged lines hidden (view full) --- 333 codec_dai->driver->playback.stream_name, 334 codec_dai->playback_active ? "active" : "inactive", 335 codec_dai->pop_wait ? "yes" : "no"); 336 337 /* are we waiting on this codec DAI stream */ 338 if (codec_dai->pop_wait == 1) { 339 codec_dai->pop_wait = 0; 340 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, |
311 codec_dai, SND_SOC_DAPM_STREAM_STOP); | 341 SND_SOC_DAPM_STREAM_STOP); |
312 } 313 314 mutex_unlock(&rtd->pcm_mutex); 315} 316 317/* 318 * Called by ALSA when a PCM substream is closed. Private data can be 319 * freed here. The cpu DAI, codec DAI, machine and platform are also --- 48 unchanged lines hidden (view full) --- 368 cpu_dai->runtime = NULL; 369 370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 371 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 372 rtd->dai_link->ignore_pmdown_time) { 373 /* powered down playback stream now */ 374 snd_soc_dapm_stream_event(rtd, 375 SNDRV_PCM_STREAM_PLAYBACK, | 342 } 343 344 mutex_unlock(&rtd->pcm_mutex); 345} 346 347/* 348 * Called by ALSA when a PCM substream is closed. Private data can be 349 * freed here. The cpu DAI, codec DAI, machine and platform are also --- 48 unchanged lines hidden (view full) --- 398 cpu_dai->runtime = NULL; 399 400 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 401 if (!rtd->pmdown_time || codec->ignore_pmdown_time || 402 rtd->dai_link->ignore_pmdown_time) { 403 /* powered down playback stream now */ 404 snd_soc_dapm_stream_event(rtd, 405 SNDRV_PCM_STREAM_PLAYBACK, |
376 codec_dai, | |
377 SND_SOC_DAPM_STREAM_STOP); 378 } else { 379 /* start delayed pop wq here for playback streams */ 380 codec_dai->pop_wait = 1; 381 schedule_delayed_work(&rtd->delayed_work, 382 msecs_to_jiffies(rtd->pmdown_time)); 383 } 384 } else { 385 /* capture streams can be powered down now */ 386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, | 406 SND_SOC_DAPM_STREAM_STOP); 407 } else { 408 /* start delayed pop wq here for playback streams */ 409 codec_dai->pop_wait = 1; 410 schedule_delayed_work(&rtd->delayed_work, 411 msecs_to_jiffies(rtd->pmdown_time)); 412 } 413 } else { 414 /* capture streams can be powered down now */ 415 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, |
387 codec_dai, SND_SOC_DAPM_STREAM_STOP); | 416 SND_SOC_DAPM_STREAM_STOP); |
388 } 389 390 mutex_unlock(&rtd->pcm_mutex); 391 392 pm_runtime_put(platform->dev); 393 pm_runtime_put(codec_dai->dev); 394 pm_runtime_put(cpu_dai->dev); 395 --- 52 unchanged lines hidden (view full) --- 448 449 /* cancel any delayed stream shutdown that is pending */ 450 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 451 codec_dai->pop_wait) { 452 codec_dai->pop_wait = 0; 453 cancel_delayed_work(&rtd->delayed_work); 454 } 455 | 417 } 418 419 mutex_unlock(&rtd->pcm_mutex); 420 421 pm_runtime_put(platform->dev); 422 pm_runtime_put(codec_dai->dev); 423 pm_runtime_put(cpu_dai->dev); 424 --- 52 unchanged lines hidden (view full) --- 477 478 /* cancel any delayed stream shutdown that is pending */ 479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 480 codec_dai->pop_wait) { 481 codec_dai->pop_wait = 0; 482 cancel_delayed_work(&rtd->delayed_work); 483 } 484 |
456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai, 457 SND_SOC_DAPM_STREAM_START); | 485 snd_soc_dapm_stream_event(rtd, substream->stream, 486 SND_SOC_DAPM_STREAM_START); |
458 459 snd_soc_dai_digital_mute(codec_dai, 0); 460 461out: 462 mutex_unlock(&rtd->pcm_mutex); 463 return ret; 464} 465 --- 163 unchanged lines hidden (view full) --- 629 if (platform->driver->delay) 630 delay += platform->driver->delay(substream, codec_dai); 631 632 runtime->delay = delay; 633 634 return offset; 635} 636 | 487 488 snd_soc_dai_digital_mute(codec_dai, 0); 489 490out: 491 mutex_unlock(&rtd->pcm_mutex); 492 return ret; 493} 494 --- 163 unchanged lines hidden (view full) --- 658 if (platform->driver->delay) 659 delay += platform->driver->delay(substream, codec_dai); 660 661 runtime->delay = delay; 662 663 return offset; 664} 665 |
666/* connect a FE and BE */ 667static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, 668 struct snd_soc_pcm_runtime *be, int stream) 669{ 670 struct snd_soc_dpcm *dpcm; 671 672 /* only add new dpcms */ 673 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 674 if (dpcm->be == be && dpcm->fe == fe) 675 return 0; 676 } 677 678 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL); 679 if (!dpcm) 680 return -ENOMEM; 681 682 dpcm->be = be; 683 dpcm->fe = fe; 684 be->dpcm[stream].runtime = fe->dpcm[stream].runtime; 685 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; 686 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); 687 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); 688 689 dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n", 690 stream ? "capture" : "playback", fe->dai_link->name, 691 stream ? "<-" : "->", be->dai_link->name); 692 693 return 1; 694} 695 696/* reparent a BE onto another FE */ 697static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, 698 struct snd_soc_pcm_runtime *be, int stream) 699{ 700 struct snd_soc_dpcm *dpcm; 701 struct snd_pcm_substream *fe_substream, *be_substream; 702 703 /* reparent if BE is connected to other FEs */ 704 if (!be->dpcm[stream].users) 705 return; 706 707 be_substream = snd_soc_dpcm_get_substream(be, stream); 708 709 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) { 710 if (dpcm->fe == fe) 711 continue; 712 713 dev_dbg(fe->dev, " reparent %s path %s %s %s\n", 714 stream ? "capture" : "playback", 715 dpcm->fe->dai_link->name, 716 stream ? "<-" : "->", dpcm->be->dai_link->name); 717 718 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream); 719 be_substream->runtime = fe_substream->runtime; 720 break; 721 } 722} 723 724/* disconnect a BE and FE */ 725static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) 726{ 727 struct snd_soc_dpcm *dpcm, *d; 728 729 list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) { 730 dev_dbg(fe->dev, "BE %s disconnect check for %s\n", 731 stream ? "capture" : "playback", 732 dpcm->be->dai_link->name); 733 734 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE) 735 continue; 736 737 dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n", 738 stream ? "capture" : "playback", fe->dai_link->name, 739 stream ? "<-" : "->", dpcm->be->dai_link->name); 740 741 /* BEs still alive need new FE */ 742 dpcm_be_reparent(fe, dpcm->be, stream); 743 744 list_del(&dpcm->list_be); 745 list_del(&dpcm->list_fe); 746 kfree(dpcm); 747 } 748} 749 750/* get BE for DAI widget and stream */ 751static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, 752 struct snd_soc_dapm_widget *widget, int stream) 753{ 754 struct snd_soc_pcm_runtime *be; 755 int i; 756 757 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 758 for (i = 0; i < card->num_links; i++) { 759 be = &card->rtd[i]; 760 761 if (be->cpu_dai->playback_widget == widget || 762 be->codec_dai->playback_widget == widget) 763 return be; 764 } 765 } else { 766 767 for (i = 0; i < card->num_links; i++) { 768 be = &card->rtd[i]; 769 770 if (be->cpu_dai->capture_widget == widget || 771 be->codec_dai->capture_widget == widget) 772 return be; 773 } 774 } 775 776 dev_err(card->dev, "can't get %s BE for %s\n", 777 stream ? "capture" : "playback", widget->name); 778 return NULL; 779} 780 781static inline struct snd_soc_dapm_widget * 782 rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream) 783{ 784 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 785 return rtd->cpu_dai->playback_widget; 786 else 787 return rtd->cpu_dai->capture_widget; 788} 789 790static inline struct snd_soc_dapm_widget * 791 rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream) 792{ 793 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 794 return rtd->codec_dai->playback_widget; 795 else 796 return rtd->codec_dai->capture_widget; 797} 798 799static int widget_in_list(struct snd_soc_dapm_widget_list *list, 800 struct snd_soc_dapm_widget *widget) 801{ 802 int i; 803 804 for (i = 0; i < list->num_widgets; i++) { 805 if (widget == list->widgets[i]) 806 return 1; 807 } 808 809 return 0; 810} 811 812static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, 813 int stream, struct snd_soc_dapm_widget_list **list_) 814{ 815 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 816 struct snd_soc_dapm_widget_list *list; 817 int paths; 818 819 list = kzalloc(sizeof(struct snd_soc_dapm_widget_list) + 820 sizeof(struct snd_soc_dapm_widget *), GFP_KERNEL); 821 if (list == NULL) 822 return -ENOMEM; 823 824 /* get number of valid DAI paths and their widgets */ 825 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list); 826 827 dev_dbg(fe->dev, "found %d audio %s paths\n", paths, 828 stream ? "capture" : "playback"); 829 830 *list_ = list; 831 return paths; 832} 833 834static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list) 835{ 836 kfree(*list); 837} 838 839static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, 840 struct snd_soc_dapm_widget_list **list_) 841{ 842 struct snd_soc_dpcm *dpcm; 843 struct snd_soc_dapm_widget_list *list = *list_; 844 struct snd_soc_dapm_widget *widget; 845 int prune = 0; 846 847 /* Destroy any old FE <--> BE connections */ 848 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 849 850 /* is there a valid CPU DAI widget for this BE */ 851 widget = rtd_get_cpu_widget(dpcm->be, stream); 852 853 /* prune the BE if it's no longer in our active list */ 854 if (widget && widget_in_list(list, widget)) 855 continue; 856 857 /* is there a valid CODEC DAI widget for this BE */ 858 widget = rtd_get_codec_widget(dpcm->be, stream); 859 860 /* prune the BE if it's no longer in our active list */ 861 if (widget && widget_in_list(list, widget)) 862 continue; 863 864 dev_dbg(fe->dev, "pruning %s BE %s for %s\n", 865 stream ? "capture" : "playback", 866 dpcm->be->dai_link->name, fe->dai_link->name); 867 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 868 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; 869 prune++; 870 } 871 872 dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune); 873 return prune; 874} 875 876static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, 877 struct snd_soc_dapm_widget_list **list_) 878{ 879 struct snd_soc_card *card = fe->card; 880 struct snd_soc_dapm_widget_list *list = *list_; 881 struct snd_soc_pcm_runtime *be; 882 int i, new = 0, err; 883 884 /* Create any new FE <--> BE connections */ 885 for (i = 0; i < list->num_widgets; i++) { 886 887 if (list->widgets[i]->id != snd_soc_dapm_dai) 888 continue; 889 890 /* is there a valid BE rtd for this widget */ 891 be = dpcm_get_be(card, list->widgets[i], stream); 892 if (!be) { 893 dev_err(fe->dev, "no BE found for %s\n", 894 list->widgets[i]->name); 895 continue; 896 } 897 898 /* make sure BE is a real BE */ 899 if (!be->dai_link->no_pcm) 900 continue; 901 902 /* don't connect if FE is not running */ 903 if (!fe->dpcm[stream].runtime) 904 continue; 905 906 /* newly connected FE and BE */ 907 err = dpcm_be_connect(fe, be, stream); 908 if (err < 0) { 909 dev_err(fe->dev, "can't connect %s\n", 910 list->widgets[i]->name); 911 break; 912 } else if (err == 0) /* already connected */ 913 continue; 914 915 /* new */ 916 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; 917 new++; 918 } 919 920 dev_dbg(fe->dev, "found %d new BE paths\n", new); 921 return new; 922} 923 924/* 925 * Find the corresponding BE DAIs that source or sink audio to this 926 * FE substream. 927 */ 928static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, 929 int stream, struct snd_soc_dapm_widget_list **list, int new) 930{ 931 if (new) 932 return dpcm_add_paths(fe, stream, list); 933 else 934 return dpcm_prune_paths(fe, stream, list); 935} 936 937static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) 938{ 939 struct snd_soc_dpcm *dpcm; 940 941 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) 942 dpcm->be->dpcm[stream].runtime_update = 943 SND_SOC_DPCM_UPDATE_NO; 944} 945 946static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, 947 int stream) 948{ 949 struct snd_soc_dpcm *dpcm; 950 951 /* disable any enabled and non active backends */ 952 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 953 954 struct snd_soc_pcm_runtime *be = dpcm->be; 955 struct snd_pcm_substream *be_substream = 956 snd_soc_dpcm_get_substream(be, stream); 957 958 if (be->dpcm[stream].users == 0) 959 dev_err(be->dev, "no users %s at close - state %d\n", 960 stream ? "capture" : "playback", 961 be->dpcm[stream].state); 962 963 if (--be->dpcm[stream].users != 0) 964 continue; 965 966 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) 967 continue; 968 969 soc_pcm_close(be_substream); 970 be_substream->runtime = NULL; 971 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 972 } 973} 974 975static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) 976{ 977 struct snd_soc_dpcm *dpcm; 978 int err, count = 0; 979 980 /* only startup BE DAIs that are either sinks or sources to this FE DAI */ 981 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 982 983 struct snd_soc_pcm_runtime *be = dpcm->be; 984 struct snd_pcm_substream *be_substream = 985 snd_soc_dpcm_get_substream(be, stream); 986 987 /* is this op for this BE ? */ 988 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 989 continue; 990 991 /* first time the dpcm is open ? */ 992 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) 993 dev_err(be->dev, "too many users %s at open %d\n", 994 stream ? "capture" : "playback", 995 be->dpcm[stream].state); 996 997 if (be->dpcm[stream].users++ != 0) 998 continue; 999 1000 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) && 1001 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) 1002 continue; 1003 1004 dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name); 1005 1006 be_substream->runtime = be->dpcm[stream].runtime; 1007 err = soc_pcm_open(be_substream); 1008 if (err < 0) { 1009 dev_err(be->dev, "BE open failed %d\n", err); 1010 be->dpcm[stream].users--; 1011 if (be->dpcm[stream].users < 0) 1012 dev_err(be->dev, "no users %s at unwind %d\n", 1013 stream ? "capture" : "playback", 1014 be->dpcm[stream].state); 1015 1016 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 1017 goto unwind; 1018 } 1019 1020 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; 1021 count++; 1022 } 1023 1024 return count; 1025 1026unwind: 1027 /* disable any enabled and non active backends */ 1028 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1029 struct snd_soc_pcm_runtime *be = dpcm->be; 1030 struct snd_pcm_substream *be_substream = 1031 snd_soc_dpcm_get_substream(be, stream); 1032 1033 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1034 continue; 1035 1036 if (be->dpcm[stream].users == 0) 1037 dev_err(be->dev, "no users %s at close %d\n", 1038 stream ? "capture" : "playback", 1039 be->dpcm[stream].state); 1040 1041 if (--be->dpcm[stream].users != 0) 1042 continue; 1043 1044 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) 1045 continue; 1046 1047 soc_pcm_close(be_substream); 1048 be_substream->runtime = NULL; 1049 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 1050 } 1051 1052 return err; 1053} 1054 1055void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) 1056{ 1057 struct snd_pcm_runtime *runtime = substream->runtime; 1058 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1059 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1060 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 1061 1062 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1063 runtime->hw.rate_min = cpu_dai_drv->playback.rate_min; 1064 runtime->hw.rate_max = cpu_dai_drv->playback.rate_max; 1065 runtime->hw.channels_min = cpu_dai_drv->playback.channels_min; 1066 runtime->hw.channels_max = cpu_dai_drv->playback.channels_max; 1067 runtime->hw.formats &= cpu_dai_drv->playback.formats; 1068 runtime->hw.rates = cpu_dai_drv->playback.rates; 1069 } else { 1070 runtime->hw.rate_min = cpu_dai_drv->capture.rate_min; 1071 runtime->hw.rate_max = cpu_dai_drv->capture.rate_max; 1072 runtime->hw.channels_min = cpu_dai_drv->capture.channels_min; 1073 runtime->hw.channels_max = cpu_dai_drv->capture.channels_max; 1074 runtime->hw.formats &= cpu_dai_drv->capture.formats; 1075 runtime->hw.rates = cpu_dai_drv->capture.rates; 1076 } 1077} 1078 1079static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) 1080{ 1081 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1082 struct snd_pcm_runtime *runtime = fe_substream->runtime; 1083 int stream = fe_substream->stream, ret = 0; 1084 1085 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1086 1087 ret = dpcm_be_dai_startup(fe, fe_substream->stream); 1088 if (ret < 0) { 1089 dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret); 1090 goto be_err; 1091 } 1092 1093 dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name); 1094 1095 /* start the DAI frontend */ 1096 ret = soc_pcm_open(fe_substream); 1097 if (ret < 0) { 1098 dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret); 1099 goto unwind; 1100 } 1101 1102 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; 1103 1104 dpcm_set_fe_runtime(fe_substream); 1105 snd_pcm_limit_hw_rates(runtime); 1106 1107 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1108 return 0; 1109 1110unwind: 1111 dpcm_be_dai_startup_unwind(fe, fe_substream->stream); 1112be_err: 1113 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1114 return ret; 1115} 1116 1117static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) 1118{ 1119 struct snd_soc_dpcm *dpcm; 1120 1121 /* only shutdown BEs that are either sinks or sources to this FE DAI */ 1122 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1123 1124 struct snd_soc_pcm_runtime *be = dpcm->be; 1125 struct snd_pcm_substream *be_substream = 1126 snd_soc_dpcm_get_substream(be, stream); 1127 1128 /* is this op for this BE ? */ 1129 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1130 continue; 1131 1132 if (be->dpcm[stream].users == 0) 1133 dev_err(be->dev, "no users %s at close - state %d\n", 1134 stream ? "capture" : "playback", 1135 be->dpcm[stream].state); 1136 1137 if (--be->dpcm[stream].users != 0) 1138 continue; 1139 1140 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && 1141 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) 1142 continue; 1143 1144 dev_dbg(be->dev, "dpcm: close BE %s\n", 1145 dpcm->fe->dai_link->name); 1146 1147 soc_pcm_close(be_substream); 1148 be_substream->runtime = NULL; 1149 1150 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 1151 } 1152 return 0; 1153} 1154 1155static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) 1156{ 1157 struct snd_soc_pcm_runtime *fe = substream->private_data; 1158 int stream = substream->stream; 1159 1160 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1161 1162 /* shutdown the BEs */ 1163 dpcm_be_dai_shutdown(fe, substream->stream); 1164 1165 dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name); 1166 1167 /* now shutdown the frontend */ 1168 soc_pcm_close(substream); 1169 1170 /* run the stream event for each BE */ 1171 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); 1172 1173 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; 1174 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1175 return 0; 1176} 1177 1178static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) 1179{ 1180 struct snd_soc_dpcm *dpcm; 1181 1182 /* only hw_params backends that are either sinks or sources 1183 * to this frontend DAI */ 1184 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1185 1186 struct snd_soc_pcm_runtime *be = dpcm->be; 1187 struct snd_pcm_substream *be_substream = 1188 snd_soc_dpcm_get_substream(be, stream); 1189 1190 /* is this op for this BE ? */ 1191 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1192 continue; 1193 1194 /* only free hw when no longer used - check all FEs */ 1195 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) 1196 continue; 1197 1198 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 1199 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && 1200 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && 1201 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 1202 continue; 1203 1204 dev_dbg(be->dev, "dpcm: hw_free BE %s\n", 1205 dpcm->fe->dai_link->name); 1206 1207 soc_pcm_hw_free(be_substream); 1208 1209 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; 1210 } 1211 1212 return 0; 1213} 1214 1215int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) 1216{ 1217 struct snd_soc_pcm_runtime *fe = substream->private_data; 1218 int err, stream = substream->stream; 1219 1220 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1221 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1222 1223 dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name); 1224 1225 /* call hw_free on the frontend */ 1226 err = soc_pcm_hw_free(substream); 1227 if (err < 0) 1228 dev_err(fe->dev,"dpcm: hw_free FE %s failed\n", 1229 fe->dai_link->name); 1230 1231 /* only hw_params backends that are either sinks or sources 1232 * to this frontend DAI */ 1233 err = dpcm_be_dai_hw_free(fe, stream); 1234 1235 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; 1236 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1237 1238 mutex_unlock(&fe->card->mutex); 1239 return 0; 1240} 1241 1242static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) 1243{ 1244 struct snd_soc_dpcm *dpcm; 1245 int ret; 1246 1247 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1248 1249 struct snd_soc_pcm_runtime *be = dpcm->be; 1250 struct snd_pcm_substream *be_substream = 1251 snd_soc_dpcm_get_substream(be, stream); 1252 1253 /* is this op for this BE ? */ 1254 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1255 continue; 1256 1257 /* only allow hw_params() if no connected FEs are running */ 1258 if (!snd_soc_dpcm_can_be_params(fe, be, stream)) 1259 continue; 1260 1261 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && 1262 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 1263 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) 1264 continue; 1265 1266 dev_dbg(be->dev, "dpcm: hw_params BE %s\n", 1267 dpcm->fe->dai_link->name); 1268 1269 /* copy params for each dpcm */ 1270 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params, 1271 sizeof(struct snd_pcm_hw_params)); 1272 1273 /* perform any hw_params fixups */ 1274 if (be->dai_link->be_hw_params_fixup) { 1275 ret = be->dai_link->be_hw_params_fixup(be, 1276 &dpcm->hw_params); 1277 if (ret < 0) { 1278 dev_err(be->dev, 1279 "dpcm: hw_params BE fixup failed %d\n", 1280 ret); 1281 goto unwind; 1282 } 1283 } 1284 1285 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); 1286 if (ret < 0) { 1287 dev_err(dpcm->be->dev, 1288 "dpcm: hw_params BE failed %d\n", ret); 1289 goto unwind; 1290 } 1291 1292 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; 1293 } 1294 return 0; 1295 1296unwind: 1297 /* disable any enabled and non active backends */ 1298 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1299 struct snd_soc_pcm_runtime *be = dpcm->be; 1300 struct snd_pcm_substream *be_substream = 1301 snd_soc_dpcm_get_substream(be, stream); 1302 1303 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1304 continue; 1305 1306 /* only allow hw_free() if no connected FEs are running */ 1307 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) 1308 continue; 1309 1310 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && 1311 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 1312 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && 1313 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 1314 continue; 1315 1316 soc_pcm_hw_free(be_substream); 1317 } 1318 1319 return ret; 1320} 1321 1322int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, 1323 struct snd_pcm_hw_params *params) 1324{ 1325 struct snd_soc_pcm_runtime *fe = substream->private_data; 1326 int ret, stream = substream->stream; 1327 1328 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1329 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1330 1331 memcpy(&fe->dpcm[substream->stream].hw_params, params, 1332 sizeof(struct snd_pcm_hw_params)); 1333 ret = dpcm_be_dai_hw_params(fe, substream->stream); 1334 if (ret < 0) { 1335 dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret); 1336 goto out; 1337 } 1338 1339 dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n", 1340 fe->dai_link->name, params_rate(params), 1341 params_channels(params), params_format(params)); 1342 1343 /* call hw_params on the frontend */ 1344 ret = soc_pcm_hw_params(substream, params); 1345 if (ret < 0) { 1346 dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret); 1347 dpcm_be_dai_hw_free(fe, stream); 1348 } else 1349 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; 1350 1351out: 1352 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1353 mutex_unlock(&fe->card->mutex); 1354 return ret; 1355} 1356 1357static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, 1358 struct snd_pcm_substream *substream, int cmd) 1359{ 1360 int ret; 1361 1362 dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n", 1363 dpcm->fe->dai_link->name, cmd); 1364 1365 ret = soc_pcm_trigger(substream, cmd); 1366 if (ret < 0) 1367 dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret); 1368 1369 return ret; 1370} 1371 1372int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd) 1373{ 1374 struct snd_soc_dpcm *dpcm; 1375 int ret = 0; 1376 1377 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1378 1379 struct snd_soc_pcm_runtime *be = dpcm->be; 1380 struct snd_pcm_substream *be_substream = 1381 snd_soc_dpcm_get_substream(be, stream); 1382 1383 /* is this op for this BE ? */ 1384 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1385 continue; 1386 1387 switch (cmd) { 1388 case SNDRV_PCM_TRIGGER_START: 1389 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && 1390 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 1391 continue; 1392 1393 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1394 if (ret) 1395 return ret; 1396 1397 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 1398 break; 1399 case SNDRV_PCM_TRIGGER_RESUME: 1400 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) 1401 continue; 1402 1403 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1404 if (ret) 1405 return ret; 1406 1407 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 1408 break; 1409 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1410 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) 1411 continue; 1412 1413 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1414 if (ret) 1415 return ret; 1416 1417 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 1418 break; 1419 case SNDRV_PCM_TRIGGER_STOP: 1420 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) 1421 continue; 1422 1423 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) 1424 continue; 1425 1426 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1427 if (ret) 1428 return ret; 1429 1430 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; 1431 break; 1432 case SNDRV_PCM_TRIGGER_SUSPEND: 1433 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) 1434 continue; 1435 1436 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) 1437 continue; 1438 1439 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1440 if (ret) 1441 return ret; 1442 1443 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; 1444 break; 1445 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1446 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) 1447 continue; 1448 1449 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) 1450 continue; 1451 1452 ret = dpcm_do_trigger(dpcm, be_substream, cmd); 1453 if (ret) 1454 return ret; 1455 1456 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; 1457 break; 1458 } 1459 } 1460 1461 return ret; 1462} 1463EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger); 1464 1465int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd) 1466{ 1467 struct snd_soc_pcm_runtime *fe = substream->private_data; 1468 int stream = substream->stream, ret; 1469 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; 1470 1471 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1472 1473 switch (trigger) { 1474 case SND_SOC_DPCM_TRIGGER_PRE: 1475 /* call trigger on the frontend before the backend. */ 1476 1477 dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n", 1478 fe->dai_link->name, cmd); 1479 1480 ret = soc_pcm_trigger(substream, cmd); 1481 if (ret < 0) { 1482 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); 1483 goto out; 1484 } 1485 1486 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); 1487 break; 1488 case SND_SOC_DPCM_TRIGGER_POST: 1489 /* call trigger on the frontend after the backend. */ 1490 1491 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); 1492 if (ret < 0) { 1493 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret); 1494 goto out; 1495 } 1496 1497 dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n", 1498 fe->dai_link->name, cmd); 1499 1500 ret = soc_pcm_trigger(substream, cmd); 1501 break; 1502 default: 1503 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd, 1504 fe->dai_link->name); 1505 ret = -EINVAL; 1506 goto out; 1507 } 1508 1509 switch (cmd) { 1510 case SNDRV_PCM_TRIGGER_START: 1511 case SNDRV_PCM_TRIGGER_RESUME: 1512 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1513 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START; 1514 break; 1515 case SNDRV_PCM_TRIGGER_STOP: 1516 case SNDRV_PCM_TRIGGER_SUSPEND: 1517 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1518 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; 1519 break; 1520 } 1521 1522out: 1523 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1524 return ret; 1525} 1526 1527static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) 1528{ 1529 struct snd_soc_dpcm *dpcm; 1530 int ret = 0; 1531 1532 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1533 1534 struct snd_soc_pcm_runtime *be = dpcm->be; 1535 struct snd_pcm_substream *be_substream = 1536 snd_soc_dpcm_get_substream(be, stream); 1537 1538 /* is this op for this BE ? */ 1539 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 1540 continue; 1541 1542 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 1543 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 1544 continue; 1545 1546 dev_dbg(be->dev, "dpcm: prepare BE %s\n", 1547 dpcm->fe->dai_link->name); 1548 1549 ret = soc_pcm_prepare(be_substream); 1550 if (ret < 0) { 1551 dev_err(be->dev, "dpcm: backend prepare failed %d\n", 1552 ret); 1553 break; 1554 } 1555 1556 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; 1557 } 1558 return ret; 1559} 1560 1561int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream) 1562{ 1563 struct snd_soc_pcm_runtime *fe = substream->private_data; 1564 int stream = substream->stream, ret = 0; 1565 1566 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1567 1568 dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name); 1569 1570 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; 1571 1572 /* there is no point preparing this FE if there are no BEs */ 1573 if (list_empty(&fe->dpcm[stream].be_clients)) { 1574 dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n", 1575 fe->dai_link->name); 1576 ret = -EINVAL; 1577 goto out; 1578 } 1579 1580 ret = dpcm_be_dai_prepare(fe, substream->stream); 1581 if (ret < 0) 1582 goto out; 1583 1584 /* call prepare on the frontend */ 1585 ret = soc_pcm_prepare(substream); 1586 if (ret < 0) { 1587 dev_err(fe->dev,"dpcm: prepare FE %s failed\n", 1588 fe->dai_link->name); 1589 goto out; 1590 } 1591 1592 /* run the stream event for each BE */ 1593 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); 1594 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; 1595 1596out: 1597 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; 1598 mutex_unlock(&fe->card->mutex); 1599 1600 return ret; 1601} 1602 1603 1604int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) 1605{ 1606 struct snd_soc_dpcm *dpcm; 1607 struct list_head *clients = 1608 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients; 1609 1610 list_for_each_entry(dpcm, clients, list_be) { 1611 1612 struct snd_soc_pcm_runtime *be = dpcm->be; 1613 struct snd_soc_dai *dai = be->codec_dai; 1614 struct snd_soc_dai_driver *drv = dai->driver; 1615 1616 if (be->dai_link->ignore_suspend) 1617 continue; 1618 1619 dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name); 1620 1621 if (drv->ops->digital_mute && dai->playback_active) 1622 drv->ops->digital_mute(dai, mute); 1623 } 1624 1625 return 0; 1626} 1627 1628int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) 1629{ 1630 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1631 struct snd_soc_dpcm *dpcm; 1632 struct snd_soc_dapm_widget_list *list; 1633 int ret; 1634 int stream = fe_substream->stream; 1635 1636 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1637 fe->dpcm[stream].runtime = fe_substream->runtime; 1638 1639 if (dpcm_path_get(fe, stream, &list) <= 0) { 1640 dev_warn(fe->dev, "asoc: %s no valid %s route\n", 1641 fe->dai_link->name, stream ? "capture" : "playback"); 1642 mutex_unlock(&fe->card->mutex); 1643 return -EINVAL; 1644 } 1645 1646 /* calculate valid and active FE <-> BE dpcms */ 1647 dpcm_process_paths(fe, stream, &list, 1); 1648 1649 ret = dpcm_fe_dai_startup(fe_substream); 1650 if (ret < 0) { 1651 /* clean up all links */ 1652 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) 1653 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 1654 1655 dpcm_be_disconnect(fe, stream); 1656 fe->dpcm[stream].runtime = NULL; 1657 } 1658 1659 dpcm_clear_pending_state(fe, stream); 1660 dpcm_path_put(&list); 1661 mutex_unlock(&fe->card->mutex); 1662 return ret; 1663} 1664 1665int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) 1666{ 1667 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1668 struct snd_soc_dpcm *dpcm; 1669 int stream = fe_substream->stream, ret; 1670 1671 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1672 ret = dpcm_fe_dai_shutdown(fe_substream); 1673 1674 /* mark FE's links ready to prune */ 1675 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) 1676 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; 1677 1678 dpcm_be_disconnect(fe, stream); 1679 1680 fe->dpcm[stream].runtime = NULL; 1681 mutex_unlock(&fe->card->mutex); 1682 return ret; 1683} 1684 |
|
637/* create a new pcm */ 638int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 639{ 640 struct snd_soc_codec *codec = rtd->codec; 641 struct snd_soc_platform *platform = rtd->platform; 642 struct snd_soc_dai *codec_dai = rtd->codec_dai; 643 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 1685/* create a new pcm */ 1686int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 1687{ 1688 struct snd_soc_codec *codec = rtd->codec; 1689 struct snd_soc_platform *platform = rtd->platform; 1690 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1691 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
644 struct snd_pcm_ops *soc_pcm_ops = &rtd->ops; | |
645 struct snd_pcm *pcm; 646 char new_name[64]; 647 int ret = 0, playback = 0, capture = 0; 648 | 1692 struct snd_pcm *pcm; 1693 char new_name[64]; 1694 int ret = 0, playback = 0, capture = 0; 1695 |
649 soc_pcm_ops->open = soc_pcm_open; 650 soc_pcm_ops->close = soc_pcm_close; 651 soc_pcm_ops->hw_params = soc_pcm_hw_params; 652 soc_pcm_ops->hw_free = soc_pcm_hw_free; 653 soc_pcm_ops->prepare = soc_pcm_prepare; 654 soc_pcm_ops->trigger = soc_pcm_trigger; 655 soc_pcm_ops->pointer = soc_pcm_pointer; | 1696 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { 1697 if (cpu_dai->driver->playback.channels_min) 1698 playback = 1; 1699 if (cpu_dai->driver->capture.channels_min) 1700 capture = 1; 1701 } else { 1702 if (codec_dai->driver->playback.channels_min) 1703 playback = 1; 1704 if (codec_dai->driver->capture.channels_min) 1705 capture = 1; 1706 } |
656 | 1707 |
657 /* check client and interface hw capabilities */ 658 snprintf(new_name, sizeof(new_name), "%s %s-%d", 659 rtd->dai_link->stream_name, codec_dai->name, num); | 1708 /* create the PCM */ 1709 if (rtd->dai_link->no_pcm) { 1710 snprintf(new_name, sizeof(new_name), "(%s)", 1711 rtd->dai_link->stream_name); |
660 | 1712 |
661 if (codec_dai->driver->playback.channels_min) 662 playback = 1; 663 if (codec_dai->driver->capture.channels_min) 664 capture = 1; | 1713 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 1714 playback, capture, &pcm); 1715 } else { 1716 if (rtd->dai_link->dynamic) 1717 snprintf(new_name, sizeof(new_name), "%s (*)", 1718 rtd->dai_link->stream_name); 1719 else 1720 snprintf(new_name, sizeof(new_name), "%s %s-%d", 1721 rtd->dai_link->stream_name, codec_dai->name, num); |
665 | 1722 |
666 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name); 667 ret = snd_pcm_new(rtd->card->snd_card, new_name, 668 num, playback, capture, &pcm); | 1723 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback, 1724 capture, &pcm); 1725 } |
669 if (ret < 0) { 670 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 671 return ret; 672 } | 1726 if (ret < 0) { 1727 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 1728 return ret; 1729 } |
1730 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); |
|
673 674 /* DAPM dai link stream work */ 675 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 676 677 rtd->pcm = pcm; 678 pcm->private_data = rtd; | 1731 1732 /* DAPM dai link stream work */ 1733 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 1734 1735 rtd->pcm = pcm; 1736 pcm->private_data = rtd; |
1737 1738 if (rtd->dai_link->no_pcm) { 1739 if (playback) 1740 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; 1741 if (capture) 1742 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; 1743 goto out; 1744 } 1745 1746 /* ASoC PCM operations */ 1747 if (rtd->dai_link->dynamic) { 1748 rtd->ops.open = dpcm_fe_dai_open; 1749 rtd->ops.hw_params = dpcm_fe_dai_hw_params; 1750 rtd->ops.prepare = dpcm_fe_dai_prepare; 1751 rtd->ops.trigger = dpcm_fe_dai_trigger; 1752 rtd->ops.hw_free = dpcm_fe_dai_hw_free; 1753 rtd->ops.close = dpcm_fe_dai_close; 1754 rtd->ops.pointer = soc_pcm_pointer; 1755 } else { 1756 rtd->ops.open = soc_pcm_open; 1757 rtd->ops.hw_params = soc_pcm_hw_params; 1758 rtd->ops.prepare = soc_pcm_prepare; 1759 rtd->ops.trigger = soc_pcm_trigger; 1760 rtd->ops.hw_free = soc_pcm_hw_free; 1761 rtd->ops.close = soc_pcm_close; 1762 rtd->ops.pointer = soc_pcm_pointer; 1763 } 1764 |
|
679 if (platform->driver->ops) { | 1765 if (platform->driver->ops) { |
680 soc_pcm_ops->mmap = platform->driver->ops->mmap; 681 soc_pcm_ops->pointer = platform->driver->ops->pointer; 682 soc_pcm_ops->ioctl = platform->driver->ops->ioctl; 683 soc_pcm_ops->copy = platform->driver->ops->copy; 684 soc_pcm_ops->silence = platform->driver->ops->silence; 685 soc_pcm_ops->ack = platform->driver->ops->ack; 686 soc_pcm_ops->page = platform->driver->ops->page; | 1766 rtd->ops.ack = platform->driver->ops->ack; 1767 rtd->ops.copy = platform->driver->ops->copy; 1768 rtd->ops.silence = platform->driver->ops->silence; 1769 rtd->ops.page = platform->driver->ops->page; 1770 rtd->ops.mmap = platform->driver->ops->mmap; |
687 } 688 689 if (playback) | 1771 } 1772 1773 if (playback) |
690 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops); | 1774 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops); |
691 692 if (capture) | 1775 1776 if (capture) |
693 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops); | 1777 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); |
694 695 if (platform->driver->pcm_new) { 696 ret = platform->driver->pcm_new(rtd); 697 if (ret < 0) { 698 pr_err("asoc: platform pcm constructor failed\n"); 699 return ret; 700 } 701 } 702 703 pcm->private_free = platform->driver->pcm_free; | 1778 1779 if (platform->driver->pcm_new) { 1780 ret = platform->driver->pcm_new(rtd); 1781 if (ret < 0) { 1782 pr_err("asoc: platform pcm constructor failed\n"); 1783 return ret; 1784 } 1785 } 1786 1787 pcm->private_free = platform->driver->pcm_free; |
1788out: |
|
704 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 705 cpu_dai->name); 706 return ret; 707} | 1789 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1790 cpu_dai->name); 1791 return ret; 1792} |
1793 1794/* is the current PCM operation for this FE ? */ 1795int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream) 1796{ 1797 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) 1798 return 1; 1799 return 0; 1800} 1801EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update); 1802 1803/* is the current PCM operation for this BE ? */ 1804int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe, 1805 struct snd_soc_pcm_runtime *be, int stream) 1806{ 1807 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) || 1808 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) && 1809 be->dpcm[stream].runtime_update)) 1810 return 1; 1811 return 0; 1812} 1813EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update); 1814 1815/* get the substream for this BE */ 1816struct snd_pcm_substream * 1817 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream) 1818{ 1819 return be->pcm->streams[stream].substream; 1820} 1821EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream); 1822 1823/* get the BE runtime state */ 1824enum snd_soc_dpcm_state 1825 snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream) 1826{ 1827 return be->dpcm[stream].state; 1828} 1829EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state); 1830 1831/* set the BE runtime state */ 1832void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, 1833 int stream, enum snd_soc_dpcm_state state) 1834{ 1835 be->dpcm[stream].state = state; 1836} 1837EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state); 1838 1839/* 1840 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE 1841 * are not running, paused or suspended for the specified stream direction. 1842 */ 1843int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, 1844 struct snd_soc_pcm_runtime *be, int stream) 1845{ 1846 struct snd_soc_dpcm *dpcm; 1847 int state; 1848 1849 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) { 1850 1851 if (dpcm->fe == fe) 1852 continue; 1853 1854 state = dpcm->fe->dpcm[stream].state; 1855 if (state == SND_SOC_DPCM_STATE_START || 1856 state == SND_SOC_DPCM_STATE_PAUSED || 1857 state == SND_SOC_DPCM_STATE_SUSPEND) 1858 return 0; 1859 } 1860 1861 /* it's safe to free/stop this BE DAI */ 1862 return 1; 1863} 1864EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop); 1865 1866/* 1867 * We can only change hw params a BE DAI if any of it's FE are not prepared, 1868 * running, paused or suspended for the specified stream direction. 1869 */ 1870int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, 1871 struct snd_soc_pcm_runtime *be, int stream) 1872{ 1873 struct snd_soc_dpcm *dpcm; 1874 int state; 1875 1876 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) { 1877 1878 if (dpcm->fe == fe) 1879 continue; 1880 1881 state = dpcm->fe->dpcm[stream].state; 1882 if (state == SND_SOC_DPCM_STATE_START || 1883 state == SND_SOC_DPCM_STATE_PAUSED || 1884 state == SND_SOC_DPCM_STATE_SUSPEND || 1885 state == SND_SOC_DPCM_STATE_PREPARE) 1886 return 0; 1887 } 1888 1889 /* it's safe to change hw_params */ 1890 return 1; 1891} 1892EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); |
|