xref: /openbmc/linux/sound/core/ctljack.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
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