diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/soc-core.c | 334 |
1 files changed, 167 insertions, 167 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 6e24654194ee..d81a16187769 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -80,6 +80,173 @@ static int run_delayed_work(struct delayed_work *dwork) | |||
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
83 | /* codec register dump */ | ||
84 | static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) | ||
85 | { | ||
86 | int i, step = 1, count = 0; | ||
87 | |||
88 | if (!codec->reg_cache_size) | ||
89 | return 0; | ||
90 | |||
91 | if (codec->reg_cache_step) | ||
92 | step = codec->reg_cache_step; | ||
93 | |||
94 | count += sprintf(buf, "%s registers\n", codec->name); | ||
95 | for (i = 0; i < codec->reg_cache_size; i += step) { | ||
96 | if (codec->readable_register && !codec->readable_register(i)) | ||
97 | continue; | ||
98 | |||
99 | count += sprintf(buf + count, "%2x: ", i); | ||
100 | if (count >= PAGE_SIZE - 1) | ||
101 | break; | ||
102 | |||
103 | if (codec->display_register) | ||
104 | count += codec->display_register(codec, buf + count, | ||
105 | PAGE_SIZE - count, i); | ||
106 | else | ||
107 | count += snprintf(buf + count, PAGE_SIZE - count, | ||
108 | "%4x", codec->read(codec, i)); | ||
109 | |||
110 | if (count >= PAGE_SIZE - 1) | ||
111 | break; | ||
112 | |||
113 | count += snprintf(buf + count, PAGE_SIZE - count, "\n"); | ||
114 | if (count >= PAGE_SIZE - 1) | ||
115 | break; | ||
116 | } | ||
117 | |||
118 | /* Truncate count; min() would cause a warning */ | ||
119 | if (count >= PAGE_SIZE) | ||
120 | count = PAGE_SIZE - 1; | ||
121 | |||
122 | return count; | ||
123 | } | ||
124 | static ssize_t codec_reg_show(struct device *dev, | ||
125 | struct device_attribute *attr, char *buf) | ||
126 | { | ||
127 | struct snd_soc_device *devdata = dev_get_drvdata(dev); | ||
128 | return soc_codec_reg_show(devdata->card->codec, buf); | ||
129 | } | ||
130 | |||
131 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); | ||
132 | |||
133 | #ifdef CONFIG_DEBUG_FS | ||
134 | static int codec_reg_open_file(struct inode *inode, struct file *file) | ||
135 | { | ||
136 | file->private_data = inode->i_private; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, | ||
141 | size_t count, loff_t *ppos) | ||
142 | { | ||
143 | ssize_t ret; | ||
144 | struct snd_soc_codec *codec = file->private_data; | ||
145 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
146 | if (!buf) | ||
147 | return -ENOMEM; | ||
148 | ret = soc_codec_reg_show(codec, buf); | ||
149 | if (ret >= 0) | ||
150 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | ||
151 | kfree(buf); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | static ssize_t codec_reg_write_file(struct file *file, | ||
156 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
157 | { | ||
158 | char buf[32]; | ||
159 | int buf_size; | ||
160 | char *start = buf; | ||
161 | unsigned long reg, value; | ||
162 | int step = 1; | ||
163 | struct snd_soc_codec *codec = file->private_data; | ||
164 | |||
165 | buf_size = min(count, (sizeof(buf)-1)); | ||
166 | if (copy_from_user(buf, user_buf, buf_size)) | ||
167 | return -EFAULT; | ||
168 | buf[buf_size] = 0; | ||
169 | |||
170 | if (codec->reg_cache_step) | ||
171 | step = codec->reg_cache_step; | ||
172 | |||
173 | while (*start == ' ') | ||
174 | start++; | ||
175 | reg = simple_strtoul(start, &start, 16); | ||
176 | if ((reg >= codec->reg_cache_size) || (reg % step)) | ||
177 | return -EINVAL; | ||
178 | while (*start == ' ') | ||
179 | start++; | ||
180 | if (strict_strtoul(start, 16, &value)) | ||
181 | return -EINVAL; | ||
182 | codec->write(codec, reg, value); | ||
183 | return buf_size; | ||
184 | } | ||
185 | |||
186 | static const struct file_operations codec_reg_fops = { | ||
187 | .open = codec_reg_open_file, | ||
188 | .read = codec_reg_read_file, | ||
189 | .write = codec_reg_write_file, | ||
190 | }; | ||
191 | |||
192 | static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | ||
193 | { | ||
194 | char codec_root[128]; | ||
195 | |||
196 | if (codec->dev) | ||
197 | snprintf(codec_root, sizeof(codec_root), | ||
198 | "%s.%s", codec->name, dev_name(codec->dev)); | ||
199 | else | ||
200 | snprintf(codec_root, sizeof(codec_root), | ||
201 | "%s", codec->name); | ||
202 | |||
203 | codec->debugfs_codec_root = debugfs_create_dir(codec_root, | ||
204 | debugfs_root); | ||
205 | if (!codec->debugfs_codec_root) { | ||
206 | printk(KERN_WARNING | ||
207 | "ASoC: Failed to create codec debugfs directory\n"); | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, | ||
212 | codec->debugfs_codec_root, | ||
213 | codec, &codec_reg_fops); | ||
214 | if (!codec->debugfs_reg) | ||
215 | printk(KERN_WARNING | ||
216 | "ASoC: Failed to create codec register debugfs file\n"); | ||
217 | |||
218 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744, | ||
219 | codec->debugfs_codec_root, | ||
220 | &codec->pop_time); | ||
221 | if (!codec->debugfs_pop_time) | ||
222 | printk(KERN_WARNING | ||
223 | "Failed to create pop time debugfs file\n"); | ||
224 | |||
225 | codec->debugfs_dapm = debugfs_create_dir("dapm", | ||
226 | codec->debugfs_codec_root); | ||
227 | if (!codec->debugfs_dapm) | ||
228 | printk(KERN_WARNING | ||
229 | "Failed to create DAPM debugfs directory\n"); | ||
230 | |||
231 | snd_soc_dapm_debugfs_init(codec); | ||
232 | } | ||
233 | |||
234 | static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | ||
235 | { | ||
236 | debugfs_remove_recursive(codec->debugfs_codec_root); | ||
237 | } | ||
238 | |||
239 | #else | ||
240 | |||
241 | static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | ||
246 | { | ||
247 | } | ||
248 | #endif | ||
249 | |||
83 | #ifdef CONFIG_SND_SOC_AC97_BUS | 250 | #ifdef CONFIG_SND_SOC_AC97_BUS |
84 | /* unregister ac97 codec */ | 251 | /* unregister ac97 codec */ |
85 | static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) | 252 | static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) |
@@ -1111,173 +1278,6 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg) | |||
1111 | } | 1278 | } |
1112 | EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); | 1279 | EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); |
1113 | 1280 | ||
1114 | /* codec register dump */ | ||
1115 | static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) | ||
1116 | { | ||
1117 | int i, step = 1, count = 0; | ||
1118 | |||
1119 | if (!codec->reg_cache_size) | ||
1120 | return 0; | ||
1121 | |||
1122 | if (codec->reg_cache_step) | ||
1123 | step = codec->reg_cache_step; | ||
1124 | |||
1125 | count += sprintf(buf, "%s registers\n", codec->name); | ||
1126 | for (i = 0; i < codec->reg_cache_size; i += step) { | ||
1127 | if (codec->readable_register && !codec->readable_register(i)) | ||
1128 | continue; | ||
1129 | |||
1130 | count += sprintf(buf + count, "%2x: ", i); | ||
1131 | if (count >= PAGE_SIZE - 1) | ||
1132 | break; | ||
1133 | |||
1134 | if (codec->display_register) | ||
1135 | count += codec->display_register(codec, buf + count, | ||
1136 | PAGE_SIZE - count, i); | ||
1137 | else | ||
1138 | count += snprintf(buf + count, PAGE_SIZE - count, | ||
1139 | "%4x", codec->read(codec, i)); | ||
1140 | |||
1141 | if (count >= PAGE_SIZE - 1) | ||
1142 | break; | ||
1143 | |||
1144 | count += snprintf(buf + count, PAGE_SIZE - count, "\n"); | ||
1145 | if (count >= PAGE_SIZE - 1) | ||
1146 | break; | ||
1147 | } | ||
1148 | |||
1149 | /* Truncate count; min() would cause a warning */ | ||
1150 | if (count >= PAGE_SIZE) | ||
1151 | count = PAGE_SIZE - 1; | ||
1152 | |||
1153 | return count; | ||
1154 | } | ||
1155 | static ssize_t codec_reg_show(struct device *dev, | ||
1156 | struct device_attribute *attr, char *buf) | ||
1157 | { | ||
1158 | struct snd_soc_device *devdata = dev_get_drvdata(dev); | ||
1159 | return soc_codec_reg_show(devdata->card->codec, buf); | ||
1160 | } | ||
1161 | |||
1162 | static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); | ||
1163 | |||
1164 | #ifdef CONFIG_DEBUG_FS | ||
1165 | static int codec_reg_open_file(struct inode *inode, struct file *file) | ||
1166 | { | ||
1167 | file->private_data = inode->i_private; | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, | ||
1172 | size_t count, loff_t *ppos) | ||
1173 | { | ||
1174 | ssize_t ret; | ||
1175 | struct snd_soc_codec *codec = file->private_data; | ||
1176 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1177 | if (!buf) | ||
1178 | return -ENOMEM; | ||
1179 | ret = soc_codec_reg_show(codec, buf); | ||
1180 | if (ret >= 0) | ||
1181 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | ||
1182 | kfree(buf); | ||
1183 | return ret; | ||
1184 | } | ||
1185 | |||
1186 | static ssize_t codec_reg_write_file(struct file *file, | ||
1187 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
1188 | { | ||
1189 | char buf[32]; | ||
1190 | int buf_size; | ||
1191 | char *start = buf; | ||
1192 | unsigned long reg, value; | ||
1193 | int step = 1; | ||
1194 | struct snd_soc_codec *codec = file->private_data; | ||
1195 | |||
1196 | buf_size = min(count, (sizeof(buf)-1)); | ||
1197 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1198 | return -EFAULT; | ||
1199 | buf[buf_size] = 0; | ||
1200 | |||
1201 | if (codec->reg_cache_step) | ||
1202 | step = codec->reg_cache_step; | ||
1203 | |||
1204 | while (*start == ' ') | ||
1205 | start++; | ||
1206 | reg = simple_strtoul(start, &start, 16); | ||
1207 | if ((reg >= codec->reg_cache_size) || (reg % step)) | ||
1208 | return -EINVAL; | ||
1209 | while (*start == ' ') | ||
1210 | start++; | ||
1211 | if (strict_strtoul(start, 16, &value)) | ||
1212 | return -EINVAL; | ||
1213 | codec->write(codec, reg, value); | ||
1214 | return buf_size; | ||
1215 | } | ||
1216 | |||
1217 | static const struct file_operations codec_reg_fops = { | ||
1218 | .open = codec_reg_open_file, | ||
1219 | .read = codec_reg_read_file, | ||
1220 | .write = codec_reg_write_file, | ||
1221 | }; | ||
1222 | |||
1223 | static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | ||
1224 | { | ||
1225 | char codec_root[128]; | ||
1226 | |||
1227 | if (codec->dev) | ||
1228 | snprintf(codec_root, sizeof(codec_root), | ||
1229 | "%s.%s", codec->name, dev_name(codec->dev)); | ||
1230 | else | ||
1231 | snprintf(codec_root, sizeof(codec_root), | ||
1232 | "%s", codec->name); | ||
1233 | |||
1234 | codec->debugfs_codec_root = debugfs_create_dir(codec_root, | ||
1235 | debugfs_root); | ||
1236 | if (!codec->debugfs_codec_root) { | ||
1237 | printk(KERN_WARNING | ||
1238 | "ASoC: Failed to create codec debugfs directory\n"); | ||
1239 | return; | ||
1240 | } | ||
1241 | |||
1242 | codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, | ||
1243 | codec->debugfs_codec_root, | ||
1244 | codec, &codec_reg_fops); | ||
1245 | if (!codec->debugfs_reg) | ||
1246 | printk(KERN_WARNING | ||
1247 | "ASoC: Failed to create codec register debugfs file\n"); | ||
1248 | |||
1249 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744, | ||
1250 | codec->debugfs_codec_root, | ||
1251 | &codec->pop_time); | ||
1252 | if (!codec->debugfs_pop_time) | ||
1253 | printk(KERN_WARNING | ||
1254 | "Failed to create pop time debugfs file\n"); | ||
1255 | |||
1256 | codec->debugfs_dapm = debugfs_create_dir("dapm", | ||
1257 | codec->debugfs_codec_root); | ||
1258 | if (!codec->debugfs_dapm) | ||
1259 | printk(KERN_WARNING | ||
1260 | "Failed to create DAPM debugfs directory\n"); | ||
1261 | |||
1262 | snd_soc_dapm_debugfs_init(codec); | ||
1263 | } | ||
1264 | |||
1265 | static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | ||
1266 | { | ||
1267 | debugfs_remove_recursive(codec->debugfs_codec_root); | ||
1268 | } | ||
1269 | |||
1270 | #else | ||
1271 | |||
1272 | static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) | ||
1273 | { | ||
1274 | } | ||
1275 | |||
1276 | static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | ||
1277 | { | ||
1278 | } | ||
1279 | #endif | ||
1280 | |||
1281 | /** | 1281 | /** |
1282 | * snd_soc_new_ac97_codec - initailise AC97 device | 1282 | * snd_soc_new_ac97_codec - initailise AC97 device |
1283 | * @codec: audio codec | 1283 | * @codec: audio codec |