aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Khoruzhick <anarsoul@gmail.com>2013-11-13 05:13:35 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-13 11:05:20 -0500
commit44832a71f377d9eae1d97afedad4d0d6d51fc485 (patch)
tree2f699268a072a200a62e32a2cc80303d40b309f3
parentd183b4fc463489b6bbe05c99afa0257a6fe578eb (diff)
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>
-rw-r--r--sound/usb/mixer_quirks.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index d42a584cf829..3454262358b3 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -433,6 +433,89 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
433 } 433 }
434} 434}
435 435
436/* EMU0204 */
437static 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
455static 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
462static 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
495static 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
506static 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/* ASUS Xonar U1 / U3 controls */ 519/* ASUS Xonar U1 / U3 controls */
437 520
438static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, 521static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
@@ -1545,6 +1628,13 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1545 snd_audigy2nx_proc_read); 1628 snd_audigy2nx_proc_read);
1546 break; 1629 break;
1547 1630
1631 /* EMU0204 */
1632 case USB_ID(0x041e, 0x3f19):
1633 err = snd_emu0204_controls_create(mixer);
1634 if (err < 0)
1635 break;
1636 break;
1637
1548 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ 1638 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
1549 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */ 1639 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */
1550 err = snd_c400_create_mixer(mixer); 1640 err = snd_c400_create_mixer(mixer);