diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2008-10-13 20:42:14 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2008-10-30 10:34:02 -0400 |
commit | 12ef193d5817504621e503e78d641265f6a86ac4 (patch) | |
tree | a86c1cc9d7297561b0912f0b2c0332bf2ab993ca /sound/soc/soc-core.c | |
parent | 15ad9a531a64d46af54839ab13542a81ad4c82a5 (diff) |
ASoC: Allow setting codec register with debugfs filesystem
i.e. echo 6 59 >/sys/kernel/debug/soc-audio.0/codec_reg
will set register 0x06 to a value of 0x59.
Also, pop_time debugfs interface setup is moved so that it
is setup in the same function as codec_reg
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r-- | sound/soc/soc-core.c | 116 |
1 files changed, 113 insertions, 3 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 462e635dfc74..4707042b3dad 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 */ |
964 | static ssize_t codec_reg_show(struct device *dev, | 965 | static 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 | } |
1003 | static 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 | |||
1004 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); | 1010 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); |
1005 | 1011 | ||
1012 | #ifdef CONFIG_DEBUG_FS | ||
1013 | static int codec_reg_open_file(struct inode *inode, struct file *file) | ||
1014 | { | ||
1015 | file->private_data = inode->i_private; | ||
1016 | return 0; | ||
1017 | } | ||
1018 | |||
1019 | static 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 | |||
1034 | static 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 | |||
1066 | static 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 | |||
1072 | static 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; | ||
1091 | exit2: | ||
1092 | debugfs_remove_recursive(root); | ||
1093 | exit1: | ||
1094 | dev_err(socdev->dev, "debugfs is not available\n"); | ||
1095 | } | ||
1096 | |||
1097 | static 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 | |||
1105 | static inline void soc_init_debugfs(struct snd_soc_device *socdev) | ||
1106 | { | ||
1107 | } | ||
1108 | |||
1109 | static 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 | ||
1221 | out: | 1330 | out: |
@@ -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]; |