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