|
27 | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | 28 | */ |
29 | 29 |
|
| 30 | +#include <linux/hid.h> |
30 | 31 | #include <linux/init.h> |
31 | 32 | #include <linux/slab.h> |
32 | 33 | #include <linux/usb.h> |
@@ -1721,6 +1722,83 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer) |
1721 | 1722 | return 0; |
1722 | 1723 | } |
1723 | 1724 |
|
| 1725 | +/* Creative Sound Blaster E1 */ |
| 1726 | + |
| 1727 | +static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol, |
| 1728 | + struct snd_ctl_elem_value *ucontrol) |
| 1729 | +{ |
| 1730 | + ucontrol->value.integer.value[0] = kcontrol->private_value; |
| 1731 | + return 0; |
| 1732 | +} |
| 1733 | + |
| 1734 | +static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer, |
| 1735 | + unsigned char state) |
| 1736 | +{ |
| 1737 | + struct snd_usb_audio *chip = mixer->chip; |
| 1738 | + int err; |
| 1739 | + unsigned char buff[2]; |
| 1740 | + |
| 1741 | + buff[0] = 0x02; |
| 1742 | + buff[1] = state ? 0x02 : 0x00; |
| 1743 | + |
| 1744 | + err = snd_usb_lock_shutdown(chip); |
| 1745 | + if (err < 0) |
| 1746 | + return err; |
| 1747 | + err = snd_usb_ctl_msg(chip->dev, |
| 1748 | + usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT, |
| 1749 | + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
| 1750 | + 0x0202, 3, buff, 2); |
| 1751 | + snd_usb_unlock_shutdown(chip); |
| 1752 | + return err; |
| 1753 | +} |
| 1754 | + |
| 1755 | +static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol, |
| 1756 | + struct snd_ctl_elem_value *ucontrol) |
| 1757 | +{ |
| 1758 | + struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); |
| 1759 | + unsigned char value = !!ucontrol->value.integer.value[0]; |
| 1760 | + int err; |
| 1761 | + |
| 1762 | + if (kcontrol->private_value == value) |
| 1763 | + return 0; |
| 1764 | + kcontrol->private_value = value; |
| 1765 | + err = snd_soundblaster_e1_switch_update(list->mixer, value); |
| 1766 | + return err < 0 ? err : 1; |
| 1767 | +} |
| 1768 | + |
| 1769 | +static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list) |
| 1770 | +{ |
| 1771 | + return snd_soundblaster_e1_switch_update(list->mixer, |
| 1772 | + list->kctl->private_value); |
| 1773 | +} |
| 1774 | + |
| 1775 | +static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol, |
| 1776 | + struct snd_ctl_elem_info *uinfo) |
| 1777 | +{ |
| 1778 | + static const char *const texts[2] = { |
| 1779 | + "Mic", "Aux" |
| 1780 | + }; |
| 1781 | + |
| 1782 | + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); |
| 1783 | +} |
| 1784 | + |
| 1785 | +static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = { |
| 1786 | + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1787 | + .name = "Input Source", |
| 1788 | + .info = snd_soundblaster_e1_switch_info, |
| 1789 | + .get = snd_soundblaster_e1_switch_get, |
| 1790 | + .put = snd_soundblaster_e1_switch_put, |
| 1791 | + .private_value = 0, |
| 1792 | +}; |
| 1793 | + |
| 1794 | +static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) |
| 1795 | +{ |
| 1796 | + return add_single_ctl_with_resume(mixer, 0, |
| 1797 | + snd_soundblaster_e1_switch_resume, |
| 1798 | + &snd_soundblaster_e1_input_switch, |
| 1799 | + NULL); |
| 1800 | +} |
| 1801 | + |
1724 | 1802 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1725 | 1803 | { |
1726 | 1804 | int err = 0; |
@@ -1802,6 +1880,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1802 | 1880 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ |
1803 | 1881 | err = snd_scarlett_controls_create(mixer); |
1804 | 1882 | break; |
| 1883 | + |
| 1884 | + case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ |
| 1885 | + err = snd_soundblaster_e1_switch_create(mixer); |
| 1886 | + break; |
1805 | 1887 | } |
1806 | 1888 |
|
1807 | 1889 | return err; |
|
0 commit comments