Commit 6bff73c6 authored by Mark Brown's avatar Mark Brown

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
parents d2aaa8d8 154dae87
...@@ -352,6 +352,21 @@ struct snd_soc_dai { ...@@ -352,6 +352,21 @@ struct snd_soc_dai {
unsigned int started:1; 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, static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
const struct snd_pcm_substream *ss) 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, ...@@ -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, struct snd_soc_dapm_widget_list **list,
bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
enum snd_soc_dapm_direction)); 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_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
struct snd_kcontrol *kcontrol); struct snd_kcontrol *kcontrol);
......
...@@ -145,6 +145,7 @@ static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) ...@@ -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 dpcm_path_get(struct snd_soc_pcm_runtime *fe,
int stream, struct snd_soc_dapm_widget_list **list_); 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 dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
int stream, struct snd_soc_dapm_widget_list **list, int new); int stream, struct snd_soc_dapm_widget_list **list, int new);
int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream); 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); ...@@ -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 dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
int event); int event);
static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
{
kfree(*list);
}
#endif #endif
...@@ -112,10 +112,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, ...@@ -112,10 +112,7 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream,
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
struct skl_dev *skl = bus_to_skl(bus); struct skl_dev *skl = bus_to_skl(bus);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) w = snd_soc_dai_get_widget(dai, substream->stream);
w = dai->playback_widget;
else
w = dai->capture_widget;
if (w->ignore_suspend && enable) if (w->ignore_suspend && enable)
skl->supend_active++; skl->supend_active++;
...@@ -475,10 +472,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -475,10 +472,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
if (!mconfig) if (!mconfig)
return -EIO; return -EIO;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) w = snd_soc_dai_get_widget(dai, substream->stream);
w = dai->playback_widget;
else
w = dai->capture_widget;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
......
...@@ -390,12 +390,7 @@ int snd_soc_dai_compress_new(struct snd_soc_dai *dai, ...@@ -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) bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
{ {
struct snd_soc_pcm_stream *stream; struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, dir);
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
stream = &dai->driver->playback;
else
stream = &dai->driver->capture;
/* If the codec specifies any channels at all, it supports the stream */ /* If the codec specifies any channels at all, it supports the stream */
return stream->channels_min; return stream->channels_min;
......
...@@ -1105,6 +1105,11 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) ...@@ -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, static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
struct list_head *widgets) struct list_head *widgets)
{ {
...@@ -1310,6 +1315,11 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, ...@@ -1310,6 +1315,11 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
return paths; 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. * Handler for regulator supply widget.
*/ */
...@@ -2620,10 +2630,7 @@ static int dapm_update_dai_unlocked(struct snd_pcm_substream *substream, ...@@ -2620,10 +2630,7 @@ static int dapm_update_dai_unlocked(struct snd_pcm_substream *substream,
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
int ret; int ret;
if (dir == SNDRV_PCM_STREAM_PLAYBACK) w = snd_soc_dai_get_widget(dai, dir);
w = dai->playback_widget;
else
w = dai->capture_widget;
if (!w) if (!w)
return 0; return 0;
...@@ -4389,10 +4396,7 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, ...@@ -4389,10 +4396,7 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
unsigned int ep; unsigned int ep;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) w = snd_soc_dai_get_widget(dai, stream);
w = dai->playback_widget;
else
w = dai->capture_widget;
if (w) { if (w) {
dapm_mark_dirty(w, "stream event"); dapm_mark_dirty(w, "stream event");
......
...@@ -28,6 +28,174 @@ ...@@ -28,6 +28,174 @@
#define DPCM_MAX_BE_USERS 8 #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, static int soc_rtd_startup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
...@@ -82,15 +250,6 @@ static int soc_rtd_trigger(struct snd_soc_pcm_runtime *rtd, ...@@ -82,15 +250,6 @@ static int soc_rtd_trigger(struct snd_soc_pcm_runtime *rtd,
return 0; 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, static void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
int stream, int action) int stream, int action)
{ {
...@@ -363,29 +522,24 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream) ...@@ -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_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
int stream = substream->stream;
int i; int i;
unsigned int bits = 0, cpu_bits; unsigned int bits = 0, cpu_bits;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { for_each_rtd_codec_dai(rtd, i, codec_dai) {
for_each_rtd_codec_dai(rtd, i, codec_dai) { pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream);
if (codec_dai->driver->playback.sig_bits == 0) {
bits = 0; if (pcm_codec->sig_bits == 0) {
break; bits = 0;
} break;
bits = max(codec_dai->driver->playback.sig_bits, bits);
}
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, bits);
soc_pcm_set_msb(substream, cpu_bits); soc_pcm_set_msb(substream, cpu_bits);
} }
...@@ -396,20 +550,16 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) ...@@ -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_pcm_hardware *hw = &runtime->hw;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai; 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 *codec_stream;
struct snd_soc_pcm_stream *cpu_stream; struct snd_soc_pcm_stream *cpu_stream;
unsigned int chan_min = 0, chan_max = UINT_MAX; unsigned int chan_min = 0, chan_max = UINT_MAX;
unsigned int rate_min = 0, rate_max = UINT_MAX; unsigned int rate_min = 0, rate_max = UINT_MAX;
unsigned int rates = UINT_MAX; unsigned int rates = UINT_MAX;
u64 formats = ULLONG_MAX; u64 formats = ULLONG_MAX;
int stream = substream->stream;
int i; int i;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = snd_soc_dai_get_pcm_stream(rtd->cpu_dai, stream);
cpu_stream = &cpu_dai_drv->playback;
else
cpu_stream = &cpu_dai_drv->capture;
/* first calculate min/max only for CODECs in the DAI link */ /* first calculate min/max only for CODECs in the DAI link */
for_each_rtd_codec_dai(rtd, i, codec_dai) { 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) ...@@ -427,11 +577,8 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
substream->stream)) substream->stream))
continue; continue;
codec_dai_drv = codec_dai->driver; codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &codec_dai_drv->playback;
else
codec_stream = &codec_dai_drv->capture;
chan_min = max(chan_min, codec_stream->channels_min); chan_min = max(chan_min, codec_stream->channels_min);
chan_max = min(chan_max, codec_stream->channels_max); chan_max = min(chan_max, codec_stream->channels_max);
rate_min = max(rate_min, codec_stream->rate_min); rate_min = max(rate_min, codec_stream->rate_min);
...@@ -1152,9 +1299,6 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, ...@@ -1152,9 +1299,6 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
{ {
struct snd_soc_dpcm *dpcm; struct snd_soc_dpcm *dpcm;
unsigned long flags; unsigned long flags;
#ifdef CONFIG_DEBUG_FS
char *name;
#endif
/* only add new dpcms */ /* only add new dpcms */
for_each_dpcm_be(fe, stream, dpcm) { for_each_dpcm_be(fe, stream, dpcm) {
...@@ -1179,17 +1323,8 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, ...@@ -1179,17 +1323,8 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
stream ? "capture" : "playback", fe->dai_link->name, stream ? "capture" : "playback", fe->dai_link->name,
stream ? "<-" : "->", be->dai_link->name); stream ? "<-" : "->", be->dai_link->name);
#ifdef CONFIG_DEBUG_FS dpcm_create_debugfs_state(dpcm, stream);
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
return 1; return 1;
} }
...@@ -1242,9 +1377,8 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) ...@@ -1242,9 +1377,8 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
/* BEs still alive need new FE */ /* BEs still alive need new FE */
dpcm_be_reparent(fe, dpcm->be, stream); dpcm_be_reparent(fe, dpcm->be, stream);
#ifdef CONFIG_DEBUG_FS dpcm_remove_debugfs_state(dpcm);
debugfs_remove_recursive(dpcm->debugfs_state);
#endif
spin_lock_irqsave(&fe->card->dpcm_lock, flags); spin_lock_irqsave(&fe->card->dpcm_lock, flags);
list_del(&dpcm->list_be); list_del(&dpcm->list_be);
list_del(&dpcm->list_fe); list_del(&dpcm->list_fe);
...@@ -1269,7 +1403,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, ...@@ -1269,7 +1403,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
if (!be->dai_link->no_pcm) if (!be->dai_link->no_pcm)
continue; 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", dev_dbg(card->dev, "ASoC: try BE : %s\n",
w ? w->name : "(not set)"); w ? w->name : "(not set)");
...@@ -1278,7 +1412,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, ...@@ -1278,7 +1412,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
return be; return be;
for_each_rtd_codec_dai(be, i, dai) { 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) if (w == widget)
return be; return be;
...@@ -1338,6 +1472,11 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe, ...@@ -1338,6 +1472,11 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
return paths; 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, static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
struct snd_soc_dapm_widget_list **list_) struct snd_soc_dapm_widget_list **list_)
{ {
...@@ -1353,7 +1492,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, ...@@ -1353,7 +1492,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
unsigned int i; unsigned int i;
/* is there a valid CPU DAI widget for this BE */ /* 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 */ /* prune the BE if it's no longer in our active list */
if (widget && widget_in_list(list, widget)) if (widget && widget_in_list(list, widget))
...@@ -1362,7 +1501,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, ...@@ -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 */ /* is there a valid CODEC DAI widget for this BE */
do_prune = 1; do_prune = 1;
for_each_rtd_codec_dai(dpcm->be, i, dai) { 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 */ /* prune the BE if it's no longer in our active list */
if (widget && widget_in_list(list, widget)) if (widget && widget_in_list(list, widget))
...@@ -1615,7 +1754,6 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, ...@@ -1615,7 +1754,6 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
for_each_dpcm_be(fe, stream, dpcm) { for_each_dpcm_be(fe, stream, dpcm) {
struct snd_soc_pcm_runtime *be = dpcm->be; struct snd_soc_pcm_runtime *be = dpcm->be;
struct snd_soc_dai_driver *codec_dai_drv;
struct snd_soc_pcm_stream *codec_stream; struct snd_soc_pcm_stream *codec_stream;
int i; int i;
...@@ -1627,11 +1765,7 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, ...@@ -1627,11 +1765,7 @@ static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
if (!snd_soc_dai_stream_valid(dai, stream)) if (!snd_soc_dai_stream_valid(dai, stream))
continue; continue;
codec_dai_drv = dai->driver; codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &codec_dai_drv->playback;
else
codec_stream = &codec_dai_drv->capture;
*formats &= codec_stream->formats; *formats &= codec_stream->formats;
} }
...@@ -1656,15 +1790,10 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, ...@@ -1656,15 +1790,10 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
for_each_dpcm_be(fe, stream, dpcm) { for_each_dpcm_be(fe, stream, dpcm) {
struct snd_soc_pcm_runtime *be = dpcm->be; 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 *codec_stream;
struct snd_soc_pcm_stream *cpu_stream; struct snd_soc_pcm_stream *cpu_stream;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = snd_soc_dai_get_pcm_stream(be->cpu_dai, stream);
cpu_stream = &cpu_dai_drv->playback;
else
cpu_stream = &cpu_dai_drv->capture;
*channels_min = max(*channels_min, cpu_stream->channels_min); *channels_min = max(*channels_min, cpu_stream->channels_min);
*channels_max = min(*channels_max, cpu_stream->channels_max); *channels_max = min(*channels_max, cpu_stream->channels_max);
...@@ -1674,12 +1803,7 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, ...@@ -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 * DAIs connected to a single CPU DAI, use CPU DAI's directly
*/ */
if (be->num_codecs == 1) { if (be->num_codecs == 1) {
codec_dai_drv = be->codec_dais[0]->driver; codec_stream = snd_soc_dai_get_pcm_stream(be->codec_dais[0], stream);
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &codec_dai_drv->playback;
else
codec_stream = &codec_dai_drv->capture;
*channels_min = max(*channels_min, *channels_min = max(*channels_min,
codec_stream->channels_min); codec_stream->channels_min);
...@@ -1708,17 +1832,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, ...@@ -1708,17 +1832,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
for_each_dpcm_be(fe, stream, dpcm) { for_each_dpcm_be(fe, stream, dpcm) {
struct snd_soc_pcm_runtime *be = dpcm->be; 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 *codec_stream;
struct snd_soc_pcm_stream *cpu_stream; struct snd_soc_pcm_stream *cpu_stream;
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
int i; int i;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = snd_soc_dai_get_pcm_stream(be->cpu_dai, stream);
cpu_stream = &cpu_dai_drv->playback;
else
cpu_stream = &cpu_dai_drv->capture;
*rate_min = max(*rate_min, cpu_stream->rate_min); *rate_min = max(*rate_min, cpu_stream->rate_min);
*rate_max = min_not_zero(*rate_max, cpu_stream->rate_max); *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, ...@@ -1732,11 +1851,7 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
if (!snd_soc_dai_stream_valid(dai, stream)) if (!snd_soc_dai_stream_valid(dai, stream))
continue; continue;
codec_dai_drv = dai->driver; codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
codec_stream = &codec_dai_drv->playback;
else
codec_stream = &codec_dai_drv->capture;
*rate_min = max(*rate_min, codec_stream->rate_min); *rate_min = max(*rate_min, codec_stream->rate_min);
*rate_max = min_not_zero(*rate_max, *rate_max = min_not_zero(*rate_max,
...@@ -2596,37 +2711,12 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) ...@@ -2596,37 +2711,12 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
return ret; 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) static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
{ {
struct snd_soc_dapm_widget_list *list; struct snd_soc_dapm_widget_list *list;
int stream; int stream;
int count, paths; int count, paths;
int ret;
if (!fe->dai_link->dynamic) if (!fe->dai_link->dynamic)
return 0; return 0;
...@@ -2663,10 +2753,14 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) ...@@ -2663,10 +2753,14 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
/* update any playback/capture paths */ /* update any playback/capture paths */
count = dpcm_process_paths(fe, stream, &list, new); count = dpcm_process_paths(fe, stream, &list, new);
if (count) { if (count) {
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
if (new) if (new)
dpcm_run_new_update(fe, stream); ret = dpcm_run_update_startup(fe, stream);
else 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_clear_pending_state(fe, stream);
dpcm_be_disconnect(fe, stream); dpcm_be_disconnect(fe, stream);
...@@ -3006,141 +3100,3 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, ...@@ -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)); return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
} }
EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment