diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-05-03 02:02:40 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-05-29 04:06:03 -0400 |
commit | 93446edcd05589201f20cf8843e8c4f990c18ae4 (patch) | |
tree | 1c744566676679ae27194df86a956fbb84453a70 | |
parent | 434b7f56872fc5783c77f362e895da8e22168325 (diff) |
[ALSA] usb-audio - Audigy 2 NX blinkenlights
USB generic driver
Adds mixer controls for the CMSS/Dolby Digital/Power LEDs
on the SB Audigy 2 NX.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
-rw-r--r-- | sound/usb/usbmixer.c | 106 |
1 files changed, 95 insertions, 11 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index d90d6fa7431a..ec880ff52625 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -83,6 +83,8 @@ struct usb_mixer_interface { | |||
83 | struct urb *rc_urb; | 83 | struct urb *rc_urb; |
84 | struct usb_ctrlrequest *rc_setup_packet; | 84 | struct usb_ctrlrequest *rc_setup_packet; |
85 | u8 rc_buffer[6]; | 85 | u8 rc_buffer[6]; |
86 | |||
87 | u8 audigy2nx_leds[3]; | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | 90 | ||
@@ -1846,6 +1848,85 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) | |||
1846 | return 0; | 1848 | return 0; |
1847 | } | 1849 | } |
1848 | 1850 | ||
1851 | static int snd_audigy2nx_led_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | ||
1852 | { | ||
1853 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1854 | uinfo->count = 1; | ||
1855 | uinfo->value.integer.min = 0; | ||
1856 | uinfo->value.integer.max = 1; | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static int snd_audigy2nx_led_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
1861 | { | ||
1862 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | ||
1863 | int index = kcontrol->private_value; | ||
1864 | |||
1865 | ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index]; | ||
1866 | return 0; | ||
1867 | } | ||
1868 | |||
1869 | static int snd_audigy2nx_led_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
1870 | { | ||
1871 | struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); | ||
1872 | int index = kcontrol->private_value; | ||
1873 | int value = ucontrol->value.integer.value[0]; | ||
1874 | int err, changed; | ||
1875 | |||
1876 | if (value > 1) | ||
1877 | return -EINVAL; | ||
1878 | changed = value != mixer->audigy2nx_leds[index]; | ||
1879 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
1880 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | ||
1881 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | ||
1882 | value, index + 2, NULL, 0, 100); | ||
1883 | if (err < 0) | ||
1884 | return err; | ||
1885 | mixer->audigy2nx_leds[index] = value; | ||
1886 | return changed; | ||
1887 | } | ||
1888 | |||
1889 | static snd_kcontrol_new_t snd_audigy2nx_controls[] = { | ||
1890 | { | ||
1891 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1892 | .name = "CMSS LED Switch", | ||
1893 | .info = snd_audigy2nx_led_info, | ||
1894 | .get = snd_audigy2nx_led_get, | ||
1895 | .put = snd_audigy2nx_led_put, | ||
1896 | .private_value = 0, | ||
1897 | }, | ||
1898 | { | ||
1899 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1900 | .name = "Power LED Switch", | ||
1901 | .info = snd_audigy2nx_led_info, | ||
1902 | .get = snd_audigy2nx_led_get, | ||
1903 | .put = snd_audigy2nx_led_put, | ||
1904 | .private_value = 1, | ||
1905 | }, | ||
1906 | { | ||
1907 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1908 | .name = "Dolby Digital LED Switch", | ||
1909 | .info = snd_audigy2nx_led_info, | ||
1910 | .get = snd_audigy2nx_led_get, | ||
1911 | .put = snd_audigy2nx_led_put, | ||
1912 | .private_value = 2, | ||
1913 | }, | ||
1914 | }; | ||
1915 | |||
1916 | static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) | ||
1917 | { | ||
1918 | int i, err; | ||
1919 | |||
1920 | for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { | ||
1921 | err = snd_ctl_add(mixer->chip->card, | ||
1922 | snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); | ||
1923 | if (err < 0) | ||
1924 | return err; | ||
1925 | } | ||
1926 | mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */ | ||
1927 | return 0; | ||
1928 | } | ||
1929 | |||
1849 | int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) | 1930 | int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) |
1850 | { | 1931 | { |
1851 | static snd_device_ops_t dev_ops = { | 1932 | static snd_device_ops_t dev_ops = { |
@@ -1871,23 +1952,26 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) | |||
1871 | } | 1952 | } |
1872 | 1953 | ||
1873 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || | 1954 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || |
1874 | (err = snd_usb_mixer_status_create(mixer)) < 0) { | 1955 | (err = snd_usb_mixer_status_create(mixer)) < 0) |
1875 | snd_usb_mixer_free(mixer); | 1956 | goto _error; |
1876 | return err; | ||
1877 | } | ||
1878 | 1957 | ||
1879 | if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) { | 1958 | if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) |
1880 | snd_usb_mixer_free(mixer); | 1959 | goto _error; |
1881 | return err; | 1960 | |
1961 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) { | ||
1962 | if ((err = snd_audigy2nx_controls_create(mixer)) < 0) | ||
1963 | goto _error; | ||
1882 | } | 1964 | } |
1883 | 1965 | ||
1884 | err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); | 1966 | err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); |
1885 | if (err < 0) { | 1967 | if (err < 0) |
1886 | snd_usb_mixer_free(mixer); | 1968 | goto _error; |
1887 | return err; | ||
1888 | } | ||
1889 | list_add(&mixer->list, &chip->mixer_list); | 1969 | list_add(&mixer->list, &chip->mixer_list); |
1890 | return 0; | 1970 | return 0; |
1971 | |||
1972 | _error: | ||
1973 | snd_usb_mixer_free(mixer); | ||
1974 | return err; | ||
1891 | } | 1975 | } |
1892 | 1976 | ||
1893 | void snd_usb_mixer_disconnect(struct list_head *p) | 1977 | void snd_usb_mixer_disconnect(struct list_head *p) |