aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-24 06:24:01 -0400
committerMark Brown <broonie@linaro.org>2013-10-24 06:24:01 -0400
commit618056167059afdf43a36aa9db40e51a6482797d (patch)
tree27c0b8a317db32e4c5e44edccf888cc7e7dc6654
parentd1c59c87128722d159db1d83bd2b8f2d8a89915f (diff)
parentcb470087669a3fab1958fec79dd7db280b33f178 (diff)
Merge remote-tracking branch 'asoc/topic/component' into asoc-next
-rw-r--r--include/sound/soc.h41
-rw-r--r--sound/soc/soc-core.c237
2 files changed, 174 insertions, 104 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index d22cb0a06feb..1dd7dc5f7d52 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -13,6 +13,7 @@
13#ifndef __LINUX_SND_SOC_H 13#ifndef __LINUX_SND_SOC_H
14#define __LINUX_SND_SOC_H 14#define __LINUX_SND_SOC_H
15 15
16#include <linux/of.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/notifier.h> 19#include <linux/notifier.h>
@@ -670,6 +671,26 @@ struct snd_soc_cache_ops {
670 int (*sync)(struct snd_soc_codec *codec); 671 int (*sync)(struct snd_soc_codec *codec);
671}; 672};
672 673
674/* component interface */
675struct snd_soc_component_driver {
676 const char *name;
677
678 /* DT */
679 int (*of_xlate_dai_name)(struct snd_soc_component *component,
680 struct of_phandle_args *args,
681 const char **dai_name);
682};
683
684struct snd_soc_component {
685 const char *name;
686 int id;
687 int num_dai;
688 struct device *dev;
689 struct list_head list;
690
691 const struct snd_soc_component_driver *driver;
692};
693
673/* SoC Audio Codec device */ 694/* SoC Audio Codec device */
674struct snd_soc_codec { 695struct snd_soc_codec {
675 const char *name; 696 const char *name;
@@ -715,6 +736,9 @@ struct snd_soc_codec {
715 struct mutex cache_rw_mutex; 736 struct mutex cache_rw_mutex;
716 int val_bytes; 737 int val_bytes;
717 738
739 /* component */
740 struct snd_soc_component component;
741
718 /* dapm */ 742 /* dapm */
719 struct snd_soc_dapm_context dapm; 743 struct snd_soc_dapm_context dapm;
720 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ 744 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
@@ -733,6 +757,7 @@ struct snd_soc_codec_driver {
733 int (*remove)(struct snd_soc_codec *); 757 int (*remove)(struct snd_soc_codec *);
734 int (*suspend)(struct snd_soc_codec *); 758 int (*suspend)(struct snd_soc_codec *);
735 int (*resume)(struct snd_soc_codec *); 759 int (*resume)(struct snd_soc_codec *);
760 struct snd_soc_component_driver component_driver;
736 761
737 /* Default control and setup, added after probe() is run */ 762 /* Default control and setup, added after probe() is run */
738 const struct snd_kcontrol_new *controls; 763 const struct snd_kcontrol_new *controls;
@@ -849,20 +874,6 @@ struct snd_soc_platform {
849#endif 874#endif
850}; 875};
851 876
852struct snd_soc_component_driver {
853 const char *name;
854};
855
856struct snd_soc_component {
857 const char *name;
858 int id;
859 int num_dai;
860 struct device *dev;
861 struct list_head list;
862
863 const struct snd_soc_component_driver *driver;
864};
865
866struct snd_soc_dai_link { 877struct snd_soc_dai_link {
867 /* config - must be set by machine driver */ 878 /* config - must be set by machine driver */
868 const char *name; /* Codec name */ 879 const char *name; /* Codec name */
@@ -1201,6 +1212,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
1201 const char *propname); 1212 const char *propname);
1202unsigned int snd_soc_of_parse_daifmt(struct device_node *np, 1213unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
1203 const char *prefix); 1214 const char *prefix);
1215int snd_soc_of_get_dai_name(struct device_node *of_node,
1216 const char **dai_name);
1204 1217
1205#include <sound/soc-dai.h> 1218#include <sound/soc-dai.h>
1206 1219
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 09e47c1434a7..b1c472fde84b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4036,6 +4036,112 @@ static void snd_soc_unregister_dais(struct device *dev, size_t count)
4036} 4036}
4037 4037
4038/** 4038/**
4039 * snd_soc_register_component - Register a component with the ASoC core
4040 *
4041 */
4042static int
4043__snd_soc_register_component(struct device *dev,
4044 struct snd_soc_component *cmpnt,
4045 const struct snd_soc_component_driver *cmpnt_drv,
4046 struct snd_soc_dai_driver *dai_drv,
4047 int num_dai, bool allow_single_dai)
4048{
4049 int ret;
4050
4051 dev_dbg(dev, "component register %s\n", dev_name(dev));
4052
4053 if (!cmpnt) {
4054 dev_err(dev, "ASoC: Failed to connecting component\n");
4055 return -ENOMEM;
4056 }
4057
4058 cmpnt->name = fmt_single_name(dev, &cmpnt->id);
4059 if (!cmpnt->name) {
4060 dev_err(dev, "ASoC: Failed to simplifying name\n");
4061 return -ENOMEM;
4062 }
4063
4064 cmpnt->dev = dev;
4065 cmpnt->driver = cmpnt_drv;
4066 cmpnt->num_dai = num_dai;
4067
4068 /*
4069 * snd_soc_register_dai() uses fmt_single_name(), and
4070 * snd_soc_register_dais() uses fmt_multiple_name()
4071 * for dai->name which is used for name based matching
4072 *
4073 * this function is used from cpu/codec.
4074 * allow_single_dai flag can ignore "codec" driver reworking
4075 * since it had been used snd_soc_register_dais(),
4076 */
4077 if ((1 == num_dai) && allow_single_dai)
4078 ret = snd_soc_register_dai(dev, dai_drv);
4079 else
4080 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4081 if (ret < 0) {
4082 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4083 goto error_component_name;
4084 }
4085
4086 mutex_lock(&client_mutex);
4087 list_add(&cmpnt->list, &component_list);
4088 mutex_unlock(&client_mutex);
4089
4090 dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
4091
4092 return ret;
4093
4094error_component_name:
4095 kfree(cmpnt->name);
4096
4097 return ret;
4098}
4099
4100int snd_soc_register_component(struct device *dev,
4101 const struct snd_soc_component_driver *cmpnt_drv,
4102 struct snd_soc_dai_driver *dai_drv,
4103 int num_dai)
4104{
4105 struct snd_soc_component *cmpnt;
4106
4107 cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
4108 if (!cmpnt) {
4109 dev_err(dev, "ASoC: Failed to allocate memory\n");
4110 return -ENOMEM;
4111 }
4112
4113 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv,
4114 dai_drv, num_dai, true);
4115}
4116EXPORT_SYMBOL_GPL(snd_soc_register_component);
4117
4118/**
4119 * snd_soc_unregister_component - Unregister a component from the ASoC core
4120 *
4121 */
4122void snd_soc_unregister_component(struct device *dev)
4123{
4124 struct snd_soc_component *cmpnt;
4125
4126 list_for_each_entry(cmpnt, &component_list, list) {
4127 if (dev == cmpnt->dev)
4128 goto found;
4129 }
4130 return;
4131
4132found:
4133 snd_soc_unregister_dais(dev, cmpnt->num_dai);
4134
4135 mutex_lock(&client_mutex);
4136 list_del(&cmpnt->list);
4137 mutex_unlock(&client_mutex);
4138
4139 dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
4140 kfree(cmpnt->name);
4141}
4142EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4143
4144/**
4039 * snd_soc_add_platform - Add a platform to the ASoC core 4145 * snd_soc_add_platform - Add a platform to the ASoC core
4040 * @dev: The parent device for the platform 4146 * @dev: The parent device for the platform
4041 * @platform: The platform to add 4147 * @platform: The platform to add
@@ -4257,10 +4363,12 @@ int snd_soc_register_codec(struct device *dev,
4257 list_add(&codec->list, &codec_list); 4363 list_add(&codec->list, &codec_list);
4258 mutex_unlock(&client_mutex); 4364 mutex_unlock(&client_mutex);
4259 4365
4260 /* register any DAIs */ 4366 /* register component */
4261 ret = snd_soc_register_dais(dev, dai_drv, num_dai); 4367 ret = __snd_soc_register_component(dev, &codec->component,
4368 &codec_drv->component_driver,
4369 dai_drv, num_dai, false);
4262 if (ret < 0) { 4370 if (ret < 0) {
4263 dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret); 4371 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
4264 goto fail_codec_name; 4372 goto fail_codec_name;
4265 } 4373 }
4266 4374
@@ -4295,7 +4403,7 @@ void snd_soc_unregister_codec(struct device *dev)
4295 return; 4403 return;
4296 4404
4297found: 4405found:
4298 snd_soc_unregister_dais(dev, codec->num_dai); 4406 snd_soc_unregister_component(dev);
4299 4407
4300 mutex_lock(&client_mutex); 4408 mutex_lock(&client_mutex);
4301 list_del(&codec->list); 4409 list_del(&codec->list);
@@ -4310,92 +4418,6 @@ found:
4310} 4418}
4311EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); 4419EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
4312 4420
4313
4314/**
4315 * snd_soc_register_component - Register a component with the ASoC core
4316 *
4317 */
4318int snd_soc_register_component(struct device *dev,
4319 const struct snd_soc_component_driver *cmpnt_drv,
4320 struct snd_soc_dai_driver *dai_drv,
4321 int num_dai)
4322{
4323 struct snd_soc_component *cmpnt;
4324 int ret;
4325
4326 dev_dbg(dev, "component register %s\n", dev_name(dev));
4327
4328 cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
4329 if (!cmpnt) {
4330 dev_err(dev, "ASoC: Failed to allocate memory\n");
4331 return -ENOMEM;
4332 }
4333
4334 cmpnt->name = fmt_single_name(dev, &cmpnt->id);
4335 if (!cmpnt->name) {
4336 dev_err(dev, "ASoC: Failed to simplifying name\n");
4337 return -ENOMEM;
4338 }
4339
4340 cmpnt->dev = dev;
4341 cmpnt->driver = cmpnt_drv;
4342 cmpnt->num_dai = num_dai;
4343
4344 /*
4345 * snd_soc_register_dai() uses fmt_single_name(), and
4346 * snd_soc_register_dais() uses fmt_multiple_name()
4347 * for dai->name which is used for name based matching
4348 */
4349 if (1 == num_dai)
4350 ret = snd_soc_register_dai(dev, dai_drv);
4351 else
4352 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4353 if (ret < 0) {
4354 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4355 goto error_component_name;
4356 }
4357
4358 mutex_lock(&client_mutex);
4359 list_add(&cmpnt->list, &component_list);
4360 mutex_unlock(&client_mutex);
4361
4362 dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
4363
4364 return ret;
4365
4366error_component_name:
4367 kfree(cmpnt->name);
4368
4369 return ret;
4370}
4371EXPORT_SYMBOL_GPL(snd_soc_register_component);
4372
4373/**
4374 * snd_soc_unregister_component - Unregister a component from the ASoC core
4375 *
4376 */
4377void snd_soc_unregister_component(struct device *dev)
4378{
4379 struct snd_soc_component *cmpnt;
4380
4381 list_for_each_entry(cmpnt, &component_list, list) {
4382 if (dev == cmpnt->dev)
4383 goto found;
4384 }
4385 return;
4386
4387found:
4388 snd_soc_unregister_dais(dev, cmpnt->num_dai);
4389
4390 mutex_lock(&client_mutex);
4391 list_del(&cmpnt->list);
4392 mutex_unlock(&client_mutex);
4393
4394 dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
4395 kfree(cmpnt->name);
4396}
4397EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4398
4399/* Retrieve a card's name from device tree */ 4421/* Retrieve a card's name from device tree */
4400int snd_soc_of_parse_card_name(struct snd_soc_card *card, 4422int snd_soc_of_parse_card_name(struct snd_soc_card *card,
4401 const char *propname) 4423 const char *propname)
@@ -4583,6 +4605,41 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
4583} 4605}
4584EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); 4606EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
4585 4607
4608int snd_soc_of_get_dai_name(struct device_node *of_node,
4609 const char **dai_name)
4610{
4611 struct snd_soc_component *pos;
4612 struct of_phandle_args args;
4613 int ret;
4614
4615 ret = of_parse_phandle_with_args(of_node, "sound-dai",
4616 "#sound-dai-cells", 0, &args);
4617 if (ret)
4618 return ret;
4619
4620 ret = -EPROBE_DEFER;
4621
4622 mutex_lock(&client_mutex);
4623 list_for_each_entry(pos, &component_list, list) {
4624 if (pos->dev->of_node != args.np)
4625 continue;
4626
4627 if (!pos->driver->of_xlate_dai_name) {
4628 ret = -ENOSYS;
4629 break;
4630 }
4631
4632 ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
4633 break;
4634 }
4635 mutex_unlock(&client_mutex);
4636
4637 of_node_put(args.np);
4638
4639 return ret;
4640}
4641EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
4642
4586static int __init snd_soc_init(void) 4643static int __init snd_soc_init(void)
4587{ 4644{
4588#ifdef CONFIG_DEBUG_FS 4645#ifdef CONFIG_DEBUG_FS