aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-21 11:38:13 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-21 12:17:59 -0400
commit79fb9387f88b6b44bbc46e19cae26d2c9fe3bb6a (patch)
treee291bf379268358a1a5a6d9e32a33cabedf6d0d2
parentb8e583f6012d618fb93bb38a302b63c3c6d2bfbc (diff)
ASoC: Add DAPM widget power decision debugfs files
Currently when built with DEBUG DAPM will dump information about the power state decisions it is taking for each widget to dmesg. This isn't an ideal way of getting the information - it requires a kernel build to turn it on and off and for large hub CODECs the volume of information is so large as to be illegible. When the output goes to the console it can also cause a noticable impact on performance simply to print it out. Improve the situation by adding a dapm directory to our debugfs tree containing a file per widget with the same information in it. This still requires a decision to build with debugfs support but is easier to navigate and much less intrusive. In addition to the previously displayed information active streams are also shown in these files. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--include/sound/soc.h1
-rw-r--r--sound/soc/soc-core.c8
-rw-r--r--sound/soc/soc-dapm.c86
4 files changed, 96 insertions, 0 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 35814ced2d22..1673f0b2cf58 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -283,6 +283,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
283 283
284/* dapm sys fs - used by the core */ 284/* dapm sys fs - used by the core */
285int snd_soc_dapm_sys_add(struct device *dev); 285int snd_soc_dapm_sys_add(struct device *dev);
286void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
286 287
287/* dapm audio pin control and status */ 288/* dapm audio pin control and status */
288int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); 289int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index dbb1702688cd..0758a1b3ca44 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -416,6 +416,7 @@ struct snd_soc_codec {
416#ifdef CONFIG_DEBUG_FS 416#ifdef CONFIG_DEBUG_FS
417 struct dentry *debugfs_reg; 417 struct dentry *debugfs_reg;
418 struct dentry *debugfs_pop_time; 418 struct dentry *debugfs_pop_time;
419 struct dentry *debugfs_dapm;
419#endif 420#endif
420}; 421};
421 422
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index e984a17cd656..7ff04ad2a97e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1267,10 +1267,18 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1267 if (!codec->debugfs_pop_time) 1267 if (!codec->debugfs_pop_time)
1268 printk(KERN_WARNING 1268 printk(KERN_WARNING
1269 "Failed to create pop time debugfs file\n"); 1269 "Failed to create pop time debugfs file\n");
1270
1271 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1272 if (!codec->debugfs_dapm)
1273 printk(KERN_WARNING
1274 "Failed to create DAPM debugfs directory\n");
1275
1276 snd_soc_dapm_debugfs_init(codec);
1270} 1277}
1271 1278
1272static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 1279static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1273{ 1280{
1281 debugfs_remove_recursive(codec->debugfs_dapm);
1274 debugfs_remove(codec->debugfs_pop_time); 1282 debugfs_remove(codec->debugfs_pop_time);
1275 debugfs_remove(codec->debugfs_reg); 1283 debugfs_remove(codec->debugfs_reg);
1276} 1284}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 5cfc90941e49..2f5295dbd158 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1081,6 +1081,92 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
1081} 1081}
1082#endif 1082#endif
1083 1083
1084#ifdef CONFIG_DEBUG_FS
1085static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1086{
1087 file->private_data = inode->i_private;
1088 return 0;
1089}
1090
1091static ssize_t dapm_widget_power_read_file(struct file *file,
1092 char __user *user_buf,
1093 size_t count, loff_t *ppos)
1094{
1095 struct snd_soc_dapm_widget *w = file->private_data;
1096 char *buf;
1097 int in, out;
1098 ssize_t ret;
1099 struct snd_soc_dapm_path *p = NULL;
1100
1101 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1102 if (!buf)
1103 return -ENOMEM;
1104
1105 in = is_connected_input_ep(w);
1106 dapm_clear_walk(w->codec);
1107 out = is_connected_output_ep(w);
1108 dapm_clear_walk(w->codec);
1109
1110 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n",
1111 w->name, w->power ? "On" : "Off", in, out);
1112
1113 if (w->active && w->sname)
1114 ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n",
1115 w->sname);
1116
1117 list_for_each_entry(p, &w->sources, list_sink) {
1118 if (p->connect)
1119 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1120 " in %s %s\n",
1121 p->name ? p->name : "static",
1122 p->source->name);
1123 }
1124 list_for_each_entry(p, &w->sinks, list_source) {
1125 if (p->connect)
1126 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1127 " out %s %s\n",
1128 p->name ? p->name : "static",
1129 p->sink->name);
1130 }
1131
1132 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1133
1134 kfree(buf);
1135 return ret;
1136}
1137
1138static const struct file_operations dapm_widget_power_fops = {
1139 .open = dapm_widget_power_open_file,
1140 .read = dapm_widget_power_read_file,
1141};
1142
1143void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1144{
1145 struct snd_soc_dapm_widget *w;
1146 struct dentry *d;
1147
1148 if (!codec->debugfs_dapm)
1149 return;
1150
1151 list_for_each_entry(w, &codec->dapm_widgets, list) {
1152 if (!w->name)
1153 continue;
1154
1155 d = debugfs_create_file(w->name, 0444,
1156 codec->debugfs_dapm, w,
1157 &dapm_widget_power_fops);
1158 if (!d)
1159 printk(KERN_WARNING
1160 "ASoC: Failed to create %s debugfs file\n",
1161 w->name);
1162 }
1163}
1164#else
1165void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1166{
1167}
1168#endif
1169
1084/* test and update the power status of a mux widget */ 1170/* test and update the power status of a mux widget */
1085static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1171static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1086 struct snd_kcontrol *kcontrol, int mask, 1172 struct snd_kcontrol *kcontrol, int mask,