aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-09-17 08:25:28 -0400
committerMark Brown <broonie@linaro.org>2013-09-17 08:25:28 -0400
commit7d930ce26e01470590cd003484b32df29529906c (patch)
tree7fd2b7d0f85f104009ef9edeb32806f6bbc47070 /sound/soc/soc-core.c
parent7f05cc98bd9b10b9a0173f3f5d20c2223fdf7470 (diff)
parentcb470087669a3fab1958fec79dd7db280b33f178 (diff)
Merge remote-tracking branch 'asoc/topic/component' into asoc-core
Conflicts: include/sound/soc.h
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c237
1 files changed, 147 insertions, 90 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 16a3930c6375..67cfb5f5ca96 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3996,6 +3996,112 @@ static void snd_soc_unregister_dais(struct device *dev, size_t count)
3996} 3996}
3997 3997
3998/** 3998/**
3999 * snd_soc_register_component - Register a component with the ASoC core
4000 *
4001 */
4002static int
4003__snd_soc_register_component(struct device *dev,
4004 struct snd_soc_component *cmpnt,
4005 const struct snd_soc_component_driver *cmpnt_drv,
4006 struct snd_soc_dai_driver *dai_drv,
4007 int num_dai, bool allow_single_dai)
4008{
4009 int ret;
4010
4011 dev_dbg(dev, "component register %s\n", dev_name(dev));
4012
4013 if (!cmpnt) {
4014 dev_err(dev, "ASoC: Failed to connecting component\n");
4015 return -ENOMEM;
4016 }
4017
4018 cmpnt->name = fmt_single_name(dev, &cmpnt->id);
4019 if (!cmpnt->name) {
4020 dev_err(dev, "ASoC: Failed to simplifying name\n");
4021 return -ENOMEM;
4022 }
4023
4024 cmpnt->dev = dev;
4025 cmpnt->driver = cmpnt_drv;
4026 cmpnt->num_dai = num_dai;
4027
4028 /*
4029 * snd_soc_register_dai() uses fmt_single_name(), and
4030 * snd_soc_register_dais() uses fmt_multiple_name()
4031 * for dai->name which is used for name based matching
4032 *
4033 * this function is used from cpu/codec.
4034 * allow_single_dai flag can ignore "codec" driver reworking
4035 * since it had been used snd_soc_register_dais(),
4036 */
4037 if ((1 == num_dai) && allow_single_dai)
4038 ret = snd_soc_register_dai(dev, dai_drv);
4039 else
4040 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4041 if (ret < 0) {
4042 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4043 goto error_component_name;
4044 }
4045
4046 mutex_lock(&client_mutex);
4047 list_add(&cmpnt->list, &component_list);
4048 mutex_unlock(&client_mutex);
4049
4050 dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
4051
4052 return ret;
4053
4054error_component_name:
4055 kfree(cmpnt->name);
4056
4057 return ret;
4058}
4059
4060int snd_soc_register_component(struct device *dev,
4061 const struct snd_soc_component_driver *cmpnt_drv,
4062 struct snd_soc_dai_driver *dai_drv,
4063 int num_dai)
4064{
4065 struct snd_soc_component *cmpnt;
4066
4067 cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
4068 if (!cmpnt) {
4069 dev_err(dev, "ASoC: Failed to allocate memory\n");
4070 return -ENOMEM;
4071 }
4072
4073 return __snd_soc_register_component(dev, cmpnt, cmpnt_drv,
4074 dai_drv, num_dai, true);
4075}
4076EXPORT_SYMBOL_GPL(snd_soc_register_component);
4077
4078/**
4079 * snd_soc_unregister_component - Unregister a component from the ASoC core
4080 *
4081 */
4082void snd_soc_unregister_component(struct device *dev)
4083{
4084 struct snd_soc_component *cmpnt;
4085
4086 list_for_each_entry(cmpnt, &component_list, list) {
4087 if (dev == cmpnt->dev)
4088 goto found;
4089 }
4090 return;
4091
4092found:
4093 snd_soc_unregister_dais(dev, cmpnt->num_dai);
4094
4095 mutex_lock(&client_mutex);
4096 list_del(&cmpnt->list);
4097 mutex_unlock(&client_mutex);
4098
4099 dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
4100 kfree(cmpnt->name);
4101}
4102EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4103
4104/**
3999 * snd_soc_add_platform - Add a platform to the ASoC core 4105 * snd_soc_add_platform - Add a platform to the ASoC core
4000 * @dev: The parent device for the platform 4106 * @dev: The parent device for the platform
4001 * @platform: The platform to add 4107 * @platform: The platform to add
@@ -4182,10 +4288,12 @@ int snd_soc_register_codec(struct device *dev,
4182 list_add(&codec->list, &codec_list); 4288 list_add(&codec->list, &codec_list);
4183 mutex_unlock(&client_mutex); 4289 mutex_unlock(&client_mutex);
4184 4290
4185 /* register any DAIs */ 4291 /* register component */
4186 ret = snd_soc_register_dais(dev, dai_drv, num_dai); 4292 ret = __snd_soc_register_component(dev, &codec->component,
4293 &codec_drv->component_driver,
4294 dai_drv, num_dai, false);
4187 if (ret < 0) { 4295 if (ret < 0) {
4188 dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret); 4296 dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
4189 goto fail_codec_name; 4297 goto fail_codec_name;
4190 } 4298 }
4191 4299
@@ -4220,7 +4328,7 @@ void snd_soc_unregister_codec(struct device *dev)
4220 return; 4328 return;
4221 4329
4222found: 4330found:
4223 snd_soc_unregister_dais(dev, codec->num_dai); 4331 snd_soc_unregister_component(dev);
4224 4332
4225 mutex_lock(&client_mutex); 4333 mutex_lock(&client_mutex);
4226 list_del(&codec->list); 4334 list_del(&codec->list);
@@ -4234,92 +4342,6 @@ found:
4234} 4342}
4235EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); 4343EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
4236 4344
4237
4238/**
4239 * snd_soc_register_component - Register a component with the ASoC core
4240 *
4241 */
4242int snd_soc_register_component(struct device *dev,
4243 const struct snd_soc_component_driver *cmpnt_drv,
4244 struct snd_soc_dai_driver *dai_drv,
4245 int num_dai)
4246{
4247 struct snd_soc_component *cmpnt;
4248 int ret;
4249
4250 dev_dbg(dev, "component register %s\n", dev_name(dev));
4251
4252 cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
4253 if (!cmpnt) {
4254 dev_err(dev, "ASoC: Failed to allocate memory\n");
4255 return -ENOMEM;
4256 }
4257
4258 cmpnt->name = fmt_single_name(dev, &cmpnt->id);
4259 if (!cmpnt->name) {
4260 dev_err(dev, "ASoC: Failed to simplifying name\n");
4261 return -ENOMEM;
4262 }
4263
4264 cmpnt->dev = dev;
4265 cmpnt->driver = cmpnt_drv;
4266 cmpnt->num_dai = num_dai;
4267
4268 /*
4269 * snd_soc_register_dai() uses fmt_single_name(), and
4270 * snd_soc_register_dais() uses fmt_multiple_name()
4271 * for dai->name which is used for name based matching
4272 */
4273 if (1 == num_dai)
4274 ret = snd_soc_register_dai(dev, dai_drv);
4275 else
4276 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
4277 if (ret < 0) {
4278 dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
4279 goto error_component_name;
4280 }
4281
4282 mutex_lock(&client_mutex);
4283 list_add(&cmpnt->list, &component_list);
4284 mutex_unlock(&client_mutex);
4285
4286 dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
4287
4288 return ret;
4289
4290error_component_name:
4291 kfree(cmpnt->name);
4292
4293 return ret;
4294}
4295EXPORT_SYMBOL_GPL(snd_soc_register_component);
4296
4297/**
4298 * snd_soc_unregister_component - Unregister a component from the ASoC core
4299 *
4300 */
4301void snd_soc_unregister_component(struct device *dev)
4302{
4303 struct snd_soc_component *cmpnt;
4304
4305 list_for_each_entry(cmpnt, &component_list, list) {
4306 if (dev == cmpnt->dev)
4307 goto found;
4308 }
4309 return;
4310
4311found:
4312 snd_soc_unregister_dais(dev, cmpnt->num_dai);
4313
4314 mutex_lock(&client_mutex);
4315 list_del(&cmpnt->list);
4316 mutex_unlock(&client_mutex);
4317
4318 dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
4319 kfree(cmpnt->name);
4320}
4321EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4322
4323/* Retrieve a card's name from device tree */ 4345/* Retrieve a card's name from device tree */
4324int snd_soc_of_parse_card_name(struct snd_soc_card *card, 4346int snd_soc_of_parse_card_name(struct snd_soc_card *card,
4325 const char *propname) 4347 const char *propname)
@@ -4507,6 +4529,41 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
4507} 4529}
4508EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt); 4530EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
4509 4531
4532int snd_soc_of_get_dai_name(struct device_node *of_node,
4533 const char **dai_name)
4534{
4535 struct snd_soc_component *pos;
4536 struct of_phandle_args args;
4537 int ret;
4538
4539 ret = of_parse_phandle_with_args(of_node, "sound-dai",
4540 "#sound-dai-cells", 0, &args);
4541 if (ret)
4542 return ret;
4543
4544 ret = -EPROBE_DEFER;
4545
4546 mutex_lock(&client_mutex);
4547 list_for_each_entry(pos, &component_list, list) {
4548 if (pos->dev->of_node != args.np)
4549 continue;
4550
4551 if (!pos->driver->of_xlate_dai_name) {
4552 ret = -ENOSYS;
4553 break;
4554 }
4555
4556 ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
4557 break;
4558 }
4559 mutex_unlock(&client_mutex);
4560
4561 of_node_put(args.np);
4562
4563 return ret;
4564}
4565EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
4566
4510static int __init snd_soc_init(void) 4567static int __init snd_soc_init(void)
4511{ 4568{
4512#ifdef CONFIG_DEBUG_FS 4569#ifdef CONFIG_DEBUG_FS