aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-11-08 05:43:24 -0500
committerMark Brown <broonie@linaro.org>2013-11-08 05:43:24 -0500
commitd20b09f0c5aaaa49a8a0189837a87adbc40095f0 (patch)
treed16d7c1f74edafee2a9f05d81e4e903d86ad9053 /sound/soc/soc-core.c
parent2fc175c4a347153a5e4f370a7dd574d56d46bb8a (diff)
parentcb470087669a3fab1958fec79dd7db280b33f178 (diff)
Merge remote-tracking branch 'asoc/topic/component' into asoc-next
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 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