All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1
@ 2018-01-16  4:38 Ian Douglas Scott
  2018-01-16 11:46 ` Takashi Iwai
  2018-01-16 23:34 ` [PATCH v2] " Ian Douglas Scott
  0 siblings, 2 replies; 4+ messages in thread
From: Ian Douglas Scott @ 2018-01-16  4:38 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai, Detlef Urban, Bhumika Goyal,
	Mark Brown, alsa-devel
  Cc: Ian Douglas Scott

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@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);
+}
+
+static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
+{
+	return snd_soundblaster_e1_switch_update(list->mixer,
+						 list->kctl->private_value);
+}
+
+static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
+{
+	static const char *const texts[2] = {
+		"Mic", "Aux"
+	};
+
+	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
+}
+
+static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Input Source",
+	.info = snd_soundblaster_e1_switch_info,
+	.get = snd_soundblaster_e1_switch_get,
+	.put = snd_soundblaster_e1_switch_put,
+	.private_value = 0,
+};
+
+static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer)
+{
+	return add_single_ctl_with_resume(mixer, 0,
+					  snd_soundblaster_e1_switch_resume,
+					  &snd_soundblaster_e1_input_switch,
+					  NULL);
+}
+
 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 {
 	int err = 0;
@@ -1802,6 +1877,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 	case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */
 		err = snd_scarlett_controls_create(mixer);
 		break;
+
+	case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
+		err = snd_soundblaster_e1_switch_create(mixer);
+		break;
 	}
 
 	return err;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1
  2018-01-16  4:38 [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1 Ian Douglas Scott
@ 2018-01-16 11:46 ` Takashi Iwai
  2018-01-16 23:34 ` [PATCH v2] " Ian Douglas Scott
  1 sibling, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2018-01-16 11:46 UTC (permalink / raw)
  To: Ian Douglas Scott; +Cc: alsa-devel, Mark Brown, Detlef Urban, Bhumika Goyal

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@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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] ALSA: usb-audio: Support changing input on Sound Blaster E1
  2018-01-16  4:38 [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1 Ian Douglas Scott
  2018-01-16 11:46 ` Takashi Iwai
@ 2018-01-16 23:34 ` Ian Douglas Scott
  2018-01-18  9:13   ` Takashi Iwai
  1 sibling, 1 reply; 4+ messages in thread
From: Ian Douglas Scott @ 2018-01-16 23:34 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai, Detlef Urban, Bhumika Goyal,
	Mark Brown, alsa-devel
  Cc: Ian Douglas Scott

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@iandouglasscott.com>
---
 sound/usb/mixer_quirks.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index e1e7ce9ab217..e6359d341878 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,83 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
 	return 0;
 }
 
+/* Creative Sound Blaster E1 */
+
+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];
+	int err;
+
+	if (kcontrol->private_value == value)
+		return 0;
+	kcontrol->private_value = value;
+	err = snd_soundblaster_e1_switch_update(list->mixer, value);
+	return err < 0 ? err : 1;
+}
+
+static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
+{
+	return snd_soundblaster_e1_switch_update(list->mixer,
+						 list->kctl->private_value);
+}
+
+static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
+{
+	static const char *const texts[2] = {
+		"Mic", "Aux"
+	};
+
+	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
+}
+
+static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Input Source",
+	.info = snd_soundblaster_e1_switch_info,
+	.get = snd_soundblaster_e1_switch_get,
+	.put = snd_soundblaster_e1_switch_put,
+	.private_value = 0,
+};
+
+static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer)
+{
+	return add_single_ctl_with_resume(mixer, 0,
+					  snd_soundblaster_e1_switch_resume,
+					  &snd_soundblaster_e1_input_switch,
+					  NULL);
+}
+
 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 {
 	int err = 0;
@@ -1802,6 +1880,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 	case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */
 		err = snd_scarlett_controls_create(mixer);
 		break;
+
+	case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
+		err = snd_soundblaster_e1_switch_create(mixer);
+		break;
 	}
 
 	return err;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] ALSA: usb-audio: Support changing input on Sound Blaster E1
  2018-01-16 23:34 ` [PATCH v2] " Ian Douglas Scott
@ 2018-01-18  9:13   ` Takashi Iwai
  0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2018-01-18  9:13 UTC (permalink / raw)
  To: Ian Douglas Scott; +Cc: alsa-devel, Mark Brown, Detlef Urban, Bhumika Goyal

On Wed, 17 Jan 2018 00:34:50 +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@iandouglasscott.com>

Applied, thanks.


Takashi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-01-18  9:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-16  4:38 [PATCH] ALSA: usb-audio: Support changing input on Sound Blaster E1 Ian Douglas Scott
2018-01-16 11:46 ` Takashi Iwai
2018-01-16 23:34 ` [PATCH v2] " Ian Douglas Scott
2018-01-18  9:13   ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.