aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_jack.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_jack.c')
-rw-r--r--sound/pci/hda/hda_jack.c102
1 files changed, 70 insertions, 32 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 2dd1c113a4c1..aaccc0236bda 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,47 +288,81 @@ 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
317/* get the unique index number for the given kctl name */
318static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
319{
320 struct hda_jack_tbl *jack;
321 int i, len = strlen(name);
322 again:
323 jack = codec->jacktbl.list;
324 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
325 /* jack->kctl.id contains "XXX Jack" name string with index */
326 if (jack->kctl &&
327 !strncmp(name, jack->kctl->id.name, len) &&
328 !strcmp(" Jack", jack->kctl->id.name + len) &&
329 jack->kctl->id.index == idx) {
330 idx++;
331 goto again;
332 }
333 }
334 return idx;
335}
336
301static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 337static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
302 const struct auto_pin_cfg *cfg, 338 const struct auto_pin_cfg *cfg)
303 char *lastname, int *lastidx)
304{ 339{
305 unsigned int def_conf, conn; 340 unsigned int def_conf, conn;
306 char name[44]; 341 char name[44];
307 int idx, err; 342 int idx, err;
343 bool phantom_jack;
308 344
309 if (!nid) 345 if (!nid)
310 return 0; 346 return 0;
311 if (!is_jack_detectable(codec, nid))
312 return 0;
313 def_conf = snd_hda_codec_get_pincfg(codec, nid); 347 def_conf = snd_hda_codec_get_pincfg(codec, nid);
314 conn = get_defcfg_connect(def_conf); 348 conn = get_defcfg_connect(def_conf);
315 if (conn != AC_JACK_PORT_COMPLEX) 349 if (conn == AC_JACK_PORT_NONE)
316 return 0; 350 return 0;
351 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
352 !is_jack_detectable(codec, nid);
317 353
318 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 354 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
319 if (!strcmp(name, lastname) && idx == *lastidx) 355 if (phantom_jack)
320 idx++; 356 /* Example final name: "Internal Mic Phantom Jack" */
321 strncpy(lastname, name, 44); 357 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
322 *lastidx = idx; 358 idx = get_unique_index(codec, name, idx);
323 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 359 err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
324 if (err < 0) 360 if (err < 0)
325 return err; 361 return err;
326 return snd_hda_jack_detect_enable(codec, nid, 0); 362
363 if (!phantom_jack)
364 return snd_hda_jack_detect_enable(codec, nid, 0);
365 return 0;
327} 366}
328 367
329/** 368/**
@@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
333 const struct auto_pin_cfg *cfg) 372 const struct auto_pin_cfg *cfg)
334{ 373{
335 const hda_nid_t *p; 374 const hda_nid_t *p;
336 int i, err, lastidx = 0; 375 int i, err;
337 char lastname[44] = "";
338 376
339 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 377 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
340 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 378 err = add_jack_kctl(codec, *p, cfg);
341 if (err < 0) 379 if (err < 0)
342 return err; 380 return err;
343 } 381 }
344 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 382 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
345 if (*p == *cfg->line_out_pins) /* might be duplicated */ 383 if (*p == *cfg->line_out_pins) /* might be duplicated */
346 break; 384 break;
347 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 385 err = add_jack_kctl(codec, *p, cfg);
348 if (err < 0) 386 if (err < 0)
349 return err; 387 return err;
350 } 388 }
351 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 389 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
352 if (*p == *cfg->line_out_pins) /* might be duplicated */ 390 if (*p == *cfg->line_out_pins) /* might be duplicated */
353 break; 391 break;
354 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 392 err = add_jack_kctl(codec, *p, cfg);
355 if (err < 0) 393 if (err < 0)
356 return err; 394 return err;
357 } 395 }
358 for (i = 0; i < cfg->num_inputs; i++) { 396 for (i = 0; i < cfg->num_inputs; i++) {
359 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); 397 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
360 if (err < 0) 398 if (err < 0)
361 return err; 399 return err;
362 } 400 }
363 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 401 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
364 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 402 err = add_jack_kctl(codec, *p, cfg);
365 if (err < 0) 403 if (err < 0)
366 return err; 404 return err;
367 } 405 }
368 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); 406 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
369 if (err < 0) 407 if (err < 0)
370 return err; 408 return err;
371 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); 409 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
372 if (err < 0) 410 if (err < 0)
373 return err; 411 return err;
374 return 0; 412 return 0;