aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/jack.h9
-rw-r--r--sound/core/Kconfig3
-rw-r--r--sound/core/Makefile3
-rw-r--r--sound/core/jack.c93
-rw-r--r--sound/pci/hda/Kconfig2
5 files changed, 103 insertions, 7 deletions
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 218235030ebc..433b13b89125 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -73,6 +73,8 @@ enum snd_jack_types {
73 73
74struct snd_jack { 74struct snd_jack {
75 struct input_dev *input_dev; 75 struct input_dev *input_dev;
76 struct list_head kctl_list;
77 struct snd_card *card;
76 int registered; 78 int registered;
77 int type; 79 int type;
78 const char *id; 80 const char *id;
@@ -86,6 +88,7 @@ struct snd_jack {
86 88
87int snd_jack_new(struct snd_card *card, const char *id, int type, 89int snd_jack_new(struct snd_card *card, const char *id, int type,
88 struct snd_jack **jack); 90 struct snd_jack **jack);
91int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);
89void snd_jack_set_parent(struct snd_jack *jack, struct device *parent); 92void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
90int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, 93int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
91 int keytype); 94 int keytype);
@@ -93,13 +96,17 @@ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
93void snd_jack_report(struct snd_jack *jack, int status); 96void snd_jack_report(struct snd_jack *jack, int status);
94 97
95#else 98#else
96
97static inline int snd_jack_new(struct snd_card *card, const char *id, int type, 99static inline int snd_jack_new(struct snd_card *card, const char *id, int type,
98 struct snd_jack **jack) 100 struct snd_jack **jack)
99{ 101{
100 return 0; 102 return 0;
101} 103}
102 104
105static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
106{
107 return 0;
108}
109
103static inline void snd_jack_set_parent(struct snd_jack *jack, 110static inline void snd_jack_set_parent(struct snd_jack *jack,
104 struct device *parent) 111 struct device *parent)
105{ 112{
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 313f22e9d929..63cc2e967099 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -221,9 +221,6 @@ config SND_PCM_XRUN_DEBUG
221config SND_VMASTER 221config SND_VMASTER
222 bool 222 bool
223 223
224config SND_KCTL_JACK
225 bool
226
227config SND_DMA_SGBUF 224config SND_DMA_SGBUF
228 def_bool y 225 def_bool y
229 depends on X86 226 depends on X86
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 4daf2f58261c..e041dc25f2c8 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -7,8 +7,7 @@ snd-y := sound.o init.o memory.o info.o control.o misc.o device.o
7snd-$(CONFIG_ISA_DMA_API) += isadma.o 7snd-$(CONFIG_ISA_DMA_API) += isadma.o
8snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o 8snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
9snd-$(CONFIG_SND_VMASTER) += vmaster.o 9snd-$(CONFIG_SND_VMASTER) += vmaster.o
10snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o 10snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
11snd-$(CONFIG_SND_JACK) += jack.o
12 11
13snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ 12snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
14 pcm_memory.o memalloc.o 13 pcm_memory.o memalloc.o
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 8658578eb584..db69ecc23651 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -24,6 +24,13 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <sound/jack.h> 25#include <sound/jack.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/control.h>
28
29struct snd_jack_kctl {
30 struct snd_kcontrol *kctl;
31 struct list_head list; /* list of controls belong to the same jack */
32 unsigned int mask_bits; /* only masked status bits are reported via kctl */
33};
27 34
28static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { 35static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
29 SW_HEADPHONE_INSERT, 36 SW_HEADPHONE_INSERT,
@@ -54,7 +61,13 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
54static int snd_jack_dev_free(struct snd_device *device) 61static int snd_jack_dev_free(struct snd_device *device)
55{ 62{
56 struct snd_jack *jack = device->device_data; 63 struct snd_jack *jack = device->device_data;
64 struct snd_card *card = device->card;
65 struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
57 66
67 list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {
68 list_del_init(&jack_kctl->list);
69 snd_ctl_remove(card, jack_kctl->kctl);
70 }
58 if (jack->private_free) 71 if (jack->private_free)
59 jack->private_free(jack); 72 jack->private_free(jack);
60 73
@@ -100,6 +113,77 @@ static int snd_jack_dev_register(struct snd_device *device)
100 return err; 113 return err;
101} 114}
102 115
116static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
117{
118 struct snd_jack_kctl *jack_kctl;
119
120 jack_kctl = kctl->private_data;
121 if (jack_kctl) {
122 list_del(&jack_kctl->list);
123 kfree(jack_kctl);
124 }
125}
126
127static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_kctl)
128{
129 list_add_tail(&jack_kctl->list, &jack->kctl_list);
130}
131
132static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask)
133{
134 struct snd_kcontrol *kctl;
135 struct snd_jack_kctl *jack_kctl;
136 int err;
137
138 kctl = snd_kctl_jack_new(name, 0, card);
139 if (!kctl)
140 return NULL;
141
142 err = snd_ctl_add(card, kctl);
143 if (err < 0)
144 return NULL;
145
146 jack_kctl = kzalloc(sizeof(*jack_kctl), GFP_KERNEL);
147
148 if (!jack_kctl)
149 goto error;
150
151 jack_kctl->kctl = kctl;
152 jack_kctl->mask_bits = mask;
153
154 kctl->private_data = jack_kctl;
155 kctl->private_free = snd_jack_kctl_private_free;
156
157 return jack_kctl;
158error:
159 snd_ctl_free_one(kctl);
160 return NULL;
161}
162
163/**
164 * snd_jack_add_new_kctl - Create a new snd_jack_kctl and add it to jack
165 * @jack: the jack instance which the kctl will attaching to
166 * @name: the name for the snd_kcontrol object
167 * @mask: a bitmask of enum snd_jack_type values that can be detected
168 * by this snd_jack_kctl object.
169 *
170 * Creates a new snd_kcontrol object and adds it to the jack kctl_list.
171 *
172 * Return: Zero if successful, or a negative error code on failure.
173 */
174int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
175{
176 struct snd_jack_kctl *jack_kctl;
177
178 jack_kctl = snd_jack_kctl_new(jack->card, name, mask);
179 if (!jack_kctl)
180 return -ENOMEM;
181
182 snd_jack_kctl_add(jack, jack_kctl);
183 return 0;
184}
185EXPORT_SYMBOL(snd_jack_add_new_kctl);
186
103/** 187/**
104 * snd_jack_new - Create a new jack 188 * snd_jack_new - Create a new jack
105 * @card: the card instance 189 * @card: the card instance
@@ -150,6 +234,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
150 if (err < 0) 234 if (err < 0)
151 goto fail_input; 235 goto fail_input;
152 236
237 jack->card = card;
238 INIT_LIST_HEAD(&jack->kctl_list);
239
153 *jjack = jack; 240 *jjack = jack;
154 241
155 return 0; 242 return 0;
@@ -230,6 +317,7 @@ EXPORT_SYMBOL(snd_jack_set_key);
230 */ 317 */
231void snd_jack_report(struct snd_jack *jack, int status) 318void snd_jack_report(struct snd_jack *jack, int status)
232{ 319{
320 struct snd_jack_kctl *jack_kctl;
233 int i; 321 int i;
234 322
235 if (!jack) 323 if (!jack)
@@ -252,6 +340,11 @@ void snd_jack_report(struct snd_jack *jack, int status)
252 } 340 }
253 341
254 input_sync(jack->input_dev); 342 input_sync(jack->input_dev);
343
344 list_for_each_entry(jack_kctl, &jack->kctl_list, list)
345 snd_kctl_jack_report(jack->card, jack_kctl->kctl,
346 status & jack_kctl->mask_bits);
347
255} 348}
256EXPORT_SYMBOL(snd_jack_report); 349EXPORT_SYMBOL(snd_jack_report);
257 350
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index a5ed1c181784..4d3d4747e55a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -4,7 +4,7 @@ config SND_HDA
4 tristate 4 tristate
5 select SND_PCM 5 select SND_PCM
6 select SND_VMASTER 6 select SND_VMASTER
7 select SND_KCTL_JACK 7 select SND_JACK
8 select SND_HDA_CORE 8 select SND_HDA_CORE
9 9
10config SND_HDA_INTEL 10config SND_HDA_INTEL