12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
235be544aSTakashi Iwai /*
335be544aSTakashi Iwai * Helper functions for jack-detection kcontrols
435be544aSTakashi Iwai *
535be544aSTakashi Iwai * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
635be544aSTakashi Iwai */
735be544aSTakashi Iwai
835be544aSTakashi Iwai #include <linux/kernel.h>
9bf815bf0STakashi Iwai #include <linux/export.h>
1035be544aSTakashi Iwai #include <sound/core.h>
1135be544aSTakashi Iwai #include <sound/control.h>
1235be544aSTakashi Iwai
1335be544aSTakashi Iwai #define jack_detect_kctl_info snd_ctl_boolean_mono_info
1435be544aSTakashi Iwai
jack_detect_kctl_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1535be544aSTakashi Iwai static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
1635be544aSTakashi Iwai struct snd_ctl_elem_value *ucontrol)
1735be544aSTakashi Iwai {
1835be544aSTakashi Iwai ucontrol->value.integer.value[0] = kcontrol->private_value;
1935be544aSTakashi Iwai return 0;
2035be544aSTakashi Iwai }
2135be544aSTakashi Iwai
22905e46acSBhumika Goyal static const struct snd_kcontrol_new jack_detect_kctl = {
2335be544aSTakashi Iwai /* name is filled later */
2435be544aSTakashi Iwai .iface = SNDRV_CTL_ELEM_IFACE_CARD,
2535be544aSTakashi Iwai .access = SNDRV_CTL_ELEM_ACCESS_READ,
2635be544aSTakashi Iwai .info = jack_detect_kctl_info,
2735be544aSTakashi Iwai .get = jack_detect_kctl_get,
2835be544aSTakashi Iwai };
2935be544aSTakashi Iwai
get_available_index(struct snd_card * card,const char * name)30b8dd0866SJie Yang static int get_available_index(struct snd_card *card, const char *name)
31b8dd0866SJie Yang {
32b8dd0866SJie Yang struct snd_ctl_elem_id sid;
33b8dd0866SJie Yang
34b8dd0866SJie Yang memset(&sid, 0, sizeof(sid));
35b8dd0866SJie Yang
36b8dd0866SJie Yang sid.index = 0;
37b8dd0866SJie Yang sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
38*75b1a8f9SJoe Perches strscpy(sid.name, name, sizeof(sid.name));
39b8dd0866SJie Yang
407378bc2fSTakashi Iwai while (snd_ctl_find_id(card, &sid)) {
41b8dd0866SJie Yang sid.index++;
427378bc2fSTakashi Iwai /* reset numid; otherwise snd_ctl_find_id() hits this again */
437378bc2fSTakashi Iwai sid.numid = 0;
447378bc2fSTakashi Iwai }
45b8dd0866SJie Yang
46b8dd0866SJie Yang return sid.index;
47b8dd0866SJie Yang }
48b8dd0866SJie Yang
jack_kctl_name_gen(char * name,const char * src_name,int size)49b8dd0866SJie Yang static void jack_kctl_name_gen(char *name, const char *src_name, int size)
50b8dd0866SJie Yang {
51b8dd0866SJie Yang size_t count = strlen(src_name);
52b8dd0866SJie Yang bool need_cat = true;
53b8dd0866SJie Yang
54b8dd0866SJie Yang /* remove redundant " Jack" from src_name */
55b8dd0866SJie Yang if (count >= 5)
56b8dd0866SJie Yang need_cat = strncmp(&src_name[count - 5], " Jack", 5) ? true : false;
57b8dd0866SJie Yang
58b8dd0866SJie Yang snprintf(name, size, need_cat ? "%s Jack" : "%s", src_name);
59b8dd0866SJie Yang
60b8dd0866SJie Yang }
61b8dd0866SJie Yang
6235be544aSTakashi Iwai struct snd_kcontrol *
snd_kctl_jack_new(const char * name,struct snd_card * card)632ba2dfa1SJie Yang snd_kctl_jack_new(const char *name, struct snd_card *card)
6435be544aSTakashi Iwai {
6535be544aSTakashi Iwai struct snd_kcontrol *kctl;
66b8dd0866SJie Yang
672ba2dfa1SJie Yang kctl = snd_ctl_new1(&jack_detect_kctl, NULL);
6835be544aSTakashi Iwai if (!kctl)
6935be544aSTakashi Iwai return NULL;
70b8dd0866SJie Yang
71b8dd0866SJie Yang jack_kctl_name_gen(kctl->id.name, name, sizeof(kctl->id.name));
72d0a601c2STakashi Iwai kctl->id.index = get_available_index(card, kctl->id.name);
7335be544aSTakashi Iwai kctl->private_value = 0;
7435be544aSTakashi Iwai return kctl;
7535be544aSTakashi Iwai }
7635be544aSTakashi Iwai
snd_kctl_jack_report(struct snd_card * card,struct snd_kcontrol * kctl,bool status)7735be544aSTakashi Iwai void snd_kctl_jack_report(struct snd_card *card,
7835be544aSTakashi Iwai struct snd_kcontrol *kctl, bool status)
7935be544aSTakashi Iwai {
8035be544aSTakashi Iwai if (kctl->private_value == status)
8135be544aSTakashi Iwai return;
8235be544aSTakashi Iwai kctl->private_value = status;
8335be544aSTakashi Iwai snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
8435be544aSTakashi Iwai }
85