Skip to content

Commit 9c55021

Browse files
committed
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
2 parents 051c2a9 + eb12f72 commit 9c55021

1 file changed

Lines changed: 37 additions & 16 deletions

File tree

sound/firewire/bebob/bebob_maudio.c

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -379,19 +379,22 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl,
379379
struct special_params *params = bebob->maudio_special_quirk;
380380
int err, id;
381381

382-
mutex_lock(&bebob->mutex);
383-
384382
id = uval->value.enumerated.item[0];
385383
if (id >= ARRAY_SIZE(special_clk_labels))
386-
return 0;
384+
return -EINVAL;
385+
386+
mutex_lock(&bebob->mutex);
387387

388388
err = avc_maudio_set_special_clk(bebob, id,
389389
params->dig_in_fmt,
390390
params->dig_out_fmt,
391391
params->clk_lock);
392392
mutex_unlock(&bebob->mutex);
393393

394-
return err >= 0;
394+
if (err >= 0)
395+
err = 1;
396+
397+
return err;
395398
}
396399
static struct snd_kcontrol_new special_clk_ctl = {
397400
.name = "Clock Source",
@@ -434,22 +437,22 @@ static struct snd_kcontrol_new special_sync_ctl = {
434437
.get = special_sync_ctl_get,
435438
};
436439

437-
/* Digital interface control for special firmware */
438-
static char *const special_dig_iface_labels[] = {
440+
/* Digital input interface control for special firmware */
441+
static char *const special_dig_in_iface_labels[] = {
439442
"S/PDIF Optical", "S/PDIF Coaxial", "ADAT Optical"
440443
};
441444
static int special_dig_in_iface_ctl_info(struct snd_kcontrol *kctl,
442445
struct snd_ctl_elem_info *einf)
443446
{
444447
einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
445448
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);
447450

448451
if (einf->value.enumerated.item >= einf->value.enumerated.items)
449452
einf->value.enumerated.item = einf->value.enumerated.items - 1;
450453

451454
strcpy(einf->value.enumerated.name,
452-
special_dig_iface_labels[einf->value.enumerated.item]);
455+
special_dig_in_iface_labels[einf->value.enumerated.item]);
453456

454457
return 0;
455458
}
@@ -491,26 +494,36 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
491494
unsigned int id, dig_in_fmt, dig_in_iface;
492495
int err;
493496

494-
mutex_lock(&bebob->mutex);
495-
496497
id = uval->value.enumerated.item[0];
498+
if (id >= ARRAY_SIZE(special_dig_in_iface_labels))
499+
return -EINVAL;
497500

498501
/* decode user value */
499502
dig_in_fmt = (id >> 1) & 0x01;
500503
dig_in_iface = id & 0x01;
501504

505+
mutex_lock(&bebob->mutex);
506+
502507
err = avc_maudio_set_special_clk(bebob,
503508
params->clk_src,
504509
dig_in_fmt,
505510
params->dig_out_fmt,
506511
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;
508518
goto end;
519+
}
509520

521+
/* For S/PDIF, optical/coaxial interfaces are selectable. */
510522
err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
511523
if (err < 0)
512524
dev_err(&bebob->unit->device,
513525
"fail to set digital input interface: %d\n", err);
526+
err = 1;
514527
end:
515528
special_stream_formation_set(bebob);
516529
mutex_unlock(&bebob->mutex);
@@ -525,18 +538,22 @@ static struct snd_kcontrol_new special_dig_in_iface_ctl = {
525538
.put = special_dig_in_iface_ctl_set
526539
};
527540

541+
/* Digital output interface control for special firmware */
542+
static char *const special_dig_out_iface_labels[] = {
543+
"S/PDIF Optical and Coaxial", "ADAT Optical"
544+
};
528545
static int special_dig_out_iface_ctl_info(struct snd_kcontrol *kctl,
529546
struct snd_ctl_elem_info *einf)
530547
{
531548
einf->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
532549
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);
534551

535552
if (einf->value.enumerated.item >= einf->value.enumerated.items)
536553
einf->value.enumerated.item = einf->value.enumerated.items - 1;
537554

538555
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]);
540557

541558
return 0;
542559
}
@@ -558,16 +575,20 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl,
558575
unsigned int id;
559576
int err;
560577

561-
mutex_lock(&bebob->mutex);
562-
563578
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);
564583

565584
err = avc_maudio_set_special_clk(bebob,
566585
params->clk_src,
567586
params->dig_in_fmt,
568587
id, params->clk_lock);
569-
if (err >= 0)
588+
if (err >= 0) {
570589
special_stream_formation_set(bebob);
590+
err = 1;
591+
}
571592

572593
mutex_unlock(&bebob->mutex);
573594
return err;

0 commit comments

Comments
 (0)