diff options
-rw-r--r-- | include/sound/soc.h | 19 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 77 |
2 files changed, 96 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index a6a059ca3874..8c46d0a7e2c0 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -324,6 +324,8 @@ struct snd_soc_dai_link; | |||
324 | struct snd_soc_platform_driver; | 324 | struct snd_soc_platform_driver; |
325 | struct snd_soc_codec; | 325 | struct snd_soc_codec; |
326 | struct snd_soc_codec_driver; | 326 | struct snd_soc_codec_driver; |
327 | struct snd_soc_component; | ||
328 | struct snd_soc_component_driver; | ||
327 | struct soc_enum; | 329 | struct soc_enum; |
328 | struct snd_soc_jack; | 330 | struct snd_soc_jack; |
329 | struct snd_soc_jack_zone; | 331 | struct snd_soc_jack_zone; |
@@ -377,6 +379,10 @@ int snd_soc_register_codec(struct device *dev, | |||
377 | const struct snd_soc_codec_driver *codec_drv, | 379 | const struct snd_soc_codec_driver *codec_drv, |
378 | struct snd_soc_dai_driver *dai_drv, int num_dai); | 380 | struct snd_soc_dai_driver *dai_drv, int num_dai); |
379 | void snd_soc_unregister_codec(struct device *dev); | 381 | void snd_soc_unregister_codec(struct device *dev); |
382 | int snd_soc_register_component(struct device *dev, | ||
383 | const struct snd_soc_component_driver *cmpnt_drv, | ||
384 | struct snd_soc_dai_driver *dai_drv, int num_dai); | ||
385 | void snd_soc_unregister_component(struct device *dev); | ||
380 | int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, | 386 | int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, |
381 | unsigned int reg); | 387 | unsigned int reg); |
382 | int snd_soc_codec_readable_register(struct snd_soc_codec *codec, | 388 | int snd_soc_codec_readable_register(struct snd_soc_codec *codec, |
@@ -841,6 +847,19 @@ struct snd_soc_platform { | |||
841 | #endif | 847 | #endif |
842 | }; | 848 | }; |
843 | 849 | ||
850 | struct snd_soc_component_driver { | ||
851 | }; | ||
852 | |||
853 | struct snd_soc_component { | ||
854 | const char *name; | ||
855 | int id; | ||
856 | int num_dai; | ||
857 | struct device *dev; | ||
858 | struct list_head list; | ||
859 | |||
860 | const struct snd_soc_component_driver *driver; | ||
861 | }; | ||
862 | |||
844 | struct snd_soc_dai_link { | 863 | struct snd_soc_dai_link { |
845 | /* config - must be set by machine driver */ | 864 | /* config - must be set by machine driver */ |
846 | const char *name; /* Codec name */ | 865 | const char *name; /* Codec name */ |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b7e84a7cd9ee..9e6118573fef 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -58,6 +58,7 @@ static DEFINE_MUTEX(client_mutex); | |||
58 | static LIST_HEAD(dai_list); | 58 | static LIST_HEAD(dai_list); |
59 | static LIST_HEAD(platform_list); | 59 | static LIST_HEAD(platform_list); |
60 | static LIST_HEAD(codec_list); | 60 | static LIST_HEAD(codec_list); |
61 | static LIST_HEAD(component_list); | ||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * This is a timeout to do a DAPM powerdown after a stream is closed(). | 64 | * This is a timeout to do a DAPM powerdown after a stream is closed(). |
@@ -4137,6 +4138,82 @@ found: | |||
4137 | } | 4138 | } |
4138 | EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); | 4139 | EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); |
4139 | 4140 | ||
4141 | |||
4142 | /** | ||
4143 | * snd_soc_register_component - Register a component with the ASoC core | ||
4144 | * | ||
4145 | */ | ||
4146 | int snd_soc_register_component(struct device *dev, | ||
4147 | const struct snd_soc_component_driver *cmpnt_drv, | ||
4148 | struct snd_soc_dai_driver *dai_drv, | ||
4149 | int num_dai) | ||
4150 | { | ||
4151 | struct snd_soc_component *cmpnt; | ||
4152 | int ret; | ||
4153 | |||
4154 | dev_dbg(dev, "component register %s\n", dev_name(dev)); | ||
4155 | |||
4156 | cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL); | ||
4157 | if (!cmpnt) { | ||
4158 | dev_err(dev, "ASoC: Failed to allocate memory\n"); | ||
4159 | return -ENOMEM; | ||
4160 | } | ||
4161 | |||
4162 | cmpnt->name = fmt_single_name(dev, &cmpnt->id); | ||
4163 | if (!cmpnt->name) { | ||
4164 | dev_err(dev, "ASoC: Failed to simplifying name\n"); | ||
4165 | return -ENOMEM; | ||
4166 | } | ||
4167 | |||
4168 | cmpnt->dev = dev; | ||
4169 | cmpnt->driver = cmpnt_drv; | ||
4170 | cmpnt->num_dai = num_dai; | ||
4171 | |||
4172 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | ||
4173 | if (ret < 0) { | ||
4174 | dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); | ||
4175 | goto error_component_name; | ||
4176 | } | ||
4177 | |||
4178 | mutex_lock(&client_mutex); | ||
4179 | list_add(&cmpnt->list, &component_list); | ||
4180 | mutex_unlock(&client_mutex); | ||
4181 | |||
4182 | dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name); | ||
4183 | |||
4184 | return ret; | ||
4185 | |||
4186 | error_component_name: | ||
4187 | kfree(cmpnt->name); | ||
4188 | |||
4189 | return ret; | ||
4190 | } | ||
4191 | |||
4192 | /** | ||
4193 | * snd_soc_unregister_component - Unregister a component from the ASoC core | ||
4194 | * | ||
4195 | */ | ||
4196 | void snd_soc_unregister_component(struct device *dev) | ||
4197 | { | ||
4198 | struct snd_soc_component *cmpnt; | ||
4199 | |||
4200 | list_for_each_entry(cmpnt, &component_list, list) { | ||
4201 | if (dev == cmpnt->dev) | ||
4202 | goto found; | ||
4203 | } | ||
4204 | return; | ||
4205 | |||
4206 | found: | ||
4207 | snd_soc_unregister_dais(dev, cmpnt->num_dai); | ||
4208 | |||
4209 | mutex_lock(&client_mutex); | ||
4210 | list_del(&cmpnt->list); | ||
4211 | mutex_unlock(&client_mutex); | ||
4212 | |||
4213 | dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); | ||
4214 | kfree(cmpnt->name); | ||
4215 | } | ||
4216 | |||
4140 | /* Retrieve a card's name from device tree */ | 4217 | /* Retrieve a card's name from device tree */ |
4141 | int snd_soc_of_parse_card_name(struct snd_soc_card *card, | 4218 | int snd_soc_of_parse_card_name(struct snd_soc_card *card, |
4142 | const char *propname) | 4219 | const char *propname) |