Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: usb-audio: add front jack channel selector for EMU0204

Add support for front jack channel selector which is present on EMU0204.
It allows to get 4 channels out of this soundcard.

Tested-by: Yury Bushmelev <jay@jay-tech.ru>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Vasily Khoruzhick and committed by
Takashi Iwai
44832a71 d183b4fc

+90
+90
sound/usb/mixer_quirks.c
··· 433 433 } 434 434 } 435 435 436 + /* EMU0204 */ 437 + static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol, 438 + struct snd_ctl_elem_info *uinfo) 439 + { 440 + static const char *texts[2] = {"1/2", 441 + "3/4" 442 + }; 443 + 444 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 445 + uinfo->count = 1; 446 + uinfo->value.enumerated.items = 2; 447 + if (uinfo->value.enumerated.item > 1) 448 + uinfo->value.enumerated.item = 1; 449 + strcpy(uinfo->value.enumerated.name, 450 + texts[uinfo->value.enumerated.item]); 451 + 452 + return 0; 453 + } 454 + 455 + static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, 456 + struct snd_ctl_elem_value *ucontrol) 457 + { 458 + ucontrol->value.enumerated.item[0] = kcontrol->private_value; 459 + return 0; 460 + } 461 + 462 + static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, 463 + struct snd_ctl_elem_value *ucontrol) 464 + { 465 + struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 466 + unsigned int value = ucontrol->value.enumerated.item[0]; 467 + int err, changed; 468 + unsigned char buf[2]; 469 + 470 + if (value > 1) 471 + return -EINVAL; 472 + 473 + buf[0] = 0x01; 474 + buf[1] = value ? 0x02 : 0x01; 475 + 476 + changed = value != kcontrol->private_value; 477 + down_read(&mixer->chip->shutdown_rwsem); 478 + if (mixer->chip->shutdown) { 479 + err = -ENODEV; 480 + goto out; 481 + } 482 + err = snd_usb_ctl_msg(mixer->chip->dev, 483 + usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, 484 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 485 + 0x0400, 0x0e00, buf, 2); 486 + out: 487 + up_read(&mixer->chip->shutdown_rwsem); 488 + if (err < 0) 489 + return err; 490 + kcontrol->private_value = value; 491 + return changed; 492 + } 493 + 494 + 495 + static struct snd_kcontrol_new snd_emu0204_controls[] = { 496 + { 497 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 498 + .name = "Front Jack Channels", 499 + .info = snd_emu0204_ch_switch_info, 500 + .get = snd_emu0204_ch_switch_get, 501 + .put = snd_emu0204_ch_switch_put, 502 + .private_value = 0, 503 + }, 504 + }; 505 + 506 + static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) 507 + { 508 + int i, err; 509 + 510 + for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { 511 + err = snd_ctl_add(mixer->chip->card, 512 + snd_ctl_new1(&snd_emu0204_controls[i], mixer)); 513 + if (err < 0) 514 + return err; 515 + } 516 + 517 + return 0; 518 + } 436 519 /* ASUS Xonar U1 / U3 controls */ 437 520 438 521 static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, ··· 1626 1543 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry)) 1627 1544 snd_info_set_text_ops(entry, mixer, 1628 1545 snd_audigy2nx_proc_read); 1546 + break; 1547 + 1548 + /* EMU0204 */ 1549 + case USB_ID(0x041e, 0x3f19): 1550 + err = snd_emu0204_controls_create(mixer); 1551 + if (err < 0) 1552 + break; 1629 1553 break; 1630 1554 1631 1555 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */