soc-pcm.c (5c68005083d620b1499fc81926a514d39ae8b88c) | soc-pcm.c (1c943f60e830d0b959c765df09d4c4b254de0481) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// soc-pcm.c -- ALSA SoC PCM 4// 5// Copyright 2005 Wolfson Microelectronics PLC. 6// Copyright 2005 Openedhand Ltd. 7// Copyright (C) 2010 Slimlogic Ltd. 8// Copyright (C) 2010 Texas Instruments Inc. 9// 10// Authors: Liam Girdwood <lrg@ti.com> 11// Mark Brown <broonie@opensource.wolfsonmicro.com> 12 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/delay.h> 16#include <linux/pinctrl/consumer.h> | 1// SPDX-License-Identifier: GPL-2.0+ 2// 3// soc-pcm.c -- ALSA SoC PCM 4// 5// Copyright 2005 Wolfson Microelectronics PLC. 6// Copyright 2005 Openedhand Ltd. 7// Copyright (C) 2010 Slimlogic Ltd. 8// Copyright (C) 2010 Texas Instruments Inc. 9// 10// Authors: Liam Girdwood <lrg@ti.com> 11// Mark Brown <broonie@opensource.wolfsonmicro.com> 12 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/delay.h> 16#include <linux/pinctrl/consumer.h> |
17#include <linux/pm_runtime.h> | |
18#include <linux/slab.h> 19#include <linux/workqueue.h> 20#include <linux/export.h> 21#include <linux/debugfs.h> 22#include <sound/core.h> 23#include <sound/pcm.h> 24#include <sound/pcm_params.h> 25#include <sound/soc.h> --- 2374 unchanged lines hidden (view full) --- 2400 struct snd_soc_pcm_runtime *be = dpcm->be; 2401 struct snd_pcm_substream *be_substream = 2402 snd_soc_dpcm_get_substream(be, stream); 2403 2404 /* is this op for this BE ? */ 2405 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 2406 continue; 2407 | 17#include <linux/slab.h> 18#include <linux/workqueue.h> 19#include <linux/export.h> 20#include <linux/debugfs.h> 21#include <sound/core.h> 22#include <sound/pcm.h> 23#include <sound/pcm_params.h> 24#include <sound/soc.h> --- 2374 unchanged lines hidden (view full) --- 2399 struct snd_soc_pcm_runtime *be = dpcm->be; 2400 struct snd_pcm_substream *be_substream = 2401 snd_soc_dpcm_get_substream(be, stream); 2402 2403 /* is this op for this BE ? */ 2404 if (!snd_soc_dpcm_be_can_update(fe, be, stream)) 2405 continue; 2406 |
2408 if (!snd_soc_dpcm_can_be_prepared(fe, be, stream)) 2409 continue; 2410 | |
2411 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 2412 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && 2413 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) && 2414 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) 2415 continue; 2416 2417 dev_dbg(be->dev, "ASoC: prepare BE %s\n", 2418 be->dai_link->name); --- 310 unchanged lines hidden (view full) --- 2729open_end: 2730 snd_soc_dpcm_mutex_unlock(fe); 2731 return ret; 2732} 2733 2734static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, 2735 int *playback, int *capture) 2736{ | 2407 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 2408 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && 2409 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) && 2410 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) 2411 continue; 2412 2413 dev_dbg(be->dev, "ASoC: prepare BE %s\n", 2414 be->dai_link->name); --- 310 unchanged lines hidden (view full) --- 2725open_end: 2726 snd_soc_dpcm_mutex_unlock(fe); 2727 return ret; 2728} 2729 2730static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, 2731 int *playback, int *capture) 2732{ |
2733 struct snd_soc_dai_link *dai_link = rtd->dai_link; |
|
2737 struct snd_soc_dai *cpu_dai; | 2734 struct snd_soc_dai *cpu_dai; |
2735 int has_playback = 0; 2736 int has_capture = 0; |
|
2738 int i; 2739 | 2737 int i; 2738 |
2740 if (rtd->dai_link->dynamic && rtd->dai_link->num_cpus > 1) { 2741 dev_err(rtd->dev, 2742 "DPCM doesn't support Multi CPU for Front-Ends yet\n"); | 2739 if (dai_link->dynamic && dai_link->num_cpus > 1) { 2740 dev_err(rtd->dev, "DPCM doesn't support Multi CPU for Front-Ends yet\n"); |
2743 return -EINVAL; 2744 } 2745 | 2741 return -EINVAL; 2742 } 2743 |
2746 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { | 2744 if (dai_link->dynamic || dai_link->no_pcm) { |
2747 int stream; 2748 | 2745 int stream; 2746 |
2749 if (rtd->dai_link->dpcm_playback) { | 2747 if (dai_link->dpcm_playback) { |
2750 stream = SNDRV_PCM_STREAM_PLAYBACK; 2751 2752 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 2753 if (snd_soc_dai_stream_valid(cpu_dai, stream)) { | 2748 stream = SNDRV_PCM_STREAM_PLAYBACK; 2749 2750 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 2751 if (snd_soc_dai_stream_valid(cpu_dai, stream)) { |
2754 *playback = 1; | 2752 has_playback = 1; |
2755 break; 2756 } 2757 } | 2753 break; 2754 } 2755 } |
2758 if (!*playback) { | 2756 if (!has_playback) { |
2759 dev_err(rtd->card->dev, 2760 "No CPU DAIs support playback for stream %s\n", | 2757 dev_err(rtd->card->dev, 2758 "No CPU DAIs support playback for stream %s\n", |
2761 rtd->dai_link->stream_name); | 2759 dai_link->stream_name); |
2762 return -EINVAL; 2763 } 2764 } | 2760 return -EINVAL; 2761 } 2762 } |
2765 if (rtd->dai_link->dpcm_capture) { | 2763 if (dai_link->dpcm_capture) { |
2766 stream = SNDRV_PCM_STREAM_CAPTURE; 2767 2768 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 2769 if (snd_soc_dai_stream_valid(cpu_dai, stream)) { | 2764 stream = SNDRV_PCM_STREAM_CAPTURE; 2765 2766 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 2767 if (snd_soc_dai_stream_valid(cpu_dai, stream)) { |
2770 *capture = 1; | 2768 has_capture = 1; |
2771 break; 2772 } 2773 } 2774 | 2769 break; 2770 } 2771 } 2772 |
2775 if (!*capture) { | 2773 if (!has_capture) { |
2776 dev_err(rtd->card->dev, 2777 "No CPU DAIs support capture for stream %s\n", | 2774 dev_err(rtd->card->dev, 2775 "No CPU DAIs support capture for stream %s\n", |
2778 rtd->dai_link->stream_name); | 2776 dai_link->stream_name); |
2779 return -EINVAL; 2780 } 2781 } 2782 } else { 2783 struct snd_soc_dai *codec_dai; 2784 2785 /* Adapt stream for codec2codec links */ | 2777 return -EINVAL; 2778 } 2779 } 2780 } else { 2781 struct snd_soc_dai *codec_dai; 2782 2783 /* Adapt stream for codec2codec links */ |
2786 int cpu_capture = rtd->dai_link->c2c_params ? 2787 SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; 2788 int cpu_playback = rtd->dai_link->c2c_params ? 2789 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 2784 int cpu_capture = snd_soc_get_stream_cpu(dai_link, SNDRV_PCM_STREAM_CAPTURE); 2785 int cpu_playback = snd_soc_get_stream_cpu(dai_link, SNDRV_PCM_STREAM_PLAYBACK); |
2790 2791 for_each_rtd_codec_dais(rtd, i, codec_dai) { | 2786 2787 for_each_rtd_codec_dais(rtd, i, codec_dai) { |
2792 if (rtd->dai_link->num_cpus == 1) { | 2788 if (dai_link->num_cpus == 1) { |
2793 cpu_dai = asoc_rtd_to_cpu(rtd, 0); | 2789 cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
2794 } else if (rtd->dai_link->num_cpus == rtd->dai_link->num_codecs) { | 2790 } else if (dai_link->num_cpus == dai_link->num_codecs) { |
2795 cpu_dai = asoc_rtd_to_cpu(rtd, i); 2796 } else { 2797 dev_err(rtd->card->dev, 2798 "N cpus to M codecs link is not supported yet\n"); 2799 return -EINVAL; 2800 } 2801 2802 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && 2803 snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) | 2791 cpu_dai = asoc_rtd_to_cpu(rtd, i); 2792 } else { 2793 dev_err(rtd->card->dev, 2794 "N cpus to M codecs link is not supported yet\n"); 2795 return -EINVAL; 2796 } 2797 2798 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) && 2799 snd_soc_dai_stream_valid(cpu_dai, cpu_playback)) |
2804 *playback = 1; | 2800 has_playback = 1; |
2805 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && 2806 snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) | 2801 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) && 2802 snd_soc_dai_stream_valid(cpu_dai, cpu_capture)) |
2807 *capture = 1; | 2803 has_capture = 1; |
2808 } 2809 } 2810 | 2804 } 2805 } 2806 |
2811 if (rtd->dai_link->playback_only) { 2812 *playback = 1; 2813 *capture = 0; 2814 } | 2807 if (dai_link->playback_only) 2808 has_capture = 0; |
2815 | 2809 |
2816 if (rtd->dai_link->capture_only) { 2817 *playback = 0; 2818 *capture = 1; | 2810 if (dai_link->capture_only) 2811 has_playback = 0; 2812 2813 if (!has_playback && !has_capture) { 2814 dev_err(rtd->dev, "substream %s has no playback, no capture\n", 2815 dai_link->stream_name); 2816 2817 return -EINVAL; |
2819 } 2820 | 2818 } 2819 |
2820 *playback = has_playback; 2821 *capture = has_capture; 2822 |
|
2821 return 0; 2822} 2823 2824static int soc_create_pcm(struct snd_pcm **pcm, 2825 struct snd_soc_pcm_runtime *rtd, 2826 int playback, int capture, int num) 2827{ 2828 char new_name[64]; --- 211 unchanged lines hidden (view full) --- 3040 SND_SOC_DPCM_STATE_PAUSED, 3041 SND_SOC_DPCM_STATE_SUSPEND, 3042 SND_SOC_DPCM_STATE_PREPARE, 3043 }; 3044 3045 return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); 3046} 3047EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); | 2823 return 0; 2824} 2825 2826static int soc_create_pcm(struct snd_pcm **pcm, 2827 struct snd_soc_pcm_runtime *rtd, 2828 int playback, int capture, int num) 2829{ 2830 char new_name[64]; --- 211 unchanged lines hidden (view full) --- 3042 SND_SOC_DPCM_STATE_PAUSED, 3043 SND_SOC_DPCM_STATE_SUSPEND, 3044 SND_SOC_DPCM_STATE_PREPARE, 3045 }; 3046 3047 return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); 3048} 3049EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); |
3048 3049/* 3050 * We can only prepare a BE DAI if any of it's FE are not prepared, 3051 * running or paused for the specified stream direction. 3052 */ 3053int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe, 3054 struct snd_soc_pcm_runtime *be, int stream) 3055{ 3056 const enum snd_soc_dpcm_state state[] = { 3057 SND_SOC_DPCM_STATE_START, 3058 SND_SOC_DPCM_STATE_PAUSED, 3059 SND_SOC_DPCM_STATE_PREPARE, 3060 }; 3061 3062 return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state)); 3063} 3064EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_prepared); | |