diff options
author | Jaroslav Kysela <perex@perex.cz> | 2010-02-16 05:17:09 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-02-16 05:25:55 -0500 |
commit | ebfdeea3df2b8c265975b6acc47996a0b7c507e8 (patch) | |
tree | b9324a24462bff4dfaae8f7ce3afe60097ead495 /sound/usb/usbmixer.c | |
parent | b8f1f5983fbe751aa3d07d9ce7ebb0c23bf4b7e4 (diff) |
ALSA: usbmixer - introduce /proc/asound/card#/usbmixer file
The usbmixer proc file contains mapping between ALSA control API and
USB mixer control units. The purpose of this file is for debugging
and a problem diagnostics.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/usb/usbmixer.c')
-rw-r--r-- | sound/usb/usbmixer.c | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index dd0c1d7bf3e..170bfd4fc9f 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -69,13 +69,16 @@ static const struct rc_config { | |||
69 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ | 69 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ |
70 | }; | 70 | }; |
71 | 71 | ||
72 | #define MAX_ID_ELEMS 256 | ||
73 | |||
72 | struct usb_mixer_interface { | 74 | struct usb_mixer_interface { |
73 | struct snd_usb_audio *chip; | 75 | struct snd_usb_audio *chip; |
74 | unsigned int ctrlif; | 76 | unsigned int ctrlif; |
75 | struct list_head list; | 77 | struct list_head list; |
76 | unsigned int ignore_ctl_error; | 78 | unsigned int ignore_ctl_error; |
77 | struct urb *urb; | 79 | struct urb *urb; |
78 | struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ | 80 | /* array[MAX_ID_ELEMS], indexed by unit id */ |
81 | struct usb_mixer_elem_info **id_elems; | ||
79 | 82 | ||
80 | /* Sound Blaster remote control stuff */ | 83 | /* Sound Blaster remote control stuff */ |
81 | const struct rc_config *rc_cfg; | 84 | const struct rc_config *rc_cfg; |
@@ -1825,6 +1828,45 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, | |||
1825 | info->elem_id); | 1828 | info->elem_id); |
1826 | } | 1829 | } |
1827 | 1830 | ||
1831 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, | ||
1832 | int unitid, | ||
1833 | struct usb_mixer_elem_info *cval) | ||
1834 | { | ||
1835 | static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", | ||
1836 | "S8", "U8", "S16", "U16"}; | ||
1837 | snd_iprintf(buffer, " Unit: %i\n", unitid); | ||
1838 | if (cval->elem_id) | ||
1839 | snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n", | ||
1840 | cval->elem_id->name, cval->elem_id->index); | ||
1841 | snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " | ||
1842 | "channels=%i, type=\"%s\"\n", cval->id, | ||
1843 | cval->control, cval->cmask, cval->channels, | ||
1844 | val_types[cval->val_type]); | ||
1845 | snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n", | ||
1846 | cval->min, cval->max, cval->dBmin, cval->dBmax); | ||
1847 | } | ||
1848 | |||
1849 | static void snd_usb_mixer_proc_read(struct snd_info_entry *entry, | ||
1850 | struct snd_info_buffer *buffer) | ||
1851 | { | ||
1852 | struct snd_usb_audio *chip = entry->private_data; | ||
1853 | struct usb_mixer_interface *mixer; | ||
1854 | struct usb_mixer_elem_info *cval; | ||
1855 | int unitid; | ||
1856 | |||
1857 | list_for_each_entry(mixer, &chip->mixer_list, list) { | ||
1858 | snd_iprintf(buffer, | ||
1859 | "USB Mixer: ctrlif=%i, ctlerr=%i\n", | ||
1860 | mixer->ctrlif, mixer->ignore_ctl_error); | ||
1861 | snd_iprintf(buffer, "Card: %s\n", chip->card->longname); | ||
1862 | for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { | ||
1863 | for (cval = mixer->id_elems[unitid]; cval; | ||
1864 | cval = cval->next_id_elem) | ||
1865 | snd_usb_mixer_dump_cval(buffer, unitid, cval); | ||
1866 | } | ||
1867 | } | ||
1868 | } | ||
1869 | |||
1828 | static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, | 1870 | static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, |
1829 | int unitid) | 1871 | int unitid) |
1830 | { | 1872 | { |
@@ -2187,20 +2229,21 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) | |||
2187 | } | 2229 | } |
2188 | 2230 | ||
2189 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 2231 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
2190 | unsigned char samplerate_id) | 2232 | unsigned char samplerate_id) |
2191 | { | 2233 | { |
2192 | struct usb_mixer_interface *mixer; | 2234 | struct usb_mixer_interface *mixer; |
2193 | struct usb_mixer_elem_info *cval; | 2235 | struct usb_mixer_elem_info *cval; |
2194 | int unitid = 12; /* SamleRate ExtensionUnit ID */ | 2236 | int unitid = 12; /* SamleRate ExtensionUnit ID */ |
2195 | 2237 | ||
2196 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 2238 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
2197 | cval = mixer->id_elems[unitid]; | 2239 | cval = mixer->id_elems[unitid]; |
2198 | if (cval) { | 2240 | if (cval) { |
2199 | set_cur_ctl_value(cval, cval->control << 8, samplerate_id); | 2241 | set_cur_ctl_value(cval, cval->control << 8, |
2242 | samplerate_id); | ||
2200 | snd_usb_mixer_notify_id(mixer, unitid); | 2243 | snd_usb_mixer_notify_id(mixer, unitid); |
2201 | } | 2244 | } |
2202 | break; | 2245 | break; |
2203 | } | 2246 | } |
2204 | } | 2247 | } |
2205 | 2248 | ||
2206 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | 2249 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, |
@@ -2210,6 +2253,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2210 | .dev_free = snd_usb_mixer_dev_free | 2253 | .dev_free = snd_usb_mixer_dev_free |
2211 | }; | 2254 | }; |
2212 | struct usb_mixer_interface *mixer; | 2255 | struct usb_mixer_interface *mixer; |
2256 | struct snd_info_entry *entry; | ||
2213 | int err; | 2257 | int err; |
2214 | 2258 | ||
2215 | strcpy(chip->card->mixername, "USB Mixer"); | 2259 | strcpy(chip->card->mixername, "USB Mixer"); |
@@ -2236,8 +2280,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2236 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || | 2280 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || |
2237 | mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || | 2281 | mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || |
2238 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { | 2282 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { |
2239 | struct snd_info_entry *entry; | ||
2240 | |||
2241 | if ((err = snd_audigy2nx_controls_create(mixer)) < 0) | 2283 | if ((err = snd_audigy2nx_controls_create(mixer)) < 0) |
2242 | goto _error; | 2284 | goto _error; |
2243 | if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) | 2285 | if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) |
@@ -2255,6 +2297,11 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2255 | err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); | 2297 | err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); |
2256 | if (err < 0) | 2298 | if (err < 0) |
2257 | goto _error; | 2299 | goto _error; |
2300 | |||
2301 | if (list_empty(&chip->mixer_list) && | ||
2302 | !snd_card_proc_new(chip->card, "usbmixer", &entry)) | ||
2303 | snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read); | ||
2304 | |||
2258 | list_add(&mixer->list, &chip->mixer_list); | 2305 | list_add(&mixer->list, &chip->mixer_list); |
2259 | return 0; | 2306 | return 0; |
2260 | 2307 | ||