@@ -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}
396399static 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};
441444static 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 ;
514527end :
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+ };
528545static 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