aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c13
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_hwdep.c67
-rw-r--r--sound/pci/hda/patch_sigmatel.c5
4 files changed, 65 insertions, 21 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0a531f2f9255..b28e4031b8a1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1086,9 +1086,16 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
1086 struct hda_pincfg *pin; 1086 struct hda_pincfg *pin;
1087 1087
1088#ifdef CONFIG_SND_HDA_HWDEP 1088#ifdef CONFIG_SND_HDA_HWDEP
1089 pin = look_up_pincfg(codec, &codec->user_pins, nid); 1089 {
1090 if (pin) 1090 unsigned int cfg = 0;
1091 return pin->cfg; 1091 mutex_lock(&codec->user_mutex);
1092 pin = look_up_pincfg(codec, &codec->user_pins, nid);
1093 if (pin)
1094 cfg = pin->cfg;
1095 mutex_unlock(&codec->user_mutex);
1096 if (cfg)
1097 return cfg;
1098 }
1092#endif 1099#endif
1093 pin = look_up_pincfg(codec, &codec->driver_pins, nid); 1100 pin = look_up_pincfg(codec, &codec->driver_pins, nid);
1094 if (pin) 1101 if (pin)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 4c4f1660e654..61085b311059 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -845,6 +845,7 @@ struct hda_codec {
845 struct snd_array cvt_setups; /* audio convert setups */ 845 struct snd_array cvt_setups; /* audio convert setups */
846 846
847#ifdef CONFIG_SND_HDA_HWDEP 847#ifdef CONFIG_SND_HDA_HWDEP
848 struct mutex user_mutex;
848 struct snd_hwdep *hwdep; /* assigned hwdep device */ 849 struct snd_hwdep *hwdep; /* assigned hwdep device */
849 struct snd_array init_verbs; /* additional init verbs */ 850 struct snd_array init_verbs; /* additional init verbs */
850 struct snd_array hints; /* additional hints */ 851 struct snd_array hints; /* additional hints */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index a5c9411bb367..2dddf7fbebcc 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -148,6 +148,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
148 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; 148 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
149#endif 149#endif
150 150
151 mutex_init(&codec->user_mutex);
151 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32); 152 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
152 snd_array_init(&codec->hints, sizeof(struct hda_hint), 32); 153 snd_array_init(&codec->hints, sizeof(struct hda_hint), 32);
153 snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16); 154 snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16);
@@ -346,12 +347,14 @@ static ssize_t init_verbs_show(struct device *dev,
346 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 347 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
347 struct hda_codec *codec = hwdep->private_data; 348 struct hda_codec *codec = hwdep->private_data;
348 int i, len = 0; 349 int i, len = 0;
350 mutex_lock(&codec->user_mutex);
349 for (i = 0; i < codec->init_verbs.used; i++) { 351 for (i = 0; i < codec->init_verbs.used; i++) {
350 struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); 352 struct hda_verb *v = snd_array_elem(&codec->init_verbs, i);
351 len += snprintf(buf + len, PAGE_SIZE - len, 353 len += snprintf(buf + len, PAGE_SIZE - len,
352 "0x%02x 0x%03x 0x%04x\n", 354 "0x%02x 0x%03x 0x%04x\n",
353 v->nid, v->verb, v->param); 355 v->nid, v->verb, v->param);
354 } 356 }
357 mutex_unlock(&codec->user_mutex);
355 return len; 358 return len;
356} 359}
357 360
@@ -364,12 +367,16 @@ static int parse_init_verbs(struct hda_codec *codec, const char *buf)
364 return -EINVAL; 367 return -EINVAL;
365 if (!nid || !verb) 368 if (!nid || !verb)
366 return -EINVAL; 369 return -EINVAL;
370 mutex_lock(&codec->user_mutex);
367 v = snd_array_new(&codec->init_verbs); 371 v = snd_array_new(&codec->init_verbs);
368 if (!v) 372 if (!v) {
373 mutex_unlock(&codec->user_mutex);
369 return -ENOMEM; 374 return -ENOMEM;
375 }
370 v->nid = nid; 376 v->nid = nid;
371 v->verb = verb; 377 v->verb = verb;
372 v->param = param; 378 v->param = param;
379 mutex_unlock(&codec->user_mutex);
373 return 0; 380 return 0;
374} 381}
375 382
@@ -392,11 +399,13 @@ static ssize_t hints_show(struct device *dev,
392 struct snd_hwdep *hwdep = dev_get_drvdata(dev); 399 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
393 struct hda_codec *codec = hwdep->private_data; 400 struct hda_codec *codec = hwdep->private_data;
394 int i, len = 0; 401 int i, len = 0;
402 mutex_lock(&codec->user_mutex);
395 for (i = 0; i < codec->hints.used; i++) { 403 for (i = 0; i < codec->hints.used; i++) {
396 struct hda_hint *hint = snd_array_elem(&codec->hints, i); 404 struct hda_hint *hint = snd_array_elem(&codec->hints, i);
397 len += snprintf(buf + len, PAGE_SIZE - len, 405 len += snprintf(buf + len, PAGE_SIZE - len,
398 "%s = %s\n", hint->key, hint->val); 406 "%s = %s\n", hint->key, hint->val);
399 } 407 }
408 mutex_unlock(&codec->user_mutex);
400 return len; 409 return len;
401} 410}
402 411
@@ -431,6 +440,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)
431{ 440{
432 char *key, *val; 441 char *key, *val;
433 struct hda_hint *hint; 442 struct hda_hint *hint;
443 int err = 0;
434 444
435 buf = skip_spaces(buf); 445 buf = skip_spaces(buf);
436 if (!*buf || *buf == '#' || *buf == '\n') 446 if (!*buf || *buf == '#' || *buf == '\n')
@@ -450,26 +460,31 @@ static int parse_hints(struct hda_codec *codec, const char *buf)
450 val = skip_spaces(val); 460 val = skip_spaces(val);
451 remove_trail_spaces(key); 461 remove_trail_spaces(key);
452 remove_trail_spaces(val); 462 remove_trail_spaces(val);
463 mutex_lock(&codec->user_mutex);
453 hint = get_hint(codec, key); 464 hint = get_hint(codec, key);
454 if (hint) { 465 if (hint) {
455 /* replace */ 466 /* replace */
456 kfree(hint->key); 467 kfree(hint->key);
457 hint->key = key; 468 hint->key = key;
458 hint->val = val; 469 hint->val = val;
459 return 0; 470 goto unlock;
460 } 471 }
461 /* allocate a new hint entry */ 472 /* allocate a new hint entry */
462 if (codec->hints.used >= MAX_HINTS) 473 if (codec->hints.used >= MAX_HINTS)
463 hint = NULL; 474 hint = NULL;
464 else 475 else
465 hint = snd_array_new(&codec->hints); 476 hint = snd_array_new(&codec->hints);
466 if (!hint) { 477 if (hint) {
467 kfree(key); 478 hint->key = key;
468 return -ENOMEM; 479 hint->val = val;
480 } else {
481 err = -ENOMEM;
469 } 482 }
470 hint->key = key; 483 unlock:
471 hint->val = val; 484 mutex_unlock(&codec->user_mutex);
472 return 0; 485 if (err)
486 kfree(key);
487 return err;
473} 488}
474 489
475static ssize_t hints_store(struct device *dev, 490static ssize_t hints_store(struct device *dev,
@@ -489,11 +504,13 @@ static ssize_t pin_configs_show(struct hda_codec *codec,
489 char *buf) 504 char *buf)
490{ 505{
491 int i, len = 0; 506 int i, len = 0;
507 mutex_lock(&codec->user_mutex);
492 for (i = 0; i < list->used; i++) { 508 for (i = 0; i < list->used; i++) {
493 struct hda_pincfg *pin = snd_array_elem(list, i); 509 struct hda_pincfg *pin = snd_array_elem(list, i);
494 len += sprintf(buf + len, "0x%02x 0x%08x\n", 510 len += sprintf(buf + len, "0x%02x 0x%08x\n",
495 pin->nid, pin->cfg); 511 pin->nid, pin->cfg);
496 } 512 }
513 mutex_unlock(&codec->user_mutex);
497 return len; 514 return len;
498} 515}
499 516
@@ -528,13 +545,16 @@ static ssize_t driver_pin_configs_show(struct device *dev,
528 545
529static int parse_user_pin_configs(struct hda_codec *codec, const char *buf) 546static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
530{ 547{
531 int nid, cfg; 548 int nid, cfg, err;
532 549
533 if (sscanf(buf, "%i %i", &nid, &cfg) != 2) 550 if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
534 return -EINVAL; 551 return -EINVAL;
535 if (!nid) 552 if (!nid)
536 return -EINVAL; 553 return -EINVAL;
537 return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); 554 mutex_lock(&codec->user_mutex);
555 err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
556 mutex_unlock(&codec->user_mutex);
557 return err;
538} 558}
539 559
540static ssize_t user_pin_configs_store(struct device *dev, 560static ssize_t user_pin_configs_store(struct device *dev,
@@ -600,16 +620,27 @@ EXPORT_SYMBOL_HDA(snd_hda_get_hint);
600 620
601int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) 621int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
602{ 622{
603 const char *p = snd_hda_get_hint(codec, key); 623 const char *p;
624 int ret;
625
626 mutex_lock(&codec->user_mutex);
627 p = snd_hda_get_hint(codec, key);
604 if (!p || !*p) 628 if (!p || !*p)
605 return -ENOENT; 629 ret = -ENOENT;
606 switch (toupper(*p)) { 630 else {
607 case 'T': /* true */ 631 switch (toupper(*p)) {
608 case 'Y': /* yes */ 632 case 'T': /* true */
609 case '1': 633 case 'Y': /* yes */
610 return 1; 634 case '1':
635 ret = 1;
636 break;
637 default:
638 ret = 0;
639 break;
640 }
611 } 641 }
612 return 0; 642 mutex_unlock(&codec->user_mutex);
643 return ret;
613} 644}
614EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); 645EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);
615 646
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a86547ca17c8..d3a81f10fe5c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4298,15 +4298,20 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4298static inline int get_int_hint(struct hda_codec *codec, const char *key, 4298static inline int get_int_hint(struct hda_codec *codec, const char *key,
4299 int *valp) 4299 int *valp)
4300{ 4300{
4301#ifdef CONFIG_SND_HDA_RECONFIG
4301 const char *p; 4302 const char *p;
4303 mutex_lock(&codec->user_mutex);
4302 p = snd_hda_get_hint(codec, key); 4304 p = snd_hda_get_hint(codec, key);
4303 if (p) { 4305 if (p) {
4304 unsigned long val; 4306 unsigned long val;
4305 if (!strict_strtoul(p, 0, &val)) { 4307 if (!strict_strtoul(p, 0, &val)) {
4306 *valp = val; 4308 *valp = val;
4309 mutex_unlock(&codec->user_mutex);
4307 return 1; 4310 return 1;
4308 } 4311 }
4309 } 4312 }
4313 mutex_unlock(&codec->user_mutex);
4314#endif
4310 return 0; 4315 return 0;
4311} 4316}
4312 4317