aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h4
-rw-r--r--sound/soc/soc-core.c116
-rw-r--r--sound/soc/soc-dapm.c33
3 files changed, 125 insertions, 28 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a1e0357a84d..d33825d624a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -425,6 +425,7 @@ struct snd_soc_codec {
425 short reg_cache_step; 425 short reg_cache_step;
426 426
427 /* dapm */ 427 /* dapm */
428 u32 pop_time;
428 struct list_head dapm_widgets; 429 struct list_head dapm_widgets;
429 struct list_head dapm_paths; 430 struct list_head dapm_paths;
430 enum snd_soc_bias_level bias_level; 431 enum snd_soc_bias_level bias_level;
@@ -516,6 +517,9 @@ struct snd_soc_device {
516 struct delayed_work delayed_work; 517 struct delayed_work delayed_work;
517 struct work_struct deferred_resume_work; 518 struct work_struct deferred_resume_work;
518 void *codec_data; 519 void *codec_data;
520#ifdef CONFIG_DEBUG_FS
521 struct dentry *debugfs_root;
522#endif
519}; 523};
520 524
521/* runtime channel data */ 525/* runtime channel data */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 462e635dfc7..4707042b3da 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/pm.h> 27#include <linux/pm.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h>
29#include <linux/platform_device.h> 30#include <linux/platform_device.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -961,10 +962,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
961} 962}
962 963
963/* codec register dump */ 964/* codec register dump */
964static ssize_t codec_reg_show(struct device *dev, 965static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf)
965 struct device_attribute *attr, char *buf)
966{ 966{
967 struct snd_soc_device *devdata = dev_get_drvdata(dev);
968 struct snd_soc_codec *codec = devdata->codec; 967 struct snd_soc_codec *codec = devdata->codec;
969 int i, step = 1, count = 0; 968 int i, step = 1, count = 0;
970 969
@@ -1001,8 +1000,117 @@ static ssize_t codec_reg_show(struct device *dev,
1001 1000
1002 return count; 1001 return count;
1003} 1002}
1003static ssize_t codec_reg_show(struct device *dev,
1004 struct device_attribute *attr, char *buf)
1005{
1006 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1007 return soc_codec_reg_show(devdata, buf);
1008}
1009
1004static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 1010static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1005 1011
1012#ifdef CONFIG_DEBUG_FS
1013static int codec_reg_open_file(struct inode *inode, struct file *file)
1014{
1015 file->private_data = inode->i_private;
1016 return 0;
1017}
1018
1019static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1020 size_t count, loff_t *ppos)
1021{
1022 ssize_t ret;
1023 struct snd_soc_device *devdata = file->private_data;
1024 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1025 if (!buf)
1026 return -ENOMEM;
1027 ret = soc_codec_reg_show(devdata, buf);
1028 if (ret >= 0)
1029 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1030 kfree(buf);
1031 return ret;
1032}
1033
1034static ssize_t codec_reg_write_file(struct file *file,
1035 const char __user *user_buf, size_t count, loff_t *ppos)
1036{
1037 char buf[32];
1038 int buf_size;
1039 char *start = buf;
1040 unsigned long reg, value;
1041 int step = 1;
1042 struct snd_soc_device *devdata = file->private_data;
1043 struct snd_soc_codec *codec = devdata->codec;
1044
1045 buf_size = min(count, (sizeof(buf)-1));
1046 if (copy_from_user(buf, user_buf, buf_size))
1047 return -EFAULT;
1048 buf[buf_size] = 0;
1049
1050 if (codec->reg_cache_step)
1051 step = codec->reg_cache_step;
1052
1053 while (*start == ' ')
1054 start++;
1055 reg = simple_strtoul(start, &start, 16);
1056 if ((reg >= codec->reg_cache_size) || (reg % step))
1057 return -EINVAL;
1058 while (*start == ' ')
1059 start++;
1060 if (strict_strtoul(start, 16, &value))
1061 return -EINVAL;
1062 codec->write(codec, reg, value);
1063 return buf_size;
1064}
1065
1066static const struct file_operations codec_reg_fops = {
1067 .open = codec_reg_open_file,
1068 .read = codec_reg_read_file,
1069 .write = codec_reg_write_file,
1070};
1071
1072static void soc_init_debugfs(struct snd_soc_device *socdev)
1073{
1074 struct dentry *root, *file;
1075 struct snd_soc_codec *codec = socdev->codec;
1076 root = debugfs_create_dir(dev_name(socdev->dev), NULL);
1077 if (IS_ERR(root) || !root)
1078 goto exit1;
1079
1080 file = debugfs_create_file("codec_reg", 0644,
1081 root, socdev, &codec_reg_fops);
1082 if (!file)
1083 goto exit2;
1084
1085 file = debugfs_create_u32("dapm_pop_time", 0744,
1086 root, &codec->pop_time);
1087 if (!file)
1088 goto exit2;
1089 socdev->debugfs_root = root;
1090 return;
1091exit2:
1092 debugfs_remove_recursive(root);
1093exit1:
1094 dev_err(socdev->dev, "debugfs is not available\n");
1095}
1096
1097static void soc_cleanup_debugfs(struct snd_soc_device *socdev)
1098{
1099 debugfs_remove_recursive(socdev->debugfs_root);
1100 socdev->debugfs_root = NULL;
1101}
1102
1103#else
1104
1105static inline void soc_init_debugfs(struct snd_soc_device *socdev)
1106{
1107}
1108
1109static inline void soc_cleanup_debugfs(struct snd_soc_device *socdev)
1110{
1111}
1112#endif
1113
1006/** 1114/**
1007 * snd_soc_new_ac97_codec - initailise AC97 device 1115 * snd_soc_new_ac97_codec - initailise AC97 device
1008 * @codec: audio codec 1116 * @codec: audio codec
@@ -1216,6 +1324,7 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1216 if (err < 0) 1324 if (err < 0)
1217 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1325 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1218 1326
1327 soc_init_debugfs(socdev);
1219 mutex_unlock(&codec->mutex); 1328 mutex_unlock(&codec->mutex);
1220 1329
1221out: 1330out:
@@ -1239,6 +1348,7 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
1239#endif 1348#endif
1240 1349
1241 mutex_lock(&codec->mutex); 1350 mutex_lock(&codec->mutex);
1351 soc_cleanup_debugfs(socdev);
1242#ifdef CONFIG_SND_SOC_AC97_BUS 1352#ifdef CONFIG_SND_SOC_AC97_BUS
1243 for (i = 0; i < codec->num_dai; i++) { 1353 for (i = 0; i < codec->num_dai; i++) {
1244 codec_dai = &codec->dai[i]; 1354 codec_dai = &codec->dai[i];
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7e9f423f5b0..b51d82285be 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -37,7 +37,6 @@
37#include <linux/bitops.h> 37#include <linux/bitops.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/pcm.h> 41#include <sound/pcm.h>
43#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
@@ -67,17 +66,13 @@ static int dapm_status = 1;
67module_param(dapm_status, int, 0); 66module_param(dapm_status, int, 0);
68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 67MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 68
70static struct dentry *asoc_debugfs; 69static void pop_wait(u32 pop_time)
71
72static u32 pop_time;
73
74static void pop_wait(void)
75{ 70{
76 if (pop_time) 71 if (pop_time)
77 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 72 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
78} 73}
79 74
80static void pop_dbg(const char *fmt, ...) 75static void pop_dbg(u32 pop_time, const char *fmt, ...)
81{ 76{
82 va_list args; 77 va_list args;
83 78
@@ -85,7 +80,7 @@ static void pop_dbg(const char *fmt, ...)
85 80
86 if (pop_time) { 81 if (pop_time) {
87 vprintk(fmt, args); 82 vprintk(fmt, args);
88 pop_wait(); 83 pop_wait(pop_time);
89 } 84 }
90 85
91 va_end(args); 86 va_end(args);
@@ -230,10 +225,11 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
230 225
231 change = old != new; 226 change = old != new;
232 if (change) { 227 if (change) {
233 pop_dbg("pop test %s : %s in %d ms\n", widget->name, 228 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
234 widget->power ? "on" : "off", pop_time); 229 widget->name, widget->power ? "on" : "off",
230 codec->pop_time);
235 snd_soc_write(codec, widget->reg, new); 231 snd_soc_write(codec, widget->reg, new);
236 pop_wait(); 232 pop_wait(codec->pop_time);
237 } 233 }
238 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 234 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
239 old, new, change); 235 old, new, change);
@@ -821,23 +817,13 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
821 817
822int snd_soc_dapm_sys_add(struct device *dev) 818int snd_soc_dapm_sys_add(struct device *dev)
823{ 819{
824 int ret = 0;
825
826 if (!dapm_status) 820 if (!dapm_status)
827 return 0; 821 return 0;
828 822
829 ret = device_create_file(dev, &dev_attr_dapm_widget); 823 ret = device_create_file(dev, &dev_attr_dapm_widget);
830 if (ret != 0) 824 if (ret != 0)
831 return ret; 825 return ret;
832 826 return device_create_file(dev, &dev_attr_dapm_widget);
833 asoc_debugfs = debugfs_create_dir("asoc", NULL);
834 if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
835 debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
836 &pop_time);
837 else
838 asoc_debugfs = NULL;
839
840 return 0;
841} 827}
842 828
843static void snd_soc_dapm_sys_remove(struct device *dev) 829static void snd_soc_dapm_sys_remove(struct device *dev)
@@ -845,9 +831,6 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
845 if (dapm_status) { 831 if (dapm_status) {
846 device_remove_file(dev, &dev_attr_dapm_widget); 832 device_remove_file(dev, &dev_attr_dapm_widget);
847 } 833 }
848
849 if (asoc_debugfs)
850 debugfs_remove_recursive(asoc_debugfs);
851} 834}
852 835
853/* free all dapm widgets and resources */ 836/* free all dapm widgets and resources */