aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_jack.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-07-17 10:48:27 -0400
committerTakashi Iwai <tiwai@suse.de>2012-07-17 10:55:56 -0400
commitf46c329644b1f7144d336fce037dd9f84ee1995f (patch)
treebee07bb6db8cb77a1093bac2d07fa36d478d0e7d /sound/pci/hda/hda_jack.c
parent7ae48b56f8d9c836259bc02f3e2ea4962d6b5d1b (diff)
ALSA: hda - Fix index number conflicts of phantom jacks
Since some jack controls may be renamed as phantom jacks, the existing check for index conflicts doesn't work because it simply compares the name with the last used name, assuming that the controls with the same name continue. Thus, it would result in the duplicated controls when two or more phantom jacks with the very same type exist, and the driver gives up with an error. This patch fixes the problem by checking the index number conflicts more intensively (but dumbly). Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_jack.c')
-rw-r--r--sound/pci/hda/hda_jack.c45
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}
315EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 315EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
316 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
317static 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,
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;