ASoC: soc-pcm cleanup step4
Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>: Hi Mark These are soc-pcm cleanup step4. [01/13] - [06/13] are posted but not yet accepted patches. To avoid conflict, I merged these into step4. These patches are already received Reviewed-by from Pierre-Louis. Subject: [PATCH 0/6] ASoC: use for_each_rtd_codec_dai() macro Date: Thu, 13 Feb 2020 13:08:07 +0900 Kuninori Morimoto (13): 1) ASoC: soundwaire: qcom: use for_each_rtd_codec_dai() macro 2) ASoC: qcom: sdm845: use for_each_rtd_codec_dai() macro 3) ASoC: qcom: apq8016_sbc: use for_each_rtd_codec_dai() macro 4) ASoC: intel: cml_rt1011_rt5682: use for_each_rtd_codec_dai() macro 5) ASoC: intel: kbl_da7219_max98927: use for_each_rtd_codec_dai() macro 6) ASoC: mediatek: mt8183-da7219-max98357: use for_each_rtd_codec_dai() macro 7) ASoC: soc-pcm: add snd_soc_dai_get_pcm_stream() 8) ASoC: soc-pcm: cleanup soc_pcm_apply_msb() 9) ASoC: soc-pcm: add snd_soc_dai_get_widget() 10) ASoC: soc-pcm: merge dpcm_run_new/old_update() into dpcm_fe_runtime_update() 11) ASoC: soc-pcm: move dpcm_path_put() to soc-pcm.c 12) ASoC: soc-pcm: move CONFIG_DEBUG_FS functions to top side 13) ASoC: soc-pcm: add dpcm_create/remove_debugfs_state() drivers/soundwire/qcom.c | 7 +- include/sound/soc-dai.h | 15 + include/sound/soc-dapm.h | 1 + include/sound/soc-dpcm.h | 7 +- sound/soc/intel/boards/cml_rt1011_rt5682.c | 3 +- sound/soc/intel/boards/kbl_da7219_max98927.c | 8 +- sound/soc/intel/skylake/skl-pcm.c | 10 +- .../mediatek/mt8183/mt8183-da7219-max98357.c | 8 +- sound/soc/qcom/apq8016_sbc.c | 7 +- sound/soc/qcom/sdm845.c | 20 +- sound/soc/soc-dai.c | 7 +- sound/soc/soc-dapm.c | 20 +- sound/soc/soc-pcm.c | 462 ++++++++---------- 13 files changed, 266 insertions(+), 309 deletions(-) -- 2.17.1 Thank you for your help !! Best regards --- Kuninori Morimoto
This commit is contained in:
commit
6bff73c611
include/sound
sound/soc
@ -352,6 +352,21 @@ struct snd_soc_dai {
|
||||
unsigned int started:1;
|
||||
};
|
||||
|
||||
static inline struct snd_soc_pcm_stream *
|
||||
snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
&dai->driver->playback : &dai->driver->capture;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(
|
||||
struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
dai->playback_widget : dai->capture_widget;
|
||||
}
|
||||
|
||||
static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
|
||||
const struct snd_pcm_substream *ss)
|
||||
{
|
||||
|
@ -484,6 +484,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
||||
struct snd_soc_dapm_widget_list **list,
|
||||
bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
|
||||
enum snd_soc_dapm_direction));
|
||||
void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list);
|
||||
|
||||
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
|
||||
struct snd_kcontrol *kcontrol);
|
||||
|
@ -145,6 +145,7 @@ static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
|
||||
|
||||
int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, struct snd_soc_dapm_widget_list **list_);
|
||||
void dpcm_path_put(struct snd_soc_dapm_widget_list **list);
|
||||
int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, struct snd_soc_dapm_widget_list **list, int new);
|
||||
int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
@ -158,10 +159,4 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
|
||||
int event);
|
||||
|
||||
static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
|
||||
{
|
||||
kfree(*list);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -112,10 +112,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dapm_widget *w;
|
||||
struct skl_dev *skl = bus_to_skl(bus);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
w = dai->playback_widget;
|
||||
else
|
||||
w = dai->capture_widget;
|
||||
w = snd_soc_dai_get_widget(dai, substream->stream);
|
||||
|
||||
if (w->ignore_suspend && enable)
|
||||
skl->supend_active++;
|
||||
@ -475,10 +472,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
if (!mconfig)
|
||||
return -EIO;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
w = dai->playback_widget;
|
||||
else
|
||||
w = dai->capture_widget;
|
||||
w = snd_soc_dai_get_widget(dai, substream->stream);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
|
@ -390,12 +390,7 @@ int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
|
||||
*/
|
||||
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
|
||||
{
|
||||
struct snd_soc_pcm_stream *stream;
|
||||
|
||||
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
stream = &dai->driver->playback;
|
||||
else
|
||||
stream = &dai->driver->capture;
|
||||
struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, dir);
|
||||
|
||||
/* If the codec specifies any channels at all, it supports the stream */
|
||||
return stream->channels_min;
|
||||
|
@ -1105,6 +1105,11 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
static void dapm_widget_list_free(struct snd_soc_dapm_widget_list **list)
|
||||
{
|
||||
kfree(*list);
|
||||
}
|
||||
|
||||
static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
|
||||
struct list_head *widgets)
|
||||
{
|
||||
@ -1310,6 +1315,11 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
||||
return paths;
|
||||
}
|
||||
|
||||
void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list)
|
||||
{
|
||||
dapm_widget_list_free(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for regulator supply widget.
|
||||
*/
|
||||
@ -2620,10 +2630,7 @@ static int dapm_update_dai_unlocked(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dapm_widget *w;
|
||||
int ret;
|
||||
|
||||
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
w = dai->playback_widget;
|
||||
else
|
||||
w = dai->capture_widget;
|
||||
w = snd_soc_dai_get_widget(dai, dir);
|
||||
|
||||
if (!w)
|
||||
return 0;
|
||||
@ -4389,10 +4396,7 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
|
||||
struct snd_soc_dapm_widget *w;
|
||||
unsigned int ep;
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
w = dai->playback_widget;
|
||||
else
|
||||
w = dai->capture_widget;
|
||||
w = snd_soc_dai_get_widget(dai, stream);
|
||||
|
||||
if (w) {
|
||||
dapm_mark_dirty(w, "stream event");
|
||||
|
@ -28,6 +28,174 @@
|
||||
|
||||
#define DPCM_MAX_BE_USERS 8
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static const char *dpcm_state_string(enum snd_soc_dpcm_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case SND_SOC_DPCM_STATE_NEW:
|
||||
return "new";
|
||||
case SND_SOC_DPCM_STATE_OPEN:
|
||||
return "open";
|
||||
case SND_SOC_DPCM_STATE_HW_PARAMS:
|
||||
return "hw_params";
|
||||
case SND_SOC_DPCM_STATE_PREPARE:
|
||||
return "prepare";
|
||||
case SND_SOC_DPCM_STATE_START:
|
||||
return "start";
|
||||
case SND_SOC_DPCM_STATE_STOP:
|
||||
return "stop";
|
||||
case SND_SOC_DPCM_STATE_SUSPEND:
|
||||
return "suspend";
|
||||
case SND_SOC_DPCM_STATE_PAUSED:
|
||||
return "paused";
|
||||
case SND_SOC_DPCM_STATE_HW_FREE:
|
||||
return "hw_free";
|
||||
case SND_SOC_DPCM_STATE_CLOSE:
|
||||
return "close";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, char *buf, size_t size)
|
||||
{
|
||||
struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
|
||||
struct snd_soc_dpcm *dpcm;
|
||||
ssize_t offset = 0;
|
||||
unsigned long flags;
|
||||
|
||||
/* FE state */
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"[%s - %s]\n", fe->dai_link->name,
|
||||
stream ? "Capture" : "Playback");
|
||||
|
||||
offset += snprintf(buf + offset, size - offset, "State: %s\n",
|
||||
dpcm_state_string(fe->dpcm[stream].state));
|
||||
|
||||
if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
|
||||
(fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"Hardware Params: "
|
||||
"Format = %s, Channels = %d, Rate = %d\n",
|
||||
snd_pcm_format_name(params_format(params)),
|
||||
params_channels(params),
|
||||
params_rate(params));
|
||||
|
||||
/* BEs state */
|
||||
offset += snprintf(buf + offset, size - offset, "Backends:\n");
|
||||
|
||||
if (list_empty(&fe->dpcm[stream].be_clients)) {
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" No active DSP links\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&fe->card->dpcm_lock, flags);
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
struct snd_soc_pcm_runtime *be = dpcm->be;
|
||||
params = &dpcm->hw_params;
|
||||
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"- %s\n", be->dai_link->name);
|
||||
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" State: %s\n",
|
||||
dpcm_state_string(be->dpcm[stream].state));
|
||||
|
||||
if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
|
||||
(be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" Hardware Params: "
|
||||
"Format = %s, Channels = %d, Rate = %d\n",
|
||||
snd_pcm_format_name(params_format(params)),
|
||||
params_channels(params),
|
||||
params_rate(params));
|
||||
}
|
||||
spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
|
||||
out:
|
||||
return offset;
|
||||
}
|
||||
|
||||
static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *fe = file->private_data;
|
||||
ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0;
|
||||
int stream;
|
||||
char *buf;
|
||||
|
||||
buf = kmalloc(out_count, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_pcm_streams(stream)
|
||||
if (snd_soc_dai_stream_valid(fe->cpu_dai, stream))
|
||||
offset += dpcm_show_state(fe, stream,
|
||||
buf + offset,
|
||||
out_count - offset);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
|
||||
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations dpcm_state_fops = {
|
||||
.open = simple_open,
|
||||
.read = dpcm_state_read_file,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
if (!rtd->dai_link)
|
||||
return;
|
||||
|
||||
if (!rtd->dai_link->dynamic)
|
||||
return;
|
||||
|
||||
if (!rtd->card->debugfs_card_root)
|
||||
return;
|
||||
|
||||
rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
|
||||
rtd->card->debugfs_card_root);
|
||||
|
||||
debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root,
|
||||
rtd, &dpcm_state_fops);
|
||||
}
|
||||
|
||||
static void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm, int stream)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = kasprintf(GFP_KERNEL, "%s:%s", dpcm->be->dai_link->name,
|
||||
stream ? "capture" : "playback");
|
||||
if (name) {
|
||||
dpcm->debugfs_state = debugfs_create_dir(
|
||||
name, dpcm->fe->debugfs_dpcm_root);
|
||||
debugfs_create_u32("state", 0644, dpcm->debugfs_state,
|
||||
&dpcm->state);
|
||||
kfree(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm)
|
||||
{
|
||||
debugfs_remove_recursive(dpcm->debugfs_state);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm,
|
||||
int stream)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int soc_rtd_startup(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
@ -82,15 +250,6 @@ static int soc_rtd_trigger(struct snd_soc_pcm_runtime *rtd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct snd_soc_dapm_widget *dai_get_widget(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return dai->playback_widget;
|
||||
else
|
||||
return dai->capture_widget;
|
||||
}
|
||||
|
||||
static void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
|
||||
int stream, int action)
|
||||
{
|
||||
@ -363,29 +522,24 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
|
||||
int stream = substream->stream;
|
||||
int i;
|
||||
unsigned int bits = 0, cpu_bits;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
for_each_rtd_codec_dai(rtd, i, codec_dai) {
|
||||
if (codec_dai->driver->playback.sig_bits == 0) {
|
||||
bits = 0;
|
||||
break;
|
||||
}
|
||||
bits = max(codec_dai->driver->playback.sig_bits, bits);
|
||||
for_each_rtd_codec_dai(rtd, i, codec_dai) {
|
||||
pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream);
|
||||
|
||||
if (pcm_codec->sig_bits == 0) {
|
||||
bits = 0;
|
||||
break;
|
||||
}
|
||||
cpu_bits = cpu_dai->driver->playback.sig_bits;
|
||||
} else {
|
||||
for_each_rtd_codec_dai(rtd, i, codec_dai) {
|
||||
if (codec_dai->driver->capture.sig_bits == 0) {
|
||||
bits = 0;
|
||||
break;
|
||||
}
|
||||
bits = max(codec_dai->driver->capture.sig_bits, bits);
|
||||
}
|
||||
cpu_bits = cpu_dai->driver->capture.sig_bits;
|
||||
bits = max(pcm_codec->sig_bits, bits);
|
||||
}
|
||||
|
||||
pcm_cpu = snd_soc_dai_get_pcm_stream(cpu_dai, stream);
|
||||
cpu_bits = pcm_cpu->sig_bits;
|
||||
|
||||
soc_pcm_set_msb(substream, bits);
|
||||
soc_pcm_set_msb(substream, cpu_bits);
|
||||
}
|
||||
@ -396,20 +550,16 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_hardware *hw = &runtime->hw;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_dai_driver *cpu_dai_drv = rtd->cpu_dai->driver;
|
||||
struct snd_soc_dai_driver *codec_dai_drv;
|
||||
struct snd_soc_pcm_stream *codec_stream;
|
||||
struct snd_soc_pcm_stream *cpu_stream;
|
||||
unsigned int chan_min = 0, chan_max = UINT_MAX;
|
||||
unsigned int rate_min = 0, rate_max = UINT_MAX;
|
||||
unsigned int rates = UINT_MAX;
|
||||
u64 formats = ULLONG_MAX;
|
||||
int stream = substream->stream;
|
||||
int i;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
cpu_stream = &cpu_dai_drv->playback;
|
||||
else
|
||||
cpu_stream = &cpu_dai_drv->capture;
|
||||
cpu_stream = snd_soc_dai_get_pcm_stream(rtd->cpu_dai, stream);
|
||||
|
||||
/* first calculate min/max only for CODECs in the DAI link */
|
||||
for_each_rtd_codec_dai(rtd, i, codec_dai) {
|
||||
@ -427,11 +577,8 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
|
||||
substream->stream))
|
||||
continue;
|
||||
|
||||
codec_dai_drv = codec_dai->driver;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
codec_stream = &codec_dai_drv->playback;
|
||||
else
|
||||
codec_stream = &codec_dai_drv->capture;
|
||||
codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream);
|
||||
|
||||
chan_min = max(chan_min, codec_stream->channels_min);
|
||||
chan_max = min(chan_max, codec_stream->channels_max);
|
||||
rate_min = max(rate_min, codec_stream->rate_min);
|
||||
@ -1152,9 +1299,6 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
|
||||
{
|
||||
struct snd_soc_dpcm *dpcm;
|
||||
unsigned long flags;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
char *name;
|
||||
#endif
|
||||
|
||||
/* only add new dpcms */
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
@ -1179,17 +1323,8 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
|
||||
stream ? "capture" : "playback", fe->dai_link->name,
|
||||
stream ? "<-" : "->", be->dai_link->name);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
name = kasprintf(GFP_KERNEL, "%s:%s", be->dai_link->name,
|
||||
stream ? "capture" : "playback");
|
||||
if (name) {
|
||||
dpcm->debugfs_state = debugfs_create_dir(name,
|
||||
fe->debugfs_dpcm_root);
|
||||
debugfs_create_u32("state", 0644, dpcm->debugfs_state,
|
||||
&dpcm->state);
|
||||
kfree(name);
|
||||
}
|
||||
#endif
|
||||
dpcm_create_debugfs_state(dpcm, stream);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1242,9 +1377,8 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
|
||||
/* BEs still alive need new FE */
|
||||
dpcm_be_reparent(fe, dpcm->be, stream);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
debugfs_remove_recursive(dpcm->debugfs_state);
|
||||
#endif
|
||||
dpcm_remove_debugfs_state(dpcm);
|
||||
|
||||
spin_lock_irqsave(&fe->card->dpcm_lock, flags);
|
||||
list_del(&dpcm->list_be);
|
||||
list_del(&dpcm->list_fe);
|
||||
@ -1269,7 +1403,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
|
||||
if (!be->dai_link->no_pcm)
|
||||
continue;
|
||||
|
||||
w = dai_get_widget(be->cpu_dai, stream);
|
||||
w = snd_soc_dai_get_widget(be->cpu_dai, stream);
|
||||
|
||||
dev_dbg(card->dev, "ASoC: try BE : %s\n",
|
||||
w ? w->name : "(not set)");
|
||||
@ -1278,7 +1412,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
|
||||
return be;
|
||||
|
||||
for_each_rtd_codec_dai(be, i, dai) {
|
||||
w = dai_get_widget(dai, stream);
|
||||
w = snd_soc_dai_get_widget(dai, stream);
|
||||
|
||||
if (w == widget)
|
||||
return be;
|
||||
@ -1338,6 +1472,11 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
|
||||
return paths;
|
||||
}
|
||||
|
||||
void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
|
||||
{
|
||||
snd_soc_dapm_dai_free_widgets(list);
|
||||
}
|
||||
|
||||
static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
|
||||
struct snd_soc_dapm_widget_list **list_)
|
||||
{
|
||||
@ -1353,7 +1492,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
|
||||
unsigned int i;
|
||||
|
||||
/* is there a valid CPU DAI widget for this BE */
|
||||
widget = dai_get_widget(dpcm->be->cpu_dai, stream);
|
||||
widget = snd_soc_dai_get_widget(dpcm->be->cpu_dai, stream);
|
||||
|
||||
/* prune the BE if it's no longer in our active list */
|
||||
if (widget && widget_in_list(list, widget))
|
||||
@ -1362,7 +1501,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
|
||||
/* is there a valid CODEC DAI widget for this BE */
|
||||
do_prune = 1;
|
||||
for_each_rtd_codec_dai(dpcm->be, i, dai) {
|
||||
widget = dai_get_widget(dai, stream);
|
||||
widget = snd_soc_dai_get_widget(dai, stream);
|
||||
|
||||
/* prune the BE if it's no longer in our active list */
|
||||
if (widget && widget_in_list(list, widget))
|
||||
@ -1615,7 +1754,6 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
|
||||
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
struct snd_soc_pcm_runtime *be = dpcm->be;
|
||||
struct snd_soc_dai_driver *codec_dai_drv;
|
||||
struct snd_soc_pcm_stream *codec_stream;
|
||||
int i;
|
||||
|
||||
@ -1627,11 +1765,7 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
|
||||
if (!snd_soc_dai_stream_valid(dai, stream))
|
||||
continue;
|
||||
|
||||
codec_dai_drv = dai->driver;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
codec_stream = &codec_dai_drv->playback;
|
||||
else
|
||||
codec_stream = &codec_dai_drv->capture;
|
||||
codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
|
||||
|
||||
*formats &= codec_stream->formats;
|
||||
}
|
||||
@ -1656,15 +1790,10 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
|
||||
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
struct snd_soc_pcm_runtime *be = dpcm->be;
|
||||
struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver;
|
||||
struct snd_soc_dai_driver *codec_dai_drv;
|
||||
struct snd_soc_pcm_stream *codec_stream;
|
||||
struct snd_soc_pcm_stream *cpu_stream;
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
cpu_stream = &cpu_dai_drv->playback;
|
||||
else
|
||||
cpu_stream = &cpu_dai_drv->capture;
|
||||
cpu_stream = snd_soc_dai_get_pcm_stream(be->cpu_dai, stream);
|
||||
|
||||
*channels_min = max(*channels_min, cpu_stream->channels_min);
|
||||
*channels_max = min(*channels_max, cpu_stream->channels_max);
|
||||
@ -1674,12 +1803,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
|
||||
* DAIs connected to a single CPU DAI, use CPU DAI's directly
|
||||
*/
|
||||
if (be->num_codecs == 1) {
|
||||
codec_dai_drv = be->codec_dais[0]->driver;
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
codec_stream = &codec_dai_drv->playback;
|
||||
else
|
||||
codec_stream = &codec_dai_drv->capture;
|
||||
codec_stream = snd_soc_dai_get_pcm_stream(be->codec_dais[0], stream);
|
||||
|
||||
*channels_min = max(*channels_min,
|
||||
codec_stream->channels_min);
|
||||
@ -1708,17 +1832,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
|
||||
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
struct snd_soc_pcm_runtime *be = dpcm->be;
|
||||
struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver;
|
||||
struct snd_soc_dai_driver *codec_dai_drv;
|
||||
struct snd_soc_pcm_stream *codec_stream;
|
||||
struct snd_soc_pcm_stream *cpu_stream;
|
||||
struct snd_soc_dai *dai;
|
||||
int i;
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
cpu_stream = &cpu_dai_drv->playback;
|
||||
else
|
||||
cpu_stream = &cpu_dai_drv->capture;
|
||||
cpu_stream = snd_soc_dai_get_pcm_stream(be->cpu_dai, stream);
|
||||
|
||||
*rate_min = max(*rate_min, cpu_stream->rate_min);
|
||||
*rate_max = min_not_zero(*rate_max, cpu_stream->rate_max);
|
||||
@ -1732,11 +1851,7 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
|
||||
if (!snd_soc_dai_stream_valid(dai, stream))
|
||||
continue;
|
||||
|
||||
codec_dai_drv = dai->driver;
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
codec_stream = &codec_dai_drv->playback;
|
||||
else
|
||||
codec_stream = &codec_dai_drv->capture;
|
||||
codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
|
||||
|
||||
*rate_min = max(*rate_min, codec_stream->rate_min);
|
||||
*rate_max = min_not_zero(*rate_max,
|
||||
@ -2596,37 +2711,12 @@ disconnect:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
|
||||
ret = dpcm_run_update_startup(fe, stream);
|
||||
if (ret < 0)
|
||||
dev_err(fe->dev, "ASoC: failed to startup some BEs\n");
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
|
||||
ret = dpcm_run_update_shutdown(fe, stream);
|
||||
if (ret < 0)
|
||||
dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
|
||||
{
|
||||
struct snd_soc_dapm_widget_list *list;
|
||||
int stream;
|
||||
int count, paths;
|
||||
int ret;
|
||||
|
||||
if (!fe->dai_link->dynamic)
|
||||
return 0;
|
||||
@ -2663,10 +2753,14 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
|
||||
/* update any playback/capture paths */
|
||||
count = dpcm_process_paths(fe, stream, &list, new);
|
||||
if (count) {
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
|
||||
if (new)
|
||||
dpcm_run_new_update(fe, stream);
|
||||
ret = dpcm_run_update_startup(fe, stream);
|
||||
else
|
||||
dpcm_run_old_update(fe, stream);
|
||||
ret = dpcm_run_update_shutdown(fe, stream);
|
||||
if (ret < 0)
|
||||
dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
|
||||
|
||||
dpcm_clear_pending_state(fe, stream);
|
||||
dpcm_be_disconnect(fe, stream);
|
||||
@ -3006,141 +3100,3 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
|
||||
return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static const char *dpcm_state_string(enum snd_soc_dpcm_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case SND_SOC_DPCM_STATE_NEW:
|
||||
return "new";
|
||||
case SND_SOC_DPCM_STATE_OPEN:
|
||||
return "open";
|
||||
case SND_SOC_DPCM_STATE_HW_PARAMS:
|
||||
return "hw_params";
|
||||
case SND_SOC_DPCM_STATE_PREPARE:
|
||||
return "prepare";
|
||||
case SND_SOC_DPCM_STATE_START:
|
||||
return "start";
|
||||
case SND_SOC_DPCM_STATE_STOP:
|
||||
return "stop";
|
||||
case SND_SOC_DPCM_STATE_SUSPEND:
|
||||
return "suspend";
|
||||
case SND_SOC_DPCM_STATE_PAUSED:
|
||||
return "paused";
|
||||
case SND_SOC_DPCM_STATE_HW_FREE:
|
||||
return "hw_free";
|
||||
case SND_SOC_DPCM_STATE_CLOSE:
|
||||
return "close";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, char *buf, size_t size)
|
||||
{
|
||||
struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
|
||||
struct snd_soc_dpcm *dpcm;
|
||||
ssize_t offset = 0;
|
||||
unsigned long flags;
|
||||
|
||||
/* FE state */
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"[%s - %s]\n", fe->dai_link->name,
|
||||
stream ? "Capture" : "Playback");
|
||||
|
||||
offset += snprintf(buf + offset, size - offset, "State: %s\n",
|
||||
dpcm_state_string(fe->dpcm[stream].state));
|
||||
|
||||
if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
|
||||
(fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"Hardware Params: "
|
||||
"Format = %s, Channels = %d, Rate = %d\n",
|
||||
snd_pcm_format_name(params_format(params)),
|
||||
params_channels(params),
|
||||
params_rate(params));
|
||||
|
||||
/* BEs state */
|
||||
offset += snprintf(buf + offset, size - offset, "Backends:\n");
|
||||
|
||||
if (list_empty(&fe->dpcm[stream].be_clients)) {
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" No active DSP links\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&fe->card->dpcm_lock, flags);
|
||||
for_each_dpcm_be(fe, stream, dpcm) {
|
||||
struct snd_soc_pcm_runtime *be = dpcm->be;
|
||||
params = &dpcm->hw_params;
|
||||
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
"- %s\n", be->dai_link->name);
|
||||
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" State: %s\n",
|
||||
dpcm_state_string(be->dpcm[stream].state));
|
||||
|
||||
if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
|
||||
(be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
|
||||
offset += snprintf(buf + offset, size - offset,
|
||||
" Hardware Params: "
|
||||
"Format = %s, Channels = %d, Rate = %d\n",
|
||||
snd_pcm_format_name(params_format(params)),
|
||||
params_channels(params),
|
||||
params_rate(params));
|
||||
}
|
||||
spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
|
||||
out:
|
||||
return offset;
|
||||
}
|
||||
|
||||
static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *fe = file->private_data;
|
||||
ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0;
|
||||
int stream;
|
||||
char *buf;
|
||||
|
||||
buf = kmalloc(out_count, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for_each_pcm_streams(stream)
|
||||
if (snd_soc_dai_stream_valid(fe->cpu_dai, stream))
|
||||
offset += dpcm_show_state(fe, stream,
|
||||
buf + offset,
|
||||
out_count - offset);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
|
||||
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations dpcm_state_fops = {
|
||||
.open = simple_open,
|
||||
.read = dpcm_state_read_file,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
if (!rtd->dai_link)
|
||||
return;
|
||||
|
||||
if (!rtd->dai_link->dynamic)
|
||||
return;
|
||||
|
||||
if (!rtd->card->debugfs_card_root)
|
||||
return;
|
||||
|
||||
rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
|
||||
rtd->card->debugfs_card_root);
|
||||
|
||||
debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root,
|
||||
rtd, &dpcm_state_fops);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user