aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-04-28 02:31:31 -0400
committerTakashi Iwai <tiwai@suse.de>2015-04-28 02:31:31 -0400
commit1962fcab4ee80e555bcc9d0f50e416800d474fa2 (patch)
tree945ba95f11016871f9d5241b7da2712f9367081a
parentf1a77547c21fe942e95ebaadbc9200f26d138574 (diff)
parent12e180a27f3e066a4ed4a446d428fd117f168beb (diff)
Merge branch 'topic/jack' into for-next
-rw-r--r--Documentation/sound/alsa/Jack-Controls.txt43
-rw-r--r--include/sound/control.h2
-rw-r--r--include/sound/jack.h13
-rw-r--r--sound/core/Kconfig3
-rw-r--r--sound/core/Makefile3
-rw-r--r--sound/core/ctljack.c41
-rw-r--r--sound/core/jack.c133
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/hda_jack.c90
-rw-r--r--sound/pci/hda/hda_jack.h5
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c2
-rw-r--r--sound/soc/soc-jack.c3
13 files changed, 242 insertions, 100 deletions
diff --git a/Documentation/sound/alsa/Jack-Controls.txt b/Documentation/sound/alsa/Jack-Controls.txt
new file mode 100644
index 000000000000..fe1c5e0c8555
--- /dev/null
+++ b/Documentation/sound/alsa/Jack-Controls.txt
@@ -0,0 +1,43 @@
1Why we need Jack kcontrols
2==========================
3
4ALSA uses kcontrols to export audio controls(switch, volume, Mux, ...)
5to user space. This means userspace applications like pulseaudio can
6switch off headphones and switch on speakers when no headphones are
7pluged in.
8
9The old ALSA jack code only created input devices for each registered
10jack. These jack input devices are not readable by userspace devices
11that run as non root.
12
13The new jack code creates embedded jack kcontrols for each jack that
14can be read by any process.
15
16This can be combined with UCM to allow userspace to route audio more
17intelligently based on jack insertion or removal events.
18
19Jack Kcontrol Internals
20=======================
21
22Each jack will have a kcontrol list, so that we can create a kcontrol
23and attach it to the jack, at jack creation stage. We can also add a
24kcontrol to an existing jack, at anytime when required.
25
26Those kcontrols will be freed automatically when the Jack is freed.
27
28How to use jack kcontrols
29=========================
30
31In order to keep compatibility, snd_jack_new() has been modified by
32adding two params :-
33
34 - @initial_kctl: if true, create a kcontrol and add it to the jack
35 list.
36 - @phantom_jack: Don't create a input device for phantom jacks.
37
38HDA jacks can set phantom_jack to true in order to create a phantom
39jack and set initial_kctl to true to create an initial kcontrol with
40the correct id.
41
42ASoC jacks should set initial_kctl as false. The pin name will be
43assigned as the jack kcontrol name.
diff --git a/include/sound/control.h b/include/sound/control.h
index 95aad6d3fd1a..21d047f229a1 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);
252 * Helper functions for jack-detection controls 252 * Helper functions for jack-detection controls
253 */ 253 */
254struct snd_kcontrol * 254struct snd_kcontrol *
255snd_kctl_jack_new(const char *name, int idx, void *private_data); 255snd_kctl_jack_new(const char *name, struct snd_card *card);
256void snd_kctl_jack_report(struct snd_card *card, 256void snd_kctl_jack_report(struct snd_card *card,
257 struct snd_kcontrol *kctl, bool status); 257 struct snd_kcontrol *kctl, bool status);
258 258
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 218235030ebc..23bede121c78 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;
@@ -85,7 +87,8 @@ struct snd_jack {
85#ifdef CONFIG_SND_JACK 87#ifdef CONFIG_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, bool initial_kctl, bool phantom_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,9 +96,13 @@ 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, bool initial_kctl, bool phantom_jack)
101{
102 return 0;
103}
104
105static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
99{ 106{
100 return 0; 107 return 0;
101} 108}
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 ae1d32b084fd..7dd17a365269 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -11,8 +11,7 @@ endif
11snd-$(CONFIG_ISA_DMA_API) += isadma.o 11snd-$(CONFIG_ISA_DMA_API) += isadma.o
12snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o 12snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o
13snd-$(CONFIG_SND_VMASTER) += vmaster.o 13snd-$(CONFIG_SND_VMASTER) += vmaster.o
14snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o 14snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
15snd-$(CONFIG_SND_JACK) += jack.o
16 15
17snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ 16snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
18 pcm_memory.o memalloc.o 17 pcm_memory.o memalloc.o
diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c
index e4b38fbe51da..8f8d1033425c 100644
--- a/sound/core/ctljack.c
+++ b/sound/core/ctljack.c
@@ -31,19 +31,49 @@ static struct snd_kcontrol_new jack_detect_kctl = {
31 .get = jack_detect_kctl_get, 31 .get = jack_detect_kctl_get,
32}; 32};
33 33
34static int get_available_index(struct snd_card *card, const char *name)
35{
36 struct snd_ctl_elem_id sid;
37
38 memset(&sid, 0, sizeof(sid));
39
40 sid.index = 0;
41 sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
42 strlcpy(sid.name, name, sizeof(sid.name));
43
44 while (snd_ctl_find_id(card, &sid))
45 sid.index++;
46
47 return sid.index;
48}
49
50static void jack_kctl_name_gen(char *name, const char *src_name, int size)
51{
52 size_t count = strlen(src_name);
53 bool need_cat = true;
54
55 /* remove redundant " Jack" from src_name */
56 if (count >= 5)
57 need_cat = strncmp(&src_name[count - 5], " Jack", 5) ? true : false;
58
59 snprintf(name, size, need_cat ? "%s Jack" : "%s", src_name);
60
61}
62
34struct snd_kcontrol * 63struct snd_kcontrol *
35snd_kctl_jack_new(const char *name, int idx, void *private_data) 64snd_kctl_jack_new(const char *name, struct snd_card *card)
36{ 65{
37 struct snd_kcontrol *kctl; 66 struct snd_kcontrol *kctl;
38 kctl = snd_ctl_new1(&jack_detect_kctl, private_data); 67
68 kctl = snd_ctl_new1(&jack_detect_kctl, NULL);
39 if (!kctl) 69 if (!kctl)
40 return NULL; 70 return NULL;
41 snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name); 71
42 kctl->id.index = idx; 72 jack_kctl_name_gen(kctl->id.name, name, sizeof(kctl->id.name));
73 kctl->id.index = get_available_index(card, name);
43 kctl->private_value = 0; 74 kctl->private_value = 0;
44 return kctl; 75 return kctl;
45} 76}
46EXPORT_SYMBOL_GPL(snd_kctl_jack_new);
47 77
48void snd_kctl_jack_report(struct snd_card *card, 78void snd_kctl_jack_report(struct snd_card *card,
49 struct snd_kcontrol *kctl, bool status) 79 struct snd_kcontrol *kctl, bool status)
@@ -53,4 +83,3 @@ void snd_kctl_jack_report(struct snd_card *card,
53 kctl->private_value = status; 83 kctl->private_value = status;
54 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); 84 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
55} 85}
56EXPORT_SYMBOL_GPL(snd_kctl_jack_report);
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 8658578eb584..e8b51f52e7df 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, 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
@@ -107,6 +191,8 @@ static int snd_jack_dev_register(struct snd_device *device)
107 * @type: a bitmask of enum snd_jack_type values that can be detected by 191 * @type: a bitmask of enum snd_jack_type values that can be detected by
108 * this jack 192 * this jack
109 * @jjack: Used to provide the allocated jack object to the caller. 193 * @jjack: Used to provide the allocated jack object to the caller.
194 * @initial_kctl: if true, create a kcontrol and add it to the jack list.
195 * @phantom_jack: Don't create a input device for phantom jacks.
110 * 196 *
111 * Creates a new jack object. 197 * Creates a new jack object.
112 * 198 *
@@ -114,9 +200,10 @@ static int snd_jack_dev_register(struct snd_device *device)
114 * On success @jjack will be initialised. 200 * On success @jjack will be initialised.
115 */ 201 */
116int snd_jack_new(struct snd_card *card, const char *id, int type, 202int snd_jack_new(struct snd_card *card, const char *id, int type,
117 struct snd_jack **jjack) 203 struct snd_jack **jjack, bool initial_kctl, bool phantom_jack)
118{ 204{
119 struct snd_jack *jack; 205 struct snd_jack *jack;
206 struct snd_jack_kctl *jack_kctl = NULL;
120 int err; 207 int err;
121 int i; 208 int i;
122 static struct snd_device_ops ops = { 209 static struct snd_device_ops ops = {
@@ -125,31 +212,47 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
125 .dev_disconnect = snd_jack_dev_disconnect, 212 .dev_disconnect = snd_jack_dev_disconnect,
126 }; 213 };
127 214
215 if (initial_kctl) {
216 jack_kctl = snd_jack_kctl_new(card, id, type);
217 if (!jack_kctl)
218 return -ENOMEM;
219 }
220
128 jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL); 221 jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
129 if (jack == NULL) 222 if (jack == NULL)
130 return -ENOMEM; 223 return -ENOMEM;
131 224
132 jack->id = kstrdup(id, GFP_KERNEL); 225 jack->id = kstrdup(id, GFP_KERNEL);
133 226
134 jack->input_dev = input_allocate_device(); 227 /* don't creat input device for phantom jack */
135 if (jack->input_dev == NULL) { 228 if (!phantom_jack) {
136 err = -ENOMEM; 229 jack->input_dev = input_allocate_device();
137 goto fail_input; 230 if (jack->input_dev == NULL) {
138 } 231 err = -ENOMEM;
232 goto fail_input;
233 }
139 234
140 jack->input_dev->phys = "ALSA"; 235 jack->input_dev->phys = "ALSA";
141 236
142 jack->type = type; 237 jack->type = type;
143 238
144 for (i = 0; i < SND_JACK_SWITCH_TYPES; i++) 239 for (i = 0; i < SND_JACK_SWITCH_TYPES; i++)
145 if (type & (1 << i)) 240 if (type & (1 << i))
146 input_set_capability(jack->input_dev, EV_SW, 241 input_set_capability(jack->input_dev, EV_SW,
147 jack_switch_types[i]); 242 jack_switch_types[i]);
243
244 }
148 245
149 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 246 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
150 if (err < 0) 247 if (err < 0)
151 goto fail_input; 248 goto fail_input;
152 249
250 jack->card = card;
251 INIT_LIST_HEAD(&jack->kctl_list);
252
253 if (initial_kctl)
254 snd_jack_kctl_add(jack, jack_kctl);
255
153 *jjack = jack; 256 *jjack = jack;
154 257
155 return 0; 258 return 0;
@@ -230,6 +333,7 @@ EXPORT_SYMBOL(snd_jack_set_key);
230 */ 333 */
231void snd_jack_report(struct snd_jack *jack, int status) 334void snd_jack_report(struct snd_jack *jack, int status)
232{ 335{
336 struct snd_jack_kctl *jack_kctl;
233 int i; 337 int i;
234 338
235 if (!jack) 339 if (!jack)
@@ -252,6 +356,11 @@ void snd_jack_report(struct snd_jack *jack, int status)
252 } 356 }
253 357
254 input_sync(jack->input_dev); 358 input_sync(jack->input_dev);
359
360 list_for_each_entry(jack_kctl, &jack->kctl_list, list)
361 snd_kctl_jack_report(jack->card, jack_kctl->kctl,
362 status & jack_kctl->mask_bits);
363
255} 364}
256EXPORT_SYMBOL(snd_jack_report); 365EXPORT_SYMBOL(snd_jack_report);
257 366
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 47aa7b8b7519..5c296d30729c 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
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index d7cfe7b8c32b..366efbf87d41 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -132,11 +132,11 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
132 132
133 for (i = 0; i < codec->jacktbl.used; i++, jack++) { 133 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
134 struct hda_jack_callback *cb, *next; 134 struct hda_jack_callback *cb, *next;
135#ifdef CONFIG_SND_HDA_INPUT_JACK 135
136 /* free jack instances manually when clearing/reconfiguring */ 136 /* free jack instances manually when clearing/reconfiguring */
137 if (!codec->bus->shutdown && jack->jack) 137 if (!codec->bus->shutdown && jack->jack)
138 snd_device_free(codec->card, jack->jack); 138 snd_device_free(codec->card, jack->jack);
139#endif 139
140 for (cb = jack->callback; cb; cb = next) { 140 for (cb = jack->callback; cb; cb = next) {
141 next = cb->next; 141 next = cb->next;
142 kfree(cb); 142 kfree(cb);
@@ -337,20 +337,15 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
337 jack = codec->jacktbl.list; 337 jack = codec->jacktbl.list;
338 for (i = 0; i < codec->jacktbl.used; i++, jack++) 338 for (i = 0; i < codec->jacktbl.used; i++, jack++)
339 if (jack->nid) { 339 if (jack->nid) {
340 if (!jack->kctl || jack->block_report) 340 if (!jack->jack || jack->block_report)
341 continue; 341 continue;
342 state = get_jack_plug_state(jack->pin_sense); 342 state = get_jack_plug_state(jack->pin_sense);
343 snd_kctl_jack_report(codec->card, jack->kctl, state); 343 snd_jack_report(jack->jack,
344#ifdef CONFIG_SND_HDA_INPUT_JACK 344 state ? jack->type : 0);
345 if (jack->jack)
346 snd_jack_report(jack->jack,
347 state ? jack->type : 0);
348#endif
349 } 345 }
350} 346}
351EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync); 347EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
352 348
353#ifdef CONFIG_SND_HDA_INPUT_JACK
354/* guess the jack type from the pin-config */ 349/* guess the jack type from the pin-config */
355static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid) 350static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid)
356{ 351{
@@ -377,54 +372,42 @@ static void hda_free_jack_priv(struct snd_jack *jack)
377 jacks->nid = 0; 372 jacks->nid = 0;
378 jacks->jack = NULL; 373 jacks->jack = NULL;
379} 374}
380#endif
381 375
382/** 376/**
383 * snd_hda_jack_add_kctl - Add a kctl for the given pin 377 * snd_hda_jack_add_kctl - Add a kctl for the given pin
384 * @codec: the HDA codec 378 * @codec: the HDA codec
385 * @nid: pin NID to assign 379 * @nid: pin NID to assign
386 * @name: string name for the jack 380 * @name: string name for the jack
387 * @idx: index number for the jack
388 * @phantom_jack: flag to deal as a phantom jack 381 * @phantom_jack: flag to deal as a phantom jack
389 * 382 *
390 * This assigns a jack-detection kctl to the given pin. The kcontrol 383 * This assigns a jack-detection kctl to the given pin. The kcontrol
391 * will have the given name and index. 384 * will have the given name and index.
392 */ 385 */
393static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 386static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
394 const char *name, int idx, bool phantom_jack) 387 const char *name, bool phantom_jack)
395{ 388{
396 struct hda_jack_tbl *jack; 389 struct hda_jack_tbl *jack;
397 struct snd_kcontrol *kctl; 390 int err, state, type;
398 int err, state;
399 391
400 jack = snd_hda_jack_tbl_new(codec, nid); 392 jack = snd_hda_jack_tbl_new(codec, nid);
401 if (!jack) 393 if (!jack)
402 return 0; 394 return 0;
403 if (jack->kctl) 395 if (jack->jack)
404 return 0; /* already created */ 396 return 0; /* already created */
405 kctl = snd_kctl_jack_new(name, idx, codec); 397
406 if (!kctl) 398 type = get_input_jack_type(codec, nid);
407 return -ENOMEM; 399 err = snd_jack_new(codec->card, name, type,
408 err = snd_hda_ctl_add(codec, nid, kctl); 400 &jack->jack, true, phantom_jack);
409 if (err < 0) 401 if (err < 0)
410 return err; 402 return err;
411 jack->kctl = kctl;
412 jack->phantom_jack = !!phantom_jack;
413 403
404 jack->phantom_jack = !!phantom_jack;
405 jack->type = type;
406 jack->jack->private_data = jack;
407 jack->jack->private_free = hda_free_jack_priv;
414 state = snd_hda_jack_detect(codec, nid); 408 state = snd_hda_jack_detect(codec, nid);
415 snd_kctl_jack_report(codec->card, kctl, state); 409 snd_jack_report(jack->jack, state ? jack->type : 0);
416#ifdef CONFIG_SND_HDA_INPUT_JACK 410
417 if (!phantom_jack) {
418 jack->type = get_input_jack_type(codec, nid);
419 err = snd_jack_new(codec->card, name, jack->type,
420 &jack->jack);
421 if (err < 0)
422 return err;
423 jack->jack->private_data = jack;
424 jack->jack->private_free = hda_free_jack_priv;
425 snd_jack_report(jack->jack, state ? jack->type : 0);
426 }
427#endif
428 return 0; 411 return 0;
429} 412}
430 413
@@ -433,44 +416,23 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
433 * @codec: the HDA codec 416 * @codec: the HDA codec
434 * @nid: pin NID 417 * @nid: pin NID
435 * @name: the name string for the jack ctl 418 * @name: the name string for the jack ctl
436 * @idx: the ctl index for the jack ctl
437 * 419 *
438 * This is a simple helper calling __snd_hda_jack_add_kctl(). 420 * This is a simple helper calling __snd_hda_jack_add_kctl().
439 */ 421 */
440int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 422int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
441 const char *name, int idx) 423 const char *name)
442{ 424{
443 return __snd_hda_jack_add_kctl(codec, nid, name, idx, false); 425 return __snd_hda_jack_add_kctl(codec, nid, name, false);
444} 426}
445EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl); 427EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
446 428
447/* get the unique index number for the given kctl name */
448static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
449{
450 struct hda_jack_tbl *jack;
451 int i, len = strlen(name);
452 again:
453 jack = codec->jacktbl.list;
454 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
455 /* jack->kctl.id contains "XXX Jack" name string with index */
456 if (jack->kctl &&
457 !strncmp(name, jack->kctl->id.name, len) &&
458 !strcmp(" Jack", jack->kctl->id.name + len) &&
459 jack->kctl->id.index == idx) {
460 idx++;
461 goto again;
462 }
463 }
464 return idx;
465}
466
467static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 429static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
468 const struct auto_pin_cfg *cfg, 430 const struct auto_pin_cfg *cfg,
469 const char *base_name) 431 const char *base_name)
470{ 432{
471 unsigned int def_conf, conn; 433 unsigned int def_conf, conn;
472 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 434 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
473 int idx, err; 435 int err;
474 bool phantom_jack; 436 bool phantom_jack;
475 437
476 if (!nid) 438 if (!nid)
@@ -482,16 +444,14 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
482 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || 444 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
483 !is_jack_detectable(codec, nid); 445 !is_jack_detectable(codec, nid);
484 446
485 if (base_name) { 447 if (base_name)
486 strlcpy(name, base_name, sizeof(name)); 448 strlcpy(name, base_name, sizeof(name));
487 idx = 0; 449 else
488 } else 450 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL);
489 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
490 if (phantom_jack) 451 if (phantom_jack)
491 /* Example final name: "Internal Mic Phantom Jack" */ 452 /* Example final name: "Internal Mic Phantom Jack" */
492 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); 453 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
493 idx = get_unique_index(codec, name, idx); 454 err = __snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
494 err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
495 if (err < 0) 455 if (err < 0)
496 return err; 456 return err;
497 457
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index b279e327a23b..387d30984dfe 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -39,11 +39,8 @@ struct hda_jack_tbl {
39 unsigned int block_report:1; /* in a transitional state - do not report to userspace */ 39 unsigned int block_report:1; /* in a transitional state - do not report to userspace */
40 hda_nid_t gating_jack; /* valid when gating jack plugged */ 40 hda_nid_t gating_jack; /* valid when gating jack plugged */
41 hda_nid_t gated_jack; /* gated is dependent on this jack */ 41 hda_nid_t gated_jack; /* gated is dependent on this jack */
42 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
43#ifdef CONFIG_SND_HDA_INPUT_JACK
44 int type; 42 int type;
45 struct snd_jack *jack; 43 struct snd_jack *jack;
46#endif
47}; 44};
48 45
49struct hda_jack_tbl * 46struct hda_jack_tbl *
@@ -85,7 +82,7 @@ static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
85bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 82bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
86 83
87int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 84int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
88 const char *name, int idx); 85 const char *name);
89int snd_hda_jack_add_kctls(struct hda_codec *codec, 86int snd_hda_jack_add_kctls(struct hda_codec *codec,
90 const struct auto_pin_cfg *cfg); 87 const struct auto_pin_cfg *cfg);
91 88
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 6e7e0b85c3e3..d925742624ee 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2081,7 +2081,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
2081 strncat(hdmi_str, " Phantom", 2081 strncat(hdmi_str, " Phantom",
2082 sizeof(hdmi_str) - strlen(hdmi_str) - 1); 2082 sizeof(hdmi_str) - strlen(hdmi_str) - 1);
2083 2083
2084 return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0); 2084 return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str);
2085} 2085}
2086 2086
2087static int generic_hdmi_build_controls(struct hda_codec *codec) 2087static int generic_hdmi_build_controls(struct hda_codec *codec)
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 6ce68604c25e..90ac479f389f 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -286,7 +286,7 @@ static void xonar_ds_init(struct oxygen *chip)
286 xonar_enable_output(chip); 286 xonar_enable_output(chip);
287 287
288 snd_jack_new(chip->card, "Headphone", 288 snd_jack_new(chip->card, "Headphone",
289 SND_JACK_HEADPHONE, &data->hp_jack); 289 SND_JACK_HEADPHONE, &data->hp_jack, false, false);
290 xonar_ds_handle_hp_jack(chip); 290 xonar_ds_handle_hp_jack(chip);
291 291
292 snd_component_add(chip->card, "WM8776"); 292 snd_component_add(chip->card, "WM8776");
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 9f60c25c4568..87ca9806f3ee 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -48,7 +48,7 @@ int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
48 INIT_LIST_HEAD(&jack->jack_zones); 48 INIT_LIST_HEAD(&jack->jack_zones);
49 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 49 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
50 50
51 ret = snd_jack_new(card->snd_card, id, type, &jack->jack); 51 ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false);
52 if (ret) 52 if (ret)
53 return ret; 53 return ret;
54 54
@@ -197,6 +197,7 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
197 197
198 INIT_LIST_HEAD(&pins[i].list); 198 INIT_LIST_HEAD(&pins[i].list);
199 list_add(&(pins[i].list), &jack->pins); 199 list_add(&(pins[i].list), &jack->pins);
200 snd_jack_add_new_kctl(jack->jack, pins[i].pin, pins[i].mask);
200 } 201 }
201 202
202 /* Update to reflect the last reported status; canned jack 203 /* Update to reflect the last reported status; canned jack