diff options
-rw-r--r-- | sound/pci/hda/hda_jack.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 60c976f06280..aaccc0236bda 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -314,9 +314,28 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
314 | } | 314 | } |
315 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 315 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
316 | 316 | ||
317 | /* get the unique index number for the given kctl name */ | ||
318 | static 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 | |||
317 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 337 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
318 | const struct auto_pin_cfg *cfg, | 338 | const struct auto_pin_cfg *cfg) |
319 | char *lastname, int *lastidx) | ||
320 | { | 339 | { |
321 | unsigned int def_conf, conn; | 340 | unsigned int def_conf, conn; |
322 | char name[44]; | 341 | char name[44]; |
@@ -336,10 +355,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
336 | if (phantom_jack) | 355 | if (phantom_jack) |
337 | /* Example final name: "Internal Mic Phantom Jack" */ | 356 | /* Example final name: "Internal Mic Phantom Jack" */ |
338 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); | 357 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); |
339 | if (!strcmp(name, lastname) && idx == *lastidx) | 358 | idx = get_unique_index(codec, name, idx); |
340 | idx++; | ||
341 | strncpy(lastname, name, sizeof(name)); | ||
342 | *lastidx = idx; | ||
343 | err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack); | 359 | err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack); |
344 | if (err < 0) | 360 | if (err < 0) |
345 | return err; | 361 | return err; |
@@ -356,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
356 | const struct auto_pin_cfg *cfg) | 372 | const struct auto_pin_cfg *cfg) |
357 | { | 373 | { |
358 | const hda_nid_t *p; | 374 | const hda_nid_t *p; |
359 | int i, err, lastidx = 0; | 375 | int i, err; |
360 | char lastname[44] = ""; | ||
361 | 376 | ||
362 | 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++) { |
363 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 378 | err = add_jack_kctl(codec, *p, cfg); |
364 | if (err < 0) | 379 | if (err < 0) |
365 | return err; | 380 | return err; |
366 | } | 381 | } |
367 | 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++) { |
368 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 383 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
369 | break; | 384 | break; |
370 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 385 | err = add_jack_kctl(codec, *p, cfg); |
371 | if (err < 0) | 386 | if (err < 0) |
372 | return err; | 387 | return err; |
373 | } | 388 | } |
374 | 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++) { |
375 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 390 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
376 | break; | 391 | break; |
377 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 392 | err = add_jack_kctl(codec, *p, cfg); |
378 | if (err < 0) | 393 | if (err < 0) |
379 | return err; | 394 | return err; |
380 | } | 395 | } |
381 | for (i = 0; i < cfg->num_inputs; i++) { | 396 | for (i = 0; i < cfg->num_inputs; i++) { |
382 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); | 397 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); |
383 | if (err < 0) | 398 | if (err < 0) |
384 | return err; | 399 | return err; |
385 | } | 400 | } |
386 | 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++) { |
387 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 402 | err = add_jack_kctl(codec, *p, cfg); |
388 | if (err < 0) | 403 | if (err < 0) |
389 | return err; | 404 | return err; |
390 | } | 405 | } |
391 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); | 406 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); |
392 | if (err < 0) | 407 | if (err < 0) |
393 | return err; | 408 | return err; |
394 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); | 409 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); |
395 | if (err < 0) | 410 | if (err < 0) |
396 | return err; | 411 | return err; |
397 | return 0; | 412 | return 0; |