Loading include/sound/soc-dpcm.h +4 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ struct snd_soc_dpcm { /* hw params for this link - may be different for each link */ struct snd_pcm_hw_params hw_params; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_state; #endif }; /* Loading Loading @@ -128,5 +131,6 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream, /* internal use only */ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); #endif include/sound/soc.h +4 −0 Original line number Diff line number Diff line Loading @@ -957,6 +957,10 @@ struct snd_soc_pcm_runtime { struct snd_soc_dai *cpu_dai; struct delayed_work delayed_work; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dpcm_root; struct dentry *debugfs_dpcm_state; #endif }; /* mixer control */ Loading sound/soc/soc-core.c +11 −0 Original line number Diff line number Diff line Loading @@ -1187,6 +1187,17 @@ static int soc_post_component_init(struct snd_soc_card *card, dev_err(codec->dev, "asoc: failed to add codec sysfs files: %d\n", ret); #ifdef CONFIG_DEBUG_FS /* add DPCM sysfs entries */ if (!dai_link->dynamic) goto out; ret = soc_dpcm_debugfs_add(rtd); if (ret < 0) dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret); out: #endif return 0; } Loading sound/soc/soc-pcm.c +152 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/export.h> #include <linux/debugfs.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> Loading Loading @@ -690,6 +691,10 @@ 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 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, fe->debugfs_dpcm_root, &dpcm->state); #endif return 1; } Loading Loading @@ -741,6 +746,9 @@ static 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(dpcm->debugfs_state); #endif list_del(&dpcm->list_be); list_del(&dpcm->list_fe); kfree(dpcm); Loading Loading @@ -1890,3 +1898,147 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, return 1; } EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); #ifdef CONFIG_DEBUG_FS static 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 int dpcm_state_open_file(struct inode *inode, struct file *file) { file->private_data = inode->i_private; return 0; } 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; /* 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; } list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 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)); } 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; char *buf; buf = kmalloc(out_count, GFP_KERNEL); if (!buf) return -ENOMEM; if (fe->cpu_dai->driver->playback.channels_min) offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK, buf + offset, out_count - offset); if (fe->cpu_dai->driver->capture.channels_min) offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE, 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 = dpcm_state_open_file, .read = dpcm_state_read_file, .llseek = default_llseek, }; int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) { rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, rtd->card->debugfs_card_root); if (!rtd->debugfs_dpcm_root) { dev_dbg(rtd->dev, "ASoC: Failed to create dpcm debugfs directory %s\n", rtd->dai_link->name); return -EINVAL; } rtd->debugfs_dpcm_state = debugfs_create_file("state", 0644, rtd->debugfs_dpcm_root, rtd, &dpcm_state_fops); return 0; } #endif Loading
include/sound/soc-dpcm.h +4 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ struct snd_soc_dpcm { /* hw params for this link - may be different for each link */ struct snd_pcm_hw_params hw_params; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_state; #endif }; /* Loading Loading @@ -128,5 +131,6 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream, /* internal use only */ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); #endif
include/sound/soc.h +4 −0 Original line number Diff line number Diff line Loading @@ -957,6 +957,10 @@ struct snd_soc_pcm_runtime { struct snd_soc_dai *cpu_dai; struct delayed_work delayed_work; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dpcm_root; struct dentry *debugfs_dpcm_state; #endif }; /* mixer control */ Loading
sound/soc/soc-core.c +11 −0 Original line number Diff line number Diff line Loading @@ -1187,6 +1187,17 @@ static int soc_post_component_init(struct snd_soc_card *card, dev_err(codec->dev, "asoc: failed to add codec sysfs files: %d\n", ret); #ifdef CONFIG_DEBUG_FS /* add DPCM sysfs entries */ if (!dai_link->dynamic) goto out; ret = soc_dpcm_debugfs_add(rtd); if (ret < 0) dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret); out: #endif return 0; } Loading
sound/soc/soc-pcm.c +152 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/export.h> #include <linux/debugfs.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> Loading Loading @@ -690,6 +691,10 @@ 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 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, fe->debugfs_dpcm_root, &dpcm->state); #endif return 1; } Loading Loading @@ -741,6 +746,9 @@ static 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(dpcm->debugfs_state); #endif list_del(&dpcm->list_be); list_del(&dpcm->list_fe); kfree(dpcm); Loading Loading @@ -1890,3 +1898,147 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, return 1; } EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params); #ifdef CONFIG_DEBUG_FS static 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 int dpcm_state_open_file(struct inode *inode, struct file *file) { file->private_data = inode->i_private; return 0; } 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; /* 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; } list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 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)); } 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; char *buf; buf = kmalloc(out_count, GFP_KERNEL); if (!buf) return -ENOMEM; if (fe->cpu_dai->driver->playback.channels_min) offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK, buf + offset, out_count - offset); if (fe->cpu_dai->driver->capture.channels_min) offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE, 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 = dpcm_state_open_file, .read = dpcm_state_read_file, .llseek = default_llseek, }; int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) { rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, rtd->card->debugfs_card_root); if (!rtd->debugfs_dpcm_root) { dev_dbg(rtd->dev, "ASoC: Failed to create dpcm debugfs directory %s\n", rtd->dai_link->name); return -EINVAL; } rtd->debugfs_dpcm_state = debugfs_create_file("state", 0644, rtd->debugfs_dpcm_root, rtd, &dpcm_state_fops); return 0; } #endif