printk(KERN_WARNING
"ASoC: Failed to create codec register debugfs file\n");
- codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
+ codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
codec->debugfs_codec_root,
&codec->pop_time);
if (!codec->debugfs_pop_time)
debugfs_remove_recursive(codec->debugfs_codec_root);
}
+static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ ssize_t len, ret = 0;
+ struct snd_soc_codec *codec;
+
+ if (!buf)
+ return -ENOMEM;
+
+ list_for_each_entry(codec, &codec_list, list) {
+ len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
+ codec->name);
+ if (len >= 0)
+ ret += len;
+ if (ret > PAGE_SIZE) {
+ ret = PAGE_SIZE;
+ break;
+ }
+ }
+
+ if (ret >= 0)
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations codec_list_fops = {
+ .read = codec_list_read_file,
+ .llseek = default_llseek,/* read accesses f_pos */
+};
+
+static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ ssize_t len, ret = 0;
+ struct snd_soc_dai *dai;
+
+ if (!buf)
+ return -ENOMEM;
+
+ list_for_each_entry(dai, &dai_list, list) {
+ len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name);
+ if (len >= 0)
+ ret += len;
+ if (ret > PAGE_SIZE) {
+ ret = PAGE_SIZE;
+ break;
+ }
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations dai_list_fops = {
+ .read = dai_list_read_file,
+ .llseek = default_llseek,/* read accesses f_pos */
+};
+
+static ssize_t platform_list_read_file(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ ssize_t len, ret = 0;
+ struct snd_soc_platform *platform;
+
+ if (!buf)
+ return -ENOMEM;
+
+ list_for_each_entry(platform, &platform_list, list) {
+ len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
+ platform->name);
+ if (len >= 0)
+ ret += len;
+ if (ret > PAGE_SIZE) {
+ ret = PAGE_SIZE;
+ break;
+ }
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations platform_list_fops = {
+ .read = platform_list_read_file,
+ .llseek = default_llseek,/* read accesses f_pos */
+};
+
#else
static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
snd_soc_dapm_sync(codec);
/* register the rtd device */
- rtd->dev.init_name = rtd->dai_link->stream_name;
rtd->dev.release = rtd_release;
rtd->dev.init_name = dai_link->name;
ret = device_register(&rtd->dev);
* for the generic AC97 subsystem.
*/
if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) {
+ /*
+ * It is possible that the AC97 device is already registered to
+ * the device subsystem. This happens when the device is created
+ * via snd_ac97_mixer(). Currently only SoC codec that does so
+ * is the generic AC97 glue but others migh emerge.
+ *
+ * In those cases we don't try to register the device again.
+ */
+ if (!rtd->codec->ac97_created)
+ return 0;
ret = soc_ac97_dev_register(rtd->codec);
if (ret < 0) {
for (i = 0; i < card->num_links; i++) {
ret = soc_probe_dai_link(card, i);
if (ret < 0) {
- printk(KERN_ERR "asoc: failed to instanciate card %s\n", card->name);
+ pr_err("asoc: failed to instantiate card %s: %d\n",
+ card->name, ret);
goto probe_dai_err;
}
}
codec->ac97->bus->ops = ops;
codec->ac97->num = num;
+
+ /*
+ * Mark the AC97 device to be created by us. This way we ensure that the
+ * device will be registered with the device subsystem later on.
+ */
+ codec->ac97_created = 1;
+
mutex_unlock(&codec->mutex);
return 0;
}
kfree(codec->ac97->bus);
kfree(codec->ac97);
codec->ac97 = NULL;
+ codec->ac97_created = 0;
mutex_unlock(&codec->mutex);
}
EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
const struct snd_kcontrol_new *control = &controls[i];
err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL));
if (err < 0) {
- dev_err(codec->dev, "%s: Failed to add %s\n",
- codec->name, control->name);
+ dev_err(codec->dev, "%s: Failed to add %s: %d\n",
+ codec->name, control->name, err);
return err;
}
}
fixup_codec_formats(&dai_drv[i].capture);
}
- /* register DAIs */
- ret = snd_soc_register_dais(dev, dai_drv, num_dai);
- if (ret < 0)
+ /* register any DAIs */
+ if (num_dai) {
+ ret = snd_soc_register_dais(dev, dai_drv, num_dai);
+ if (ret < 0)
goto error;
+ }
mutex_lock(&client_mutex);
list_add(&codec->list, &codec_list);
return;
found:
- for (i = 0; i < codec->num_dai; i++)
- snd_soc_unregister_dai(dev);
+ if (codec->num_dai)
+ for (i = 0; i < codec->num_dai; i++)
+ snd_soc_unregister_dai(dev);
mutex_lock(&client_mutex);
list_del(&codec->list);
"ASoC: Failed to create debugfs directory\n");
debugfs_root = NULL;
}
+
+ if (!debugfs_create_file("codecs", 0444, debugfs_root, NULL,
+ &codec_list_fops))
+ pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
+
+ if (!debugfs_create_file("dais", 0444, debugfs_root, NULL,
+ &dai_list_fops))
+ pr_warn("ASoC: Failed to create DAI list debugfs file\n");
+
+ if (!debugfs_create_file("platforms", 0444, debugfs_root, NULL,
+ &platform_list_fops))
+ pr_warn("ASoC: Failed to create platform list debugfs file\n");
#endif
return platform_driver_register(&soc_driver);
}
+module_init(snd_soc_init);
static void __exit snd_soc_exit(void)
{
#endif
platform_driver_unregister(&soc_driver);
}
-
-module_init(snd_soc_init);
module_exit(snd_soc_exit);
/* Module information */