Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next
This commit is contained in:
commit
bd26974f71
|
@ -2884,7 +2884,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
|||
{
|
||||
int i, r, ret = 0;
|
||||
|
||||
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
||||
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
for (i = 0; i < num; i++) {
|
||||
r = snd_soc_dapm_add_route(dapm, route);
|
||||
if (r < 0) {
|
||||
|
@ -2915,7 +2915,7 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
|
|||
{
|
||||
int i;
|
||||
|
||||
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
|
||||
mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
||||
for (i = 0; i < num; i++) {
|
||||
snd_soc_dapm_del_route(dapm, route);
|
||||
route++;
|
||||
|
@ -3778,18 +3778,27 @@ static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
|
||||
const struct snd_soc_pcm_stream *params,
|
||||
unsigned int num_params,
|
||||
struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
static void
|
||||
snd_soc_dapm_free_kcontrol(struct snd_soc_card *card,
|
||||
unsigned long *private_value,
|
||||
int num_params,
|
||||
const char **w_param_text)
|
||||
{
|
||||
int count;
|
||||
|
||||
devm_kfree(card->dev, (void *)*private_value);
|
||||
for (count = 0 ; count < num_params; count++)
|
||||
devm_kfree(card->dev, (void *)w_param_text[count]);
|
||||
devm_kfree(card->dev, w_param_text);
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new *
|
||||
snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
|
||||
char *link_name,
|
||||
const struct snd_soc_pcm_stream *params,
|
||||
int num_params, const char **w_param_text,
|
||||
unsigned long *private_value)
|
||||
{
|
||||
struct snd_soc_dapm_widget template;
|
||||
struct snd_soc_dapm_widget *w;
|
||||
char *link_name;
|
||||
int ret, count;
|
||||
unsigned long private_value;
|
||||
const char **w_param_text;
|
||||
struct soc_enum w_param_enum[] = {
|
||||
SOC_ENUM_SINGLE(0, 0, 0, NULL),
|
||||
};
|
||||
|
@ -3798,19 +3807,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
|
|||
snd_soc_dapm_dai_link_get,
|
||||
snd_soc_dapm_dai_link_put),
|
||||
};
|
||||
struct snd_kcontrol_new *kcontrol_news;
|
||||
const struct snd_soc_pcm_stream *config = params;
|
||||
|
||||
w_param_text = devm_kcalloc(card->dev, num_params,
|
||||
sizeof(char *), GFP_KERNEL);
|
||||
if (!w_param_text)
|
||||
return -ENOMEM;
|
||||
|
||||
link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
|
||||
source->name, sink->name);
|
||||
if (!link_name) {
|
||||
ret = -ENOMEM;
|
||||
goto outfree_w_param;
|
||||
}
|
||||
int count;
|
||||
|
||||
for (count = 0 ; count < num_params; count++) {
|
||||
if (!config->stream_name) {
|
||||
|
@ -3821,25 +3820,64 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
|
|||
devm_kasprintf(card->dev, GFP_KERNEL,
|
||||
"Anonymous Configuration %d",
|
||||
count);
|
||||
if (!w_param_text[count]) {
|
||||
ret = -ENOMEM;
|
||||
goto outfree_link_name;
|
||||
}
|
||||
} else {
|
||||
w_param_text[count] = devm_kmemdup(card->dev,
|
||||
config->stream_name,
|
||||
strlen(config->stream_name) + 1,
|
||||
GFP_KERNEL);
|
||||
if (!w_param_text[count]) {
|
||||
ret = -ENOMEM;
|
||||
goto outfree_link_name;
|
||||
}
|
||||
}
|
||||
if (!w_param_text[count])
|
||||
goto outfree_w_param;
|
||||
config++;
|
||||
}
|
||||
|
||||
w_param_enum[0].items = num_params;
|
||||
w_param_enum[0].texts = w_param_text;
|
||||
|
||||
*private_value =
|
||||
(unsigned long) devm_kmemdup(card->dev,
|
||||
(void *)(kcontrol_dai_link[0].private_value),
|
||||
sizeof(struct soc_enum), GFP_KERNEL);
|
||||
if (!*private_value) {
|
||||
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
|
||||
link_name);
|
||||
goto outfree_w_param;
|
||||
}
|
||||
kcontrol_dai_link[0].private_value = *private_value;
|
||||
/* duplicate kcontrol_dai_link on heap so that memory persists */
|
||||
kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0],
|
||||
sizeof(struct snd_kcontrol_new),
|
||||
GFP_KERNEL);
|
||||
if (!kcontrol_news) {
|
||||
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
|
||||
link_name);
|
||||
goto outfree_w_param;
|
||||
}
|
||||
return kcontrol_news;
|
||||
|
||||
outfree_w_param:
|
||||
snd_soc_dapm_free_kcontrol(card, private_value, num_params, w_param_text);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
|
||||
const struct snd_soc_pcm_stream *params,
|
||||
unsigned int num_params,
|
||||
struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_dapm_widget template;
|
||||
struct snd_soc_dapm_widget *w;
|
||||
const char **w_param_text;
|
||||
unsigned long private_value;
|
||||
char *link_name;
|
||||
int ret;
|
||||
|
||||
link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
|
||||
source->name, sink->name);
|
||||
if (!link_name)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.reg = SND_SOC_NOPM;
|
||||
template.id = snd_soc_dapm_dai_link;
|
||||
|
@ -3847,31 +3885,29 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
|
|||
template.event = snd_soc_dai_link_event;
|
||||
template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMD;
|
||||
template.num_kcontrols = 1;
|
||||
/* duplicate w_param_enum on heap so that memory persists */
|
||||
private_value =
|
||||
(unsigned long) devm_kmemdup(card->dev,
|
||||
(void *)(kcontrol_dai_link[0].private_value),
|
||||
sizeof(struct soc_enum), GFP_KERNEL);
|
||||
if (!private_value) {
|
||||
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
|
||||
link_name);
|
||||
ret = -ENOMEM;
|
||||
goto outfree_link_name;
|
||||
}
|
||||
kcontrol_dai_link[0].private_value = private_value;
|
||||
/* duplicate kcontrol_dai_link on heap so that memory persists */
|
||||
template.kcontrol_news =
|
||||
devm_kmemdup(card->dev, &kcontrol_dai_link[0],
|
||||
sizeof(struct snd_kcontrol_new),
|
||||
GFP_KERNEL);
|
||||
if (!template.kcontrol_news) {
|
||||
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
|
||||
link_name);
|
||||
ret = -ENOMEM;
|
||||
goto outfree_private_value;
|
||||
}
|
||||
template.kcontrol_news = NULL;
|
||||
|
||||
/* allocate memory for control, only in case of multiple configs */
|
||||
if (num_params > 1) {
|
||||
w_param_text = devm_kcalloc(card->dev, num_params,
|
||||
sizeof(char *), GFP_KERNEL);
|
||||
if (!w_param_text) {
|
||||
ret = -ENOMEM;
|
||||
goto param_fail;
|
||||
}
|
||||
|
||||
template.num_kcontrols = 1;
|
||||
template.kcontrol_news =
|
||||
snd_soc_dapm_alloc_kcontrol(card,
|
||||
link_name, params, num_params,
|
||||
w_param_text, &private_value);
|
||||
if (!template.kcontrol_news) {
|
||||
ret = -ENOMEM;
|
||||
goto param_fail;
|
||||
}
|
||||
} else {
|
||||
w_param_text = NULL;
|
||||
}
|
||||
dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
|
||||
|
||||
w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
|
||||
|
@ -3903,15 +3939,9 @@ outfree_w:
|
|||
devm_kfree(card->dev, w);
|
||||
outfree_kcontrol_news:
|
||||
devm_kfree(card->dev, (void *)template.kcontrol_news);
|
||||
outfree_private_value:
|
||||
devm_kfree(card->dev, (void *)private_value);
|
||||
outfree_link_name:
|
||||
snd_soc_dapm_free_kcontrol(card, &private_value, num_params, w_param_text);
|
||||
param_fail:
|
||||
devm_kfree(card->dev, link_name);
|
||||
outfree_w_param:
|
||||
for (count = 0 ; count < num_params; count++)
|
||||
devm_kfree(card->dev, (void *)w_param_text[count]);
|
||||
devm_kfree(card->dev, w_param_text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue