[alsa-devel] [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1
Takashi Iwai
tiwai at suse.de
Tue Jan 16 12:46:36 CET 2018
On Tue, 16 Jan 2018 05:38:27 +0100,
Ian Douglas Scott wrote:
>
> The E1 has two headphone jacks, one of which can be set as a microphone
> input. In the default mode, it uses the built-in microphone as an input.
> By sending a special command, the second headphone jack is instead used
> as an input.
>
> This might work with the E3 as well, but I don't have one of those to
> test it.
>
> Signed-off-by: Ian Douglas Scott <ian at iandouglasscott.com>
> ---
> sound/usb/mixer_quirks.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 79 insertions(+)
>
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index e1e7ce9ab217..a91a0b75f6db 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -27,6 +27,7 @@
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> */
>
> +#include <linux/hid.h>
> #include <linux/init.h>
> #include <linux/slab.h>
> #include <linux/usb.h>
> @@ -1721,6 +1722,80 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
> return 0;
> }
>
> +static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + ucontrol->value.integer.value[0] = kcontrol->private_value;
> + return 0;
> +}
> +
> +static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer,
> + unsigned char state)
> +{
> + struct snd_usb_audio *chip = mixer->chip;
> + int err;
> + unsigned char buff[2];
> +
> + buff[0] = 0x02;
> + buff[1] = state ? 0x02 : 0x00;
> +
> + err = snd_usb_lock_shutdown(chip);
> + if (err < 0)
> + return err;
> + err = snd_usb_ctl_msg(chip->dev,
> + usb_sndctrlpipe(chip->dev, 0),
> + HID_REQ_SET_REPORT,
> + USB_TYPE_CLASS | USB_RECIP_INTERFACE
> + | USB_DIR_OUT,
> + 0x0202, 3,
> + buff, 2);
> + snd_usb_unlock_shutdown(chip);
> + return err;
> +}
> +
> +static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
> + unsigned char value = ucontrol->value.integer.value[0];
> +
> + kcontrol->private_value = value;
> + return snd_soundblaster_e1_switch_update(list->mixer, value);
> +}
The put callback returns three types of values: a negative error, 0
for unchanged values, and 1 for the value change. Also, the passed
value should be checked beforehand. So, it should be like:
static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
unsigned char value = !!ucontrol->value.integer.value[0];
if (kcontrol->private_value = value)
return 0;
kcontrol->private_value = value;
return snd_soundblaster_e1_switch_update(list->mixer, value);
}
thanks,
Takashi
More information about the Alsa-devel
mailing list