aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-07-25 21:03:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-07-25 21:03:45 -0400
commit9c5502189fa00ad623aed7ff006d5c2a16b121c0 (patch)
treebde834a5225ecb60597d9fb987b8b3cc03c9d746 /sound
parent051c2a9fdebdabec594c151727ce3834ff17d793 (diff)
parenteb12f72ee7245ca207818b9efd10be2641494502 (diff)
Merge tag 'sound-3.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Here contains only the fixes for the new FireWire bebob driver. All fairly trivial and local fixes, so safe to apply" * tag 'sound-3.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: bebob: Correction for return value of special_clk_ctl_put() in error ALSA: bebob: Correction for return value of .put callback ALSA: bebob: Use different labels for digital input/output ALSA: bebob: Fix a missing to unlock mutex in error handling case
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/bebob/bebob_maudio.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c
index 6af50eb80ea7..70faa3a32526 100644
--- a/sound/firewire/bebob/bebob_maudio.c
+++ b/sound/firewire/bebob/bebob_maudio.c
@@ -379,11 +379,11 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
379 struct special_params *params = bebob->maudio_special_quirk; 379 struct special_params *params = bebob->maudio_special_quirk;
380 int err, id; 380 int err, id;
381 381
382 mutex_lock(&bebob->mutex);
383
384 id = uval->value.enumerated.item[0]; 382 id = uval->value.enumerated.item[0];
385 if (id >= ARRAY_SIZE(special_clk_labels)) 383 if (id >= ARRAY_SIZE(special_clk_labels))
386 return 0; 384 return -EINVAL;
385
386 mutex_lock(&bebob->mutex);
387 387
388 err = avc_maudio_set_special_clk(bebob, id, 388 err = avc_maudio_set_special_clk(bebob, id,
389 params->dig_in_fmt, 389 params->dig_in_fmt,
@@ -391,7 +391,10 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
391 params->clk_lock); 391 params->clk_lock);
392 mutex_unlock(&bebob->mutex); 392 mutex_unlock(&bebob->mutex);
393 393
394 return err >= 0; 394 if (err >= 0)
395 err = 1;
396
397 return err;
395} 398}
396static struct snd_kcontrol_new special_clk_ctl = { 399static struct snd_kcontrol_new special_clk_ctl = {
397 .name = "Clock Source", 400 .name = "Clock Source",
@@ -434,8 +437,8 @@ static struct snd_kcontrol_new special_sync_ctl = {
434 .get = special_sync_ctl_get, 437 .get = special_sync_ctl_get,
435}; 438};
436 439
437/* Digital interface control for special firmware */ 440/* Digital input interface control for special firmware */
438static char *const special_dig_iface_labels[] = { 441static char *const special_dig_in_iface_labels[] = {
439 "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical" 442 "S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical"
440}; 443};
441static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl, 444static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
@@ -443,13 +446,13 @@ static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
443{ 446{
444 einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 447 einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
445 einf->count = 1; 448 einf->count = 1;
446 einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels); 449 einf->value.enumerated.items = ARRAY_SIZE(special_dig_in_iface_labels);
447 450
448 if (einf->value.enumerated.item >= einf->value.enumerated.items) 451 if (einf->value.enumerated.item >= einf->value.enumerated.items)
449 einf->value.enumerated.item = einf->value.enumerated.items - 1; 452 einf->value.enumerated.item = einf->value.enumerated.items - 1;
450 453
451 strcpy(einf->value.enumerated.name, 454 strcpy(einf->value.enumerated.name,
452 special_dig_iface_labels[einf->value.enumerated.item]); 455 special_dig_in_iface_labels[einf->value.enumerated.item]);
453 456
454 return 0; 457 return 0;
455} 458}
@@ -491,26 +494,36 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
491 unsigned int id, dig_in_fmt, dig_in_iface; 494 unsigned int id, dig_in_fmt, dig_in_iface;
492 int err; 495 int err;
493 496
494 mutex_lock(&bebob->mutex);
495
496 id = uval->value.enumerated.item[0]; 497 id = uval->value.enumerated.item[0];
498 if (id >= ARRAY_SIZE(special_dig_in_iface_labels))
499 return -EINVAL;
497 500
498 /* decode user value */ 501 /* decode user value */
499 dig_in_fmt = (id >> 1) & 0x01; 502 dig_in_fmt = (id >> 1) & 0x01;
500 dig_in_iface = id & 0x01; 503 dig_in_iface = id & 0x01;
501 504
505 mutex_lock(&bebob->mutex);
506
502 err = avc_maudio_set_special_clk(bebob, 507 err = avc_maudio_set_special_clk(bebob,
503 params->clk_src, 508 params->clk_src,
504 dig_in_fmt, 509 dig_in_fmt,
505 params->dig_out_fmt, 510 params->dig_out_fmt,
506 params->clk_lock); 511 params->clk_lock);
507 if ((err < 0) || (params->dig_in_fmt > 0)) /* ADAT */ 512 if (err < 0)
513 goto end;
514
515 /* For ADAT, optical interface is only available. */
516 if (params->dig_in_fmt > 0) {
517 err = 1;
508 goto end; 518 goto end;
519 }
509 520
521 /* For S/PDIF, optical/coaxial interfaces are selectable. */
510 err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface); 522 err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
511 if (err < 0) 523 if (err < 0)
512 dev_err(&bebob->unit->device, 524 dev_err(&bebob->unit->device,
513 "fail to set digital input interface: %d\n", err); 525 "fail to set digital input interface: %d\n", err);
526 err = 1;
514end: 527end:
515 special_stream_formation_set(bebob); 528 special_stream_formation_set(bebob);
516 mutex_unlock(&bebob->mutex); 529 mutex_unlock(&bebob->mutex);
@@ -525,18 +538,22 @@ static struct snd_kcontrol_new special_dig_in_iface_ctl = {
525 .put = special_dig_in_iface_ctl_set 538 .put = special_dig_in_iface_ctl_set
526}; 539};
527 540
541/* Digital output interface control for special firmware */
542static char *const special_dig_out_iface_labels[] = {
543 "S/PDIF Optical and Coaxial", "ADAT Optical"
544};
528static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl, 545static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl,
529 struct snd_ctl_elem_info *einf) 546 struct snd_ctl_elem_info *einf)
530{ 547{
531 einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 548 einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
532 einf->count = 1; 549 einf->count = 1;
533 einf->value.enumerated.items = ARRAY_SIZE(special_dig_iface_labels) - 1; 550 einf->value.enumerated.items = ARRAY_SIZE(special_dig_out_iface_labels);
534 551
535 if (einf->value.enumerated.item >= einf->value.enumerated.items) 552 if (einf->value.enumerated.item >= einf->value.enumerated.items)
536 einf->value.enumerated.item = einf->value.enumerated.items - 1; 553 einf->value.enumerated.item = einf->value.enumerated.items - 1;
537 554
538 strcpy(einf->value.enumerated.name, 555 strcpy(einf->value.enumerated.name,
539 special_dig_iface_labels[einf->value.enumerated.item + 1]); 556 special_dig_out_iface_labels[einf->value.enumerated.item]);
540 557
541 return 0; 558 return 0;
542} 559}
@@ -558,16 +575,20 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
558 unsigned int id; 575 unsigned int id;
559 int err; 576 int err;
560 577
561 mutex_lock(&bebob->mutex);
562
563 id = uval->value.enumerated.item[0]; 578 id = uval->value.enumerated.item[0];
579 if (id >= ARRAY_SIZE(special_dig_out_iface_labels))
580 return -EINVAL;
581
582 mutex_lock(&bebob->mutex);
564 583
565 err = avc_maudio_set_special_clk(bebob, 584 err = avc_maudio_set_special_clk(bebob,
566 params->clk_src, 585 params->clk_src,
567 params->dig_in_fmt, 586 params->dig_in_fmt,
568 id, params->clk_lock); 587 id, params->clk_lock);
569 if (err >= 0) 588 if (err >= 0) {
570 special_stream_formation_set(bebob); 589 special_stream_formation_set(bebob);
590 err = 1;
591 }
571 592
572 mutex_unlock(&bebob->mutex); 593 mutex_unlock(&bebob->mutex);
573 return err; 594 return err;