Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/core/ctljack.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Helper functions for jack-detection kcontrols
4
*
5
* Copyright (c) 2011 Takashi Iwai <[email protected]>
6
*/
7
8
#include <linux/kernel.h>
9
#include <linux/export.h>
10
#include <sound/core.h>
11
#include <sound/control.h>
12
13
#define jack_detect_kctl_info snd_ctl_boolean_mono_info
14
15
static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol,
16
struct snd_ctl_elem_value *ucontrol)
17
{
18
ucontrol->value.integer.value[0] = kcontrol->private_value;
19
return 0;
20
}
21
22
static const struct snd_kcontrol_new jack_detect_kctl = {
23
/* name is filled later */
24
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
25
.access = SNDRV_CTL_ELEM_ACCESS_READ,
26
.info = jack_detect_kctl_info,
27
.get = jack_detect_kctl_get,
28
};
29
30
static int get_available_index(struct snd_card *card, const char *name)
31
{
32
struct snd_ctl_elem_id sid;
33
34
memset(&sid, 0, sizeof(sid));
35
36
sid.index = 0;
37
sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
38
strscpy(sid.name, name, sizeof(sid.name));
39
40
while (snd_ctl_find_id(card, &sid)) {
41
sid.index++;
42
/* reset numid; otherwise snd_ctl_find_id() hits this again */
43
sid.numid = 0;
44
}
45
46
return sid.index;
47
}
48
49
static void jack_kctl_name_gen(char *name, const char *src_name, int size)
50
{
51
size_t count = strlen(src_name);
52
bool need_cat = true;
53
54
/* remove redundant " Jack" from src_name */
55
if (count >= 5)
56
need_cat = strncmp(&src_name[count - 5], " Jack", 5) ? true : false;
57
58
snprintf(name, size, need_cat ? "%s Jack" : "%s", src_name);
59
60
}
61
62
struct snd_kcontrol *
63
snd_kctl_jack_new(const char *name, struct snd_card *card)
64
{
65
struct snd_kcontrol *kctl;
66
67
kctl = snd_ctl_new1(&jack_detect_kctl, NULL);
68
if (!kctl)
69
return NULL;
70
71
jack_kctl_name_gen(kctl->id.name, name, sizeof(kctl->id.name));
72
kctl->id.index = get_available_index(card, kctl->id.name);
73
kctl->private_value = 0;
74
return kctl;
75
}
76
77
void snd_kctl_jack_report(struct snd_card *card,
78
struct snd_kcontrol *kctl, bool status)
79
{
80
if (kctl->private_value == status)
81
return;
82
kctl->private_value = status;
83
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
84
}
85
86