Loading sound/usb/mixer_quirks.c +46 −38 Original line number Diff line number Diff line Loading @@ -473,63 +473,71 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, return 0; } static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer, int value) { struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); unsigned int value = ucontrol->value.enumerated.item[0]; int err, changed; struct snd_usb_audio *chip = mixer->chip; int err; unsigned char buf[2]; if (value > 1) return -EINVAL; buf[0] = 0x01; buf[1] = value ? 0x02 : 0x01; changed = value != kcontrol->private_value; down_read(&mixer->chip->shutdown_rwsem); down_read(&chip->shutdown_rwsem); if (mixer->chip->shutdown) { err = -ENODEV; goto out; } err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, buf[0] = 0x01; buf[1] = value ? 0x02 : 0x01; err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 0x0400, 0x0e00, buf, 2); out: up_read(&mixer->chip->shutdown_rwsem); if (err < 0) up_read(&chip->shutdown_rwsem); return err; kcontrol->private_value = value; return changed; } static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); struct usb_mixer_interface *mixer = list->mixer; unsigned int value = ucontrol->value.enumerated.item[0]; int err; if (value > 1) return -EINVAL; if (value == kcontrol->private_value) return 0; kcontrol->private_value = value; err = snd_emu0204_ch_switch_update(mixer, value); return err < 0 ? err : 1; } static struct snd_kcontrol_new snd_emu0204_controls[] = { static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list) { return snd_emu0204_ch_switch_update(list->mixer, list->kctl->private_value); } static struct snd_kcontrol_new snd_emu0204_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Front Jack Channels", .info = snd_emu0204_ch_switch_info, .get = snd_emu0204_ch_switch_get, .put = snd_emu0204_ch_switch_put, .private_value = 0, }, }; static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) { int i, err; for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { err = snd_ctl_add(mixer->chip->card, snd_ctl_new1(&snd_emu0204_controls[i], mixer)); if (err < 0) return err; return add_single_ctl_with_resume(mixer, 0, snd_emu0204_ch_switch_resume, &snd_emu0204_control, NULL); } return 0; } /* ASUS Xonar U1 / U3 controls */ static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, Loading Loading
sound/usb/mixer_quirks.c +46 −38 Original line number Diff line number Diff line Loading @@ -473,63 +473,71 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol, return 0; } static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer, int value) { struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); unsigned int value = ucontrol->value.enumerated.item[0]; int err, changed; struct snd_usb_audio *chip = mixer->chip; int err; unsigned char buf[2]; if (value > 1) return -EINVAL; buf[0] = 0x01; buf[1] = value ? 0x02 : 0x01; changed = value != kcontrol->private_value; down_read(&mixer->chip->shutdown_rwsem); down_read(&chip->shutdown_rwsem); if (mixer->chip->shutdown) { err = -ENODEV; goto out; } err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, buf[0] = 0x01; buf[1] = value ? 0x02 : 0x01; err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 0x0400, 0x0e00, buf, 2); out: up_read(&mixer->chip->shutdown_rwsem); if (err < 0) up_read(&chip->shutdown_rwsem); return err; kcontrol->private_value = value; return changed; } static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); struct usb_mixer_interface *mixer = list->mixer; unsigned int value = ucontrol->value.enumerated.item[0]; int err; if (value > 1) return -EINVAL; if (value == kcontrol->private_value) return 0; kcontrol->private_value = value; err = snd_emu0204_ch_switch_update(mixer, value); return err < 0 ? err : 1; } static struct snd_kcontrol_new snd_emu0204_controls[] = { static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list) { return snd_emu0204_ch_switch_update(list->mixer, list->kctl->private_value); } static struct snd_kcontrol_new snd_emu0204_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Front Jack Channels", .info = snd_emu0204_ch_switch_info, .get = snd_emu0204_ch_switch_get, .put = snd_emu0204_ch_switch_put, .private_value = 0, }, }; static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) { int i, err; for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { err = snd_ctl_add(mixer->chip->card, snd_ctl_new1(&snd_emu0204_controls[i], mixer)); if (err < 0) return err; return add_single_ctl_with_resume(mixer, 0, snd_emu0204_ch_switch_resume, &snd_emu0204_control, NULL); } return 0; } /* ASUS Xonar U1 / U3 controls */ static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, Loading