From b8dd086674cfbfc246a5b9d7d7ff37f62350a878 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Mon, 27 Apr 2015 21:20:57 +0800 Subject: [PATCH] ALSA: Jack: handle jack embedded kcontrol creating within ctljack This patch adds a static method get_available_index() to allocate the index of new jack kcontrols and also adds jack_kctl_name_gen() which is used to ensure compatibility with jack naming by removing " Jack" from some incorrectly passed names. Signed-off-by: Jie Yang Signed-off-by: Takashi Iwai --- include/sound/control.h | 2 +- sound/core/ctljack.c | 37 ++++++++++++++++++++++++++++++++++--- sound/core/jack.c | 2 +- sound/pci/hda/hda_jack.c | 2 +- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/sound/control.h b/include/sound/control.h index 95aad6d3fd1a..f50e2e918ceb 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -252,7 +252,7 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); * Helper functions for jack-detection controls */ struct snd_kcontrol * -snd_kctl_jack_new(const char *name, int idx, void *private_data); +snd_kctl_jack_new(const char *name, void *private_data, struct snd_card *card); void snd_kctl_jack_report(struct snd_card *card, struct snd_kcontrol *kctl, bool status); diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c index e4b38fbe51da..df7c6cd63c4a 100644 --- a/sound/core/ctljack.c +++ b/sound/core/ctljack.c @@ -31,15 +31,46 @@ static struct snd_kcontrol_new jack_detect_kctl = { .get = jack_detect_kctl_get, }; +static int get_available_index(struct snd_card *card, const char *name) +{ + struct snd_ctl_elem_id sid; + + memset(&sid, 0, sizeof(sid)); + + sid.index = 0; + sid.iface = SNDRV_CTL_ELEM_IFACE_CARD; + strlcpy(sid.name, name, sizeof(sid.name)); + + while (snd_ctl_find_id(card, &sid)) + sid.index++; + + return sid.index; +} + +static void jack_kctl_name_gen(char *name, const char *src_name, int size) +{ + size_t count = strlen(src_name); + bool need_cat = true; + + /* remove redundant " Jack" from src_name */ + if (count >= 5) + need_cat = strncmp(&src_name[count - 5], " Jack", 5) ? true : false; + + snprintf(name, size, need_cat ? "%s Jack" : "%s", src_name); + +} + struct snd_kcontrol * -snd_kctl_jack_new(const char *name, int idx, void *private_data) +snd_kctl_jack_new(const char *name, void *private_data, struct snd_card *card) { struct snd_kcontrol *kctl; + kctl = snd_ctl_new1(&jack_detect_kctl, private_data); if (!kctl) return NULL; - snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name); - kctl->id.index = idx; + + jack_kctl_name_gen(kctl->id.name, name, sizeof(kctl->id.name)); + kctl->id.index = get_available_index(card, name); kctl->private_value = 0; return kctl; } diff --git a/sound/core/jack.c b/sound/core/jack.c index db69ecc23651..067d37d14e64 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -135,7 +135,7 @@ static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const cha struct snd_jack_kctl *jack_kctl; int err; - kctl = snd_kctl_jack_new(name, 0, card); + kctl = snd_kctl_jack_new(name, card, card); if (!kctl) return NULL; diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index d7cfe7b8c32b..05b49aa8af6c 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -402,7 +402,7 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, return 0; if (jack->kctl) return 0; /* already created */ - kctl = snd_kctl_jack_new(name, idx, codec); + kctl = snd_kctl_jack_new(name, codec, codec->card); if (!kctl) return -ENOMEM; err = snd_hda_ctl_add(codec, nid, kctl);