aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2012-06-04 03:33:51 -0400
committerTakashi Iwai <tiwai@suse.de>2012-06-14 06:59:35 -0400
commit80c8bfbe76869bfd6bdf3d260d316e7a32f318c3 (patch)
treee7b2634839fb7f698d1124a7b4d7a66065f5891a /sound/pci/hda
parent3de5ff88773d9f106b668937da2f36c97801b332 (diff)
ALSA: HDA: Create phantom jacks for fixed inputs and outputs
PulseAudio sometimes have difficulties knowing that there is a "Speaker" or "Internal Mic", if they have no individual volume controls or selectors. As a result, only e g "Headphone" might be created for a laptop, but no "Speaker". To help out, create phantom jacks (that are always present, at least for now) for "Speaker", "Internal Mic" etc, in case we detect them. The naming convention is e g "Speaker Phantom Jack". In order not to pollute the /dev/input namespace with even more devices, these are added to the kcontrols only, not the input devices. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_jack.c59
-rw-r--r--sound/pci/hda/hda_jack.h1
2 files changed, 42 insertions, 18 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 2dd1c113a4c1..60c976f06280 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
127static void jack_detect_update(struct hda_codec *codec, 127static void jack_detect_update(struct hda_codec *codec,
128 struct hda_jack_tbl *jack) 128 struct hda_jack_tbl *jack)
129{ 129{
130 if (jack->jack_dirty || !jack->jack_detect) { 130 if (!jack->jack_dirty)
131 return;
132
133 if (jack->phantom_jack)
134 jack->pin_sense = AC_PINSENSE_PRESENCE;
135 else
131 jack->pin_sense = read_pin_sense(codec, jack->nid); 136 jack->pin_sense = read_pin_sense(codec, jack->nid);
132 jack->jack_dirty = 0; 137
133 } 138 jack->jack_dirty = 0;
134} 139}
135 140
136/** 141/**
@@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack)
264 * This assigns a jack-detection kctl to the given pin. The kcontrol 269 * This assigns a jack-detection kctl to the given pin. The kcontrol
265 * will have the given name and index. 270 * will have the given name and index.
266 */ 271 */
267int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 272static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
268 const char *name, int idx) 273 const char *name, int idx, bool phantom_jack)
269{ 274{
270 struct hda_jack_tbl *jack; 275 struct hda_jack_tbl *jack;
271 struct snd_kcontrol *kctl; 276 struct snd_kcontrol *kctl;
@@ -283,19 +288,30 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
283 if (err < 0) 288 if (err < 0)
284 return err; 289 return err;
285 jack->kctl = kctl; 290 jack->kctl = kctl;
291 jack->phantom_jack = !!phantom_jack;
292
286 state = snd_hda_jack_detect(codec, nid); 293 state = snd_hda_jack_detect(codec, nid);
287 snd_kctl_jack_report(codec->bus->card, kctl, state); 294 snd_kctl_jack_report(codec->bus->card, kctl, state);
288#ifdef CONFIG_SND_HDA_INPUT_JACK 295#ifdef CONFIG_SND_HDA_INPUT_JACK
289 jack->type = get_input_jack_type(codec, nid); 296 if (!phantom_jack) {
290 err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); 297 jack->type = get_input_jack_type(codec, nid);
291 if (err < 0) 298 err = snd_jack_new(codec->bus->card, name, jack->type,
292 return err; 299 &jack->jack);
293 jack->jack->private_data = jack; 300 if (err < 0)
294 jack->jack->private_free = hda_free_jack_priv; 301 return err;
295 snd_jack_report(jack->jack, state ? jack->type : 0); 302 jack->jack->private_data = jack;
303 jack->jack->private_free = hda_free_jack_priv;
304 snd_jack_report(jack->jack, state ? jack->type : 0);
305 }
296#endif 306#endif
297 return 0; 307 return 0;
298} 308}
309
310int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
311 const char *name, int idx)
312{
313 return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
314}
299EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 315EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
300 316
301static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 317static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
@@ -305,25 +321,32 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
305 unsigned int def_conf, conn; 321 unsigned int def_conf, conn;
306 char name[44]; 322 char name[44];
307 int idx, err; 323 int idx, err;
324 bool phantom_jack;
308 325
309 if (!nid) 326 if (!nid)
310 return 0; 327 return 0;
311 if (!is_jack_detectable(codec, nid))
312 return 0;
313 def_conf = snd_hda_codec_get_pincfg(codec, nid); 328 def_conf = snd_hda_codec_get_pincfg(codec, nid);
314 conn = get_defcfg_connect(def_conf); 329 conn = get_defcfg_connect(def_conf);
315 if (conn != AC_JACK_PORT_COMPLEX) 330 if (conn == AC_JACK_PORT_NONE)
316 return 0; 331 return 0;
332 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
333 !is_jack_detectable(codec, nid);
317 334
318 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 335 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
336 if (phantom_jack)
337 /* Example final name: "Internal Mic Phantom Jack" */
338 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
319 if (!strcmp(name, lastname) && idx == *lastidx) 339 if (!strcmp(name, lastname) && idx == *lastidx)
320 idx++; 340 idx++;
321 strncpy(lastname, name, 44); 341 strncpy(lastname, name, sizeof(name));
322 *lastidx = idx; 342 *lastidx = idx;
323 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 343 err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
324 if (err < 0) 344 if (err < 0)
325 return err; 345 return err;
326 return snd_hda_jack_detect_enable(codec, nid, 0); 346
347 if (!phantom_jack)
348 return snd_hda_jack_detect_enable(codec, nid, 0);
349 return 0;
327} 350}
328 351
329/** 352/**
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 8ae52465ec5d..a9803da633c0 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -23,6 +23,7 @@ struct hda_jack_tbl {
23 unsigned int pin_sense; /* cached pin-sense value */ 23 unsigned int pin_sense; /* cached pin-sense value */
24 unsigned int jack_detect:1; /* capable of jack-detection? */ 24 unsigned int jack_detect:1; /* capable of jack-detection? */
25 unsigned int jack_dirty:1; /* needs to update? */ 25 unsigned int jack_dirty:1; /* needs to update? */
26 unsigned int phantom_jack:1; /* a fixed, always present port? */
26 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ 27 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
27#ifdef CONFIG_SND_HDA_INPUT_JACK 28#ifdef CONFIG_SND_HDA_INPUT_JACK
28 int type; 29 int type;