Commit 0af49ffe3c04ed5a9095ea1349d3e26a1e8b311a
Committed by
Takashi Iwai
1 parent
4a9f911861
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
ALSA: usb: uniform style used in MODULE_SUPPORTED_DEVICE()
In sound/usb/card.c and sound/usb/misc/ua101.c there are no spaces between the vendor and the device names, use this style in the other drivers too. This also helps keeping consistency when new drivers copies from the ones already in the mainline tree. Signed-off-by: Antonio Ospite <ao2@amarulasolutions.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 3 changed files with 16 additions and 16 deletions Inline Diff
sound/usb/6fire/chip.c
1 | /* | 1 | /* |
2 | * Linux driver for TerraTec DMX 6Fire USB | 2 | * Linux driver for TerraTec DMX 6Fire USB |
3 | * | 3 | * |
4 | * Main routines and module definitions. | 4 | * Main routines and module definitions. |
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "chip.h" | 16 | #include "chip.h" |
17 | #include "firmware.h" | 17 | #include "firmware.h" |
18 | #include "pcm.h" | 18 | #include "pcm.h" |
19 | #include "control.h" | 19 | #include "control.h" |
20 | #include "comm.h" | 20 | #include "comm.h" |
21 | #include "midi.h" | 21 | #include "midi.h" |
22 | 22 | ||
23 | #include <linux/moduleparam.h> | 23 | #include <linux/moduleparam.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/gfp.h> | 27 | #include <linux/gfp.h> |
28 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
29 | 29 | ||
30 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); | 30 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); |
31 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver"); | 31 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver"); |
32 | MODULE_LICENSE("GPL v2"); | 32 | MODULE_LICENSE("GPL v2"); |
33 | MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); | 33 | MODULE_SUPPORTED_DEVICE("{{TerraTec,DMX 6Fire USB}}"); |
34 | 34 | ||
35 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 35 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
36 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ | 36 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ |
37 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ | 37 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ |
38 | static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | 38 | static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; |
39 | static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | 39 | static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; |
40 | 40 | ||
41 | module_param_array(index, int, NULL, 0444); | 41 | module_param_array(index, int, NULL, 0444); |
42 | MODULE_PARM_DESC(index, "Index value for the 6fire sound device"); | 42 | MODULE_PARM_DESC(index, "Index value for the 6fire sound device"); |
43 | module_param_array(id, charp, NULL, 0444); | 43 | module_param_array(id, charp, NULL, 0444); |
44 | MODULE_PARM_DESC(id, "ID string for the 6fire sound device."); | 44 | MODULE_PARM_DESC(id, "ID string for the 6fire sound device."); |
45 | module_param_array(enable, bool, NULL, 0444); | 45 | module_param_array(enable, bool, NULL, 0444); |
46 | MODULE_PARM_DESC(enable, "Enable the 6fire sound device."); | 46 | MODULE_PARM_DESC(enable, "Enable the 6fire sound device."); |
47 | 47 | ||
48 | static DEFINE_MUTEX(register_mutex); | 48 | static DEFINE_MUTEX(register_mutex); |
49 | 49 | ||
50 | static void usb6fire_chip_abort(struct sfire_chip *chip) | 50 | static void usb6fire_chip_abort(struct sfire_chip *chip) |
51 | { | 51 | { |
52 | if (chip) { | 52 | if (chip) { |
53 | if (chip->pcm) | 53 | if (chip->pcm) |
54 | usb6fire_pcm_abort(chip); | 54 | usb6fire_pcm_abort(chip); |
55 | if (chip->midi) | 55 | if (chip->midi) |
56 | usb6fire_midi_abort(chip); | 56 | usb6fire_midi_abort(chip); |
57 | if (chip->comm) | 57 | if (chip->comm) |
58 | usb6fire_comm_abort(chip); | 58 | usb6fire_comm_abort(chip); |
59 | if (chip->control) | 59 | if (chip->control) |
60 | usb6fire_control_abort(chip); | 60 | usb6fire_control_abort(chip); |
61 | if (chip->card) { | 61 | if (chip->card) { |
62 | snd_card_disconnect(chip->card); | 62 | snd_card_disconnect(chip->card); |
63 | snd_card_free_when_closed(chip->card); | 63 | snd_card_free_when_closed(chip->card); |
64 | chip->card = NULL; | 64 | chip->card = NULL; |
65 | } | 65 | } |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | static void usb6fire_chip_destroy(struct sfire_chip *chip) | 69 | static void usb6fire_chip_destroy(struct sfire_chip *chip) |
70 | { | 70 | { |
71 | if (chip) { | 71 | if (chip) { |
72 | if (chip->pcm) | 72 | if (chip->pcm) |
73 | usb6fire_pcm_destroy(chip); | 73 | usb6fire_pcm_destroy(chip); |
74 | if (chip->midi) | 74 | if (chip->midi) |
75 | usb6fire_midi_destroy(chip); | 75 | usb6fire_midi_destroy(chip); |
76 | if (chip->comm) | 76 | if (chip->comm) |
77 | usb6fire_comm_destroy(chip); | 77 | usb6fire_comm_destroy(chip); |
78 | if (chip->control) | 78 | if (chip->control) |
79 | usb6fire_control_destroy(chip); | 79 | usb6fire_control_destroy(chip); |
80 | if (chip->card) | 80 | if (chip->card) |
81 | snd_card_free(chip->card); | 81 | snd_card_free(chip->card); |
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
85 | static int usb6fire_chip_probe(struct usb_interface *intf, | 85 | static int usb6fire_chip_probe(struct usb_interface *intf, |
86 | const struct usb_device_id *usb_id) | 86 | const struct usb_device_id *usb_id) |
87 | { | 87 | { |
88 | int ret; | 88 | int ret; |
89 | int i; | 89 | int i; |
90 | struct sfire_chip *chip = NULL; | 90 | struct sfire_chip *chip = NULL; |
91 | struct usb_device *device = interface_to_usbdev(intf); | 91 | struct usb_device *device = interface_to_usbdev(intf); |
92 | int regidx = -1; /* index in module parameter array */ | 92 | int regidx = -1; /* index in module parameter array */ |
93 | struct snd_card *card = NULL; | 93 | struct snd_card *card = NULL; |
94 | 94 | ||
95 | /* look if we already serve this card and return if so */ | 95 | /* look if we already serve this card and return if so */ |
96 | mutex_lock(®ister_mutex); | 96 | mutex_lock(®ister_mutex); |
97 | for (i = 0; i < SNDRV_CARDS; i++) { | 97 | for (i = 0; i < SNDRV_CARDS; i++) { |
98 | if (devices[i] == device) { | 98 | if (devices[i] == device) { |
99 | if (chips[i]) | 99 | if (chips[i]) |
100 | chips[i]->intf_count++; | 100 | chips[i]->intf_count++; |
101 | usb_set_intfdata(intf, chips[i]); | 101 | usb_set_intfdata(intf, chips[i]); |
102 | mutex_unlock(®ister_mutex); | 102 | mutex_unlock(®ister_mutex); |
103 | return 0; | 103 | return 0; |
104 | } else if (regidx < 0) | 104 | } else if (regidx < 0) |
105 | regidx = i; | 105 | regidx = i; |
106 | } | 106 | } |
107 | if (regidx < 0) { | 107 | if (regidx < 0) { |
108 | mutex_unlock(®ister_mutex); | 108 | mutex_unlock(®ister_mutex); |
109 | snd_printk(KERN_ERR PREFIX "too many cards registered.\n"); | 109 | snd_printk(KERN_ERR PREFIX "too many cards registered.\n"); |
110 | return -ENODEV; | 110 | return -ENODEV; |
111 | } | 111 | } |
112 | devices[regidx] = device; | 112 | devices[regidx] = device; |
113 | mutex_unlock(®ister_mutex); | 113 | mutex_unlock(®ister_mutex); |
114 | 114 | ||
115 | /* check, if firmware is present on device, upload it if not */ | 115 | /* check, if firmware is present on device, upload it if not */ |
116 | ret = usb6fire_fw_init(intf); | 116 | ret = usb6fire_fw_init(intf); |
117 | if (ret < 0) | 117 | if (ret < 0) |
118 | return ret; | 118 | return ret; |
119 | else if (ret == FW_NOT_READY) /* firmware update performed */ | 119 | else if (ret == FW_NOT_READY) /* firmware update performed */ |
120 | return 0; | 120 | return 0; |
121 | 121 | ||
122 | /* if we are here, card can be registered in alsa. */ | 122 | /* if we are here, card can be registered in alsa. */ |
123 | if (usb_set_interface(device, 0, 0) != 0) { | 123 | if (usb_set_interface(device, 0, 0) != 0) { |
124 | snd_printk(KERN_ERR PREFIX "can't set first interface.\n"); | 124 | snd_printk(KERN_ERR PREFIX "can't set first interface.\n"); |
125 | return -EIO; | 125 | return -EIO; |
126 | } | 126 | } |
127 | ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE, | 127 | ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE, |
128 | sizeof(struct sfire_chip), &card); | 128 | sizeof(struct sfire_chip), &card); |
129 | if (ret < 0) { | 129 | if (ret < 0) { |
130 | snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n"); | 130 | snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n"); |
131 | return ret; | 131 | return ret; |
132 | } | 132 | } |
133 | strcpy(card->driver, "6FireUSB"); | 133 | strcpy(card->driver, "6FireUSB"); |
134 | strcpy(card->shortname, "TerraTec DMX6FireUSB"); | 134 | strcpy(card->shortname, "TerraTec DMX6FireUSB"); |
135 | sprintf(card->longname, "%s at %d:%d", card->shortname, | 135 | sprintf(card->longname, "%s at %d:%d", card->shortname, |
136 | device->bus->busnum, device->devnum); | 136 | device->bus->busnum, device->devnum); |
137 | snd_card_set_dev(card, &intf->dev); | 137 | snd_card_set_dev(card, &intf->dev); |
138 | 138 | ||
139 | chip = card->private_data; | 139 | chip = card->private_data; |
140 | chips[regidx] = chip; | 140 | chips[regidx] = chip; |
141 | chip->dev = device; | 141 | chip->dev = device; |
142 | chip->regidx = regidx; | 142 | chip->regidx = regidx; |
143 | chip->intf_count = 1; | 143 | chip->intf_count = 1; |
144 | chip->card = card; | 144 | chip->card = card; |
145 | 145 | ||
146 | ret = usb6fire_comm_init(chip); | 146 | ret = usb6fire_comm_init(chip); |
147 | if (ret < 0) { | 147 | if (ret < 0) { |
148 | usb6fire_chip_destroy(chip); | 148 | usb6fire_chip_destroy(chip); |
149 | return ret; | 149 | return ret; |
150 | } | 150 | } |
151 | 151 | ||
152 | ret = usb6fire_midi_init(chip); | 152 | ret = usb6fire_midi_init(chip); |
153 | if (ret < 0) { | 153 | if (ret < 0) { |
154 | usb6fire_chip_destroy(chip); | 154 | usb6fire_chip_destroy(chip); |
155 | return ret; | 155 | return ret; |
156 | } | 156 | } |
157 | 157 | ||
158 | ret = usb6fire_pcm_init(chip); | 158 | ret = usb6fire_pcm_init(chip); |
159 | if (ret < 0) { | 159 | if (ret < 0) { |
160 | usb6fire_chip_destroy(chip); | 160 | usb6fire_chip_destroy(chip); |
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
163 | 163 | ||
164 | ret = usb6fire_control_init(chip); | 164 | ret = usb6fire_control_init(chip); |
165 | if (ret < 0) { | 165 | if (ret < 0) { |
166 | usb6fire_chip_destroy(chip); | 166 | usb6fire_chip_destroy(chip); |
167 | return ret; | 167 | return ret; |
168 | } | 168 | } |
169 | 169 | ||
170 | ret = snd_card_register(card); | 170 | ret = snd_card_register(card); |
171 | if (ret < 0) { | 171 | if (ret < 0) { |
172 | snd_printk(KERN_ERR PREFIX "cannot register card."); | 172 | snd_printk(KERN_ERR PREFIX "cannot register card."); |
173 | usb6fire_chip_destroy(chip); | 173 | usb6fire_chip_destroy(chip); |
174 | return ret; | 174 | return ret; |
175 | } | 175 | } |
176 | usb_set_intfdata(intf, chip); | 176 | usb_set_intfdata(intf, chip); |
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | static void usb6fire_chip_disconnect(struct usb_interface *intf) | 180 | static void usb6fire_chip_disconnect(struct usb_interface *intf) |
181 | { | 181 | { |
182 | struct sfire_chip *chip; | 182 | struct sfire_chip *chip; |
183 | struct snd_card *card; | 183 | struct snd_card *card; |
184 | 184 | ||
185 | chip = usb_get_intfdata(intf); | 185 | chip = usb_get_intfdata(intf); |
186 | if (chip) { /* if !chip, fw upload has been performed */ | 186 | if (chip) { /* if !chip, fw upload has been performed */ |
187 | card = chip->card; | 187 | card = chip->card; |
188 | chip->intf_count--; | 188 | chip->intf_count--; |
189 | if (!chip->intf_count) { | 189 | if (!chip->intf_count) { |
190 | mutex_lock(®ister_mutex); | 190 | mutex_lock(®ister_mutex); |
191 | devices[chip->regidx] = NULL; | 191 | devices[chip->regidx] = NULL; |
192 | chips[chip->regidx] = NULL; | 192 | chips[chip->regidx] = NULL; |
193 | mutex_unlock(®ister_mutex); | 193 | mutex_unlock(®ister_mutex); |
194 | 194 | ||
195 | chip->shutdown = true; | 195 | chip->shutdown = true; |
196 | usb6fire_chip_abort(chip); | 196 | usb6fire_chip_abort(chip); |
197 | usb6fire_chip_destroy(chip); | 197 | usb6fire_chip_destroy(chip); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | static struct usb_device_id device_table[] = { | 202 | static struct usb_device_id device_table[] = { |
203 | { | 203 | { |
204 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 204 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
205 | .idVendor = 0x0ccd, | 205 | .idVendor = 0x0ccd, |
206 | .idProduct = 0x0080 | 206 | .idProduct = 0x0080 |
207 | }, | 207 | }, |
208 | {} | 208 | {} |
209 | }; | 209 | }; |
210 | 210 | ||
211 | MODULE_DEVICE_TABLE(usb, device_table); | 211 | MODULE_DEVICE_TABLE(usb, device_table); |
212 | 212 | ||
213 | static struct usb_driver usb_driver = { | 213 | static struct usb_driver usb_driver = { |
214 | .name = "snd-usb-6fire", | 214 | .name = "snd-usb-6fire", |
215 | .probe = usb6fire_chip_probe, | 215 | .probe = usb6fire_chip_probe, |
216 | .disconnect = usb6fire_chip_disconnect, | 216 | .disconnect = usb6fire_chip_disconnect, |
217 | .id_table = device_table, | 217 | .id_table = device_table, |
218 | }; | 218 | }; |
219 | 219 | ||
220 | module_usb_driver(usb_driver); | 220 | module_usb_driver(usb_driver); |
221 | 221 |
sound/usb/caiaq/device.c
1 | /* | 1 | /* |
2 | * caiaq.c: ALSA driver for caiaq/NativeInstruments devices | 2 | * caiaq.c: ALSA driver for caiaq/NativeInstruments devices |
3 | * | 3 | * |
4 | * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de> | 4 | * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de> |
5 | * Karsten Wiese <fzu@wemgehoertderstaat.de> | 5 | * Karsten Wiese <fzu@wemgehoertderstaat.de> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/gfp.h> | 27 | #include <linux/gfp.h> |
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
30 | #include <sound/core.h> | 30 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
32 | 32 | ||
33 | #include "device.h" | 33 | #include "device.h" |
34 | #include "audio.h" | 34 | #include "audio.h" |
35 | #include "midi.h" | 35 | #include "midi.h" |
36 | #include "control.h" | 36 | #include "control.h" |
37 | #include "input.h" | 37 | #include "input.h" |
38 | 38 | ||
39 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 39 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
40 | MODULE_DESCRIPTION("caiaq USB audio"); | 40 | MODULE_DESCRIPTION("caiaq USB audio"); |
41 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
42 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | 42 | MODULE_SUPPORTED_DEVICE("{{Native Instruments,RigKontrol2}," |
43 | "{Native Instruments, RigKontrol3}," | 43 | "{Native Instruments,RigKontrol3}," |
44 | "{Native Instruments, Kore Controller}," | 44 | "{Native Instruments,Kore Controller}," |
45 | "{Native Instruments, Kore Controller 2}," | 45 | "{Native Instruments,Kore Controller 2}," |
46 | "{Native Instruments, Audio Kontrol 1}," | 46 | "{Native Instruments,Audio Kontrol 1}," |
47 | "{Native Instruments, Audio 2 DJ}," | 47 | "{Native Instruments,Audio 2 DJ}," |
48 | "{Native Instruments, Audio 4 DJ}," | 48 | "{Native Instruments,Audio 4 DJ}," |
49 | "{Native Instruments, Audio 8 DJ}," | 49 | "{Native Instruments,Audio 8 DJ}," |
50 | "{Native Instruments, Traktor Audio 2}," | 50 | "{Native Instruments,Traktor Audio 2}," |
51 | "{Native Instruments, Session I/O}," | 51 | "{Native Instruments,Session I/O}," |
52 | "{Native Instruments, GuitarRig mobile}," | 52 | "{Native Instruments,GuitarRig mobile}," |
53 | "{Native Instruments, Traktor Kontrol X1}," | 53 | "{Native Instruments,Traktor Kontrol X1}," |
54 | "{Native Instruments, Traktor Kontrol S4}," | 54 | "{Native Instruments,Traktor Kontrol S4}," |
55 | "{Native Instruments, Maschine Controller}}"); | 55 | "{Native Instruments,Maschine Controller}}"); |
56 | 56 | ||
57 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 57 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
58 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 58 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
59 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 59 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ |
60 | 60 | ||
61 | module_param_array(index, int, NULL, 0444); | 61 | module_param_array(index, int, NULL, 0444); |
62 | MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); | 62 | MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); |
63 | module_param_array(id, charp, NULL, 0444); | 63 | module_param_array(id, charp, NULL, 0444); |
64 | MODULE_PARM_DESC(id, "ID string for the caiaq soundcard."); | 64 | MODULE_PARM_DESC(id, "ID string for the caiaq soundcard."); |
65 | module_param_array(enable, bool, NULL, 0444); | 65 | module_param_array(enable, bool, NULL, 0444); |
66 | MODULE_PARM_DESC(enable, "Enable the caiaq soundcard."); | 66 | MODULE_PARM_DESC(enable, "Enable the caiaq soundcard."); |
67 | 67 | ||
68 | enum { | 68 | enum { |
69 | SAMPLERATE_44100 = 0, | 69 | SAMPLERATE_44100 = 0, |
70 | SAMPLERATE_48000 = 1, | 70 | SAMPLERATE_48000 = 1, |
71 | SAMPLERATE_96000 = 2, | 71 | SAMPLERATE_96000 = 2, |
72 | SAMPLERATE_192000 = 3, | 72 | SAMPLERATE_192000 = 3, |
73 | SAMPLERATE_88200 = 4, | 73 | SAMPLERATE_88200 = 4, |
74 | SAMPLERATE_INVALID = 0xff | 74 | SAMPLERATE_INVALID = 0xff |
75 | }; | 75 | }; |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | DEPTH_NONE = 0, | 78 | DEPTH_NONE = 0, |
79 | DEPTH_16 = 1, | 79 | DEPTH_16 = 1, |
80 | DEPTH_24 = 2, | 80 | DEPTH_24 = 2, |
81 | DEPTH_32 = 3 | 81 | DEPTH_32 = 3 |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static struct usb_device_id snd_usb_id_table[] = { | 84 | static struct usb_device_id snd_usb_id_table[] = { |
85 | { | 85 | { |
86 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 86 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
87 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 87 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
88 | .idProduct = USB_PID_RIGKONTROL2 | 88 | .idProduct = USB_PID_RIGKONTROL2 |
89 | }, | 89 | }, |
90 | { | 90 | { |
91 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 91 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
92 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 92 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
93 | .idProduct = USB_PID_RIGKONTROL3 | 93 | .idProduct = USB_PID_RIGKONTROL3 |
94 | }, | 94 | }, |
95 | { | 95 | { |
96 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 96 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
97 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 97 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
98 | .idProduct = USB_PID_KORECONTROLLER | 98 | .idProduct = USB_PID_KORECONTROLLER |
99 | }, | 99 | }, |
100 | { | 100 | { |
101 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 101 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
102 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 102 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
103 | .idProduct = USB_PID_KORECONTROLLER2 | 103 | .idProduct = USB_PID_KORECONTROLLER2 |
104 | }, | 104 | }, |
105 | { | 105 | { |
106 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 106 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
107 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 107 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
108 | .idProduct = USB_PID_AK1 | 108 | .idProduct = USB_PID_AK1 |
109 | }, | 109 | }, |
110 | { | 110 | { |
111 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 111 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
112 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 112 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
113 | .idProduct = USB_PID_AUDIO8DJ | 113 | .idProduct = USB_PID_AUDIO8DJ |
114 | }, | 114 | }, |
115 | { | 115 | { |
116 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 116 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
117 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 117 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
118 | .idProduct = USB_PID_SESSIONIO | 118 | .idProduct = USB_PID_SESSIONIO |
119 | }, | 119 | }, |
120 | { | 120 | { |
121 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 121 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
122 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 122 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
123 | .idProduct = USB_PID_GUITARRIGMOBILE | 123 | .idProduct = USB_PID_GUITARRIGMOBILE |
124 | }, | 124 | }, |
125 | { | 125 | { |
126 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 126 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
127 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 127 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
128 | .idProduct = USB_PID_AUDIO4DJ | 128 | .idProduct = USB_PID_AUDIO4DJ |
129 | }, | 129 | }, |
130 | { | 130 | { |
131 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 131 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
132 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 132 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
133 | .idProduct = USB_PID_AUDIO2DJ | 133 | .idProduct = USB_PID_AUDIO2DJ |
134 | }, | 134 | }, |
135 | { | 135 | { |
136 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 136 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
137 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 137 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
138 | .idProduct = USB_PID_TRAKTORKONTROLX1 | 138 | .idProduct = USB_PID_TRAKTORKONTROLX1 |
139 | }, | 139 | }, |
140 | { | 140 | { |
141 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 141 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
142 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 142 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
143 | .idProduct = USB_PID_TRAKTORKONTROLS4 | 143 | .idProduct = USB_PID_TRAKTORKONTROLS4 |
144 | }, | 144 | }, |
145 | { | 145 | { |
146 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 146 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
147 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 147 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
148 | .idProduct = USB_PID_TRAKTORAUDIO2 | 148 | .idProduct = USB_PID_TRAKTORAUDIO2 |
149 | }, | 149 | }, |
150 | { | 150 | { |
151 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 151 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
152 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 152 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
153 | .idProduct = USB_PID_MASCHINECONTROLLER | 153 | .idProduct = USB_PID_MASCHINECONTROLLER |
154 | }, | 154 | }, |
155 | { /* terminator */ } | 155 | { /* terminator */ } |
156 | }; | 156 | }; |
157 | 157 | ||
158 | static void usb_ep1_command_reply_dispatch (struct urb* urb) | 158 | static void usb_ep1_command_reply_dispatch (struct urb* urb) |
159 | { | 159 | { |
160 | int ret; | 160 | int ret; |
161 | struct device *dev = &urb->dev->dev; | 161 | struct device *dev = &urb->dev->dev; |
162 | struct snd_usb_caiaqdev *cdev = urb->context; | 162 | struct snd_usb_caiaqdev *cdev = urb->context; |
163 | unsigned char *buf = urb->transfer_buffer; | 163 | unsigned char *buf = urb->transfer_buffer; |
164 | 164 | ||
165 | if (urb->status || !cdev) { | 165 | if (urb->status || !cdev) { |
166 | dev_warn(dev, "received EP1 urb->status = %i\n", urb->status); | 166 | dev_warn(dev, "received EP1 urb->status = %i\n", urb->status); |
167 | return; | 167 | return; |
168 | } | 168 | } |
169 | 169 | ||
170 | switch(buf[0]) { | 170 | switch(buf[0]) { |
171 | case EP1_CMD_GET_DEVICE_INFO: | 171 | case EP1_CMD_GET_DEVICE_INFO: |
172 | memcpy(&cdev->spec, buf+1, sizeof(struct caiaq_device_spec)); | 172 | memcpy(&cdev->spec, buf+1, sizeof(struct caiaq_device_spec)); |
173 | cdev->spec.fw_version = le16_to_cpu(cdev->spec.fw_version); | 173 | cdev->spec.fw_version = le16_to_cpu(cdev->spec.fw_version); |
174 | dev_dbg(dev, "device spec (firmware %d): audio: %d in, %d out, " | 174 | dev_dbg(dev, "device spec (firmware %d): audio: %d in, %d out, " |
175 | "MIDI: %d in, %d out, data alignment %d\n", | 175 | "MIDI: %d in, %d out, data alignment %d\n", |
176 | cdev->spec.fw_version, | 176 | cdev->spec.fw_version, |
177 | cdev->spec.num_analog_audio_in, | 177 | cdev->spec.num_analog_audio_in, |
178 | cdev->spec.num_analog_audio_out, | 178 | cdev->spec.num_analog_audio_out, |
179 | cdev->spec.num_midi_in, | 179 | cdev->spec.num_midi_in, |
180 | cdev->spec.num_midi_out, | 180 | cdev->spec.num_midi_out, |
181 | cdev->spec.data_alignment); | 181 | cdev->spec.data_alignment); |
182 | 182 | ||
183 | cdev->spec_received++; | 183 | cdev->spec_received++; |
184 | wake_up(&cdev->ep1_wait_queue); | 184 | wake_up(&cdev->ep1_wait_queue); |
185 | break; | 185 | break; |
186 | case EP1_CMD_AUDIO_PARAMS: | 186 | case EP1_CMD_AUDIO_PARAMS: |
187 | cdev->audio_parm_answer = buf[1]; | 187 | cdev->audio_parm_answer = buf[1]; |
188 | wake_up(&cdev->ep1_wait_queue); | 188 | wake_up(&cdev->ep1_wait_queue); |
189 | break; | 189 | break; |
190 | case EP1_CMD_MIDI_READ: | 190 | case EP1_CMD_MIDI_READ: |
191 | snd_usb_caiaq_midi_handle_input(cdev, buf[1], buf + 3, buf[2]); | 191 | snd_usb_caiaq_midi_handle_input(cdev, buf[1], buf + 3, buf[2]); |
192 | break; | 192 | break; |
193 | case EP1_CMD_READ_IO: | 193 | case EP1_CMD_READ_IO: |
194 | if (cdev->chip.usb_id == | 194 | if (cdev->chip.usb_id == |
195 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { | 195 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { |
196 | if (urb->actual_length > sizeof(cdev->control_state)) | 196 | if (urb->actual_length > sizeof(cdev->control_state)) |
197 | urb->actual_length = sizeof(cdev->control_state); | 197 | urb->actual_length = sizeof(cdev->control_state); |
198 | memcpy(cdev->control_state, buf + 1, urb->actual_length); | 198 | memcpy(cdev->control_state, buf + 1, urb->actual_length); |
199 | wake_up(&cdev->ep1_wait_queue); | 199 | wake_up(&cdev->ep1_wait_queue); |
200 | break; | 200 | break; |
201 | } | 201 | } |
202 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 202 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
203 | case EP1_CMD_READ_ERP: | 203 | case EP1_CMD_READ_ERP: |
204 | case EP1_CMD_READ_ANALOG: | 204 | case EP1_CMD_READ_ANALOG: |
205 | snd_usb_caiaq_input_dispatch(cdev, buf, urb->actual_length); | 205 | snd_usb_caiaq_input_dispatch(cdev, buf, urb->actual_length); |
206 | #endif | 206 | #endif |
207 | break; | 207 | break; |
208 | } | 208 | } |
209 | 209 | ||
210 | cdev->ep1_in_urb.actual_length = 0; | 210 | cdev->ep1_in_urb.actual_length = 0; |
211 | ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC); | 211 | ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC); |
212 | if (ret < 0) | 212 | if (ret < 0) |
213 | dev_err(dev, "unable to submit urb. OOM!?\n"); | 213 | dev_err(dev, "unable to submit urb. OOM!?\n"); |
214 | } | 214 | } |
215 | 215 | ||
216 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, | 216 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, |
217 | unsigned char command, | 217 | unsigned char command, |
218 | const unsigned char *buffer, | 218 | const unsigned char *buffer, |
219 | int len) | 219 | int len) |
220 | { | 220 | { |
221 | int actual_len; | 221 | int actual_len; |
222 | struct usb_device *usb_dev = cdev->chip.dev; | 222 | struct usb_device *usb_dev = cdev->chip.dev; |
223 | 223 | ||
224 | if (!usb_dev) | 224 | if (!usb_dev) |
225 | return -EIO; | 225 | return -EIO; |
226 | 226 | ||
227 | if (len > EP1_BUFSIZE - 1) | 227 | if (len > EP1_BUFSIZE - 1) |
228 | len = EP1_BUFSIZE - 1; | 228 | len = EP1_BUFSIZE - 1; |
229 | 229 | ||
230 | if (buffer && len > 0) | 230 | if (buffer && len > 0) |
231 | memcpy(cdev->ep1_out_buf+1, buffer, len); | 231 | memcpy(cdev->ep1_out_buf+1, buffer, len); |
232 | 232 | ||
233 | cdev->ep1_out_buf[0] = command; | 233 | cdev->ep1_out_buf[0] = command; |
234 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), | 234 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), |
235 | cdev->ep1_out_buf, len+1, &actual_len, 200); | 235 | cdev->ep1_out_buf, len+1, &actual_len, 200); |
236 | } | 236 | } |
237 | 237 | ||
238 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev, | 238 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev, |
239 | int rate, int depth, int bpp) | 239 | int rate, int depth, int bpp) |
240 | { | 240 | { |
241 | int ret; | 241 | int ret; |
242 | char tmp[5]; | 242 | char tmp[5]; |
243 | struct device *dev = caiaqdev_to_dev(cdev); | 243 | struct device *dev = caiaqdev_to_dev(cdev); |
244 | 244 | ||
245 | switch (rate) { | 245 | switch (rate) { |
246 | case 44100: tmp[0] = SAMPLERATE_44100; break; | 246 | case 44100: tmp[0] = SAMPLERATE_44100; break; |
247 | case 48000: tmp[0] = SAMPLERATE_48000; break; | 247 | case 48000: tmp[0] = SAMPLERATE_48000; break; |
248 | case 88200: tmp[0] = SAMPLERATE_88200; break; | 248 | case 88200: tmp[0] = SAMPLERATE_88200; break; |
249 | case 96000: tmp[0] = SAMPLERATE_96000; break; | 249 | case 96000: tmp[0] = SAMPLERATE_96000; break; |
250 | case 192000: tmp[0] = SAMPLERATE_192000; break; | 250 | case 192000: tmp[0] = SAMPLERATE_192000; break; |
251 | default: return -EINVAL; | 251 | default: return -EINVAL; |
252 | } | 252 | } |
253 | 253 | ||
254 | switch (depth) { | 254 | switch (depth) { |
255 | case 16: tmp[1] = DEPTH_16; break; | 255 | case 16: tmp[1] = DEPTH_16; break; |
256 | case 24: tmp[1] = DEPTH_24; break; | 256 | case 24: tmp[1] = DEPTH_24; break; |
257 | default: return -EINVAL; | 257 | default: return -EINVAL; |
258 | } | 258 | } |
259 | 259 | ||
260 | tmp[2] = bpp & 0xff; | 260 | tmp[2] = bpp & 0xff; |
261 | tmp[3] = bpp >> 8; | 261 | tmp[3] = bpp >> 8; |
262 | tmp[4] = 1; /* packets per microframe */ | 262 | tmp[4] = 1; /* packets per microframe */ |
263 | 263 | ||
264 | dev_dbg(dev, "setting audio params: %d Hz, %d bits, %d bpp\n", | 264 | dev_dbg(dev, "setting audio params: %d Hz, %d bits, %d bpp\n", |
265 | rate, depth, bpp); | 265 | rate, depth, bpp); |
266 | 266 | ||
267 | cdev->audio_parm_answer = -1; | 267 | cdev->audio_parm_answer = -1; |
268 | ret = snd_usb_caiaq_send_command(cdev, EP1_CMD_AUDIO_PARAMS, | 268 | ret = snd_usb_caiaq_send_command(cdev, EP1_CMD_AUDIO_PARAMS, |
269 | tmp, sizeof(tmp)); | 269 | tmp, sizeof(tmp)); |
270 | 270 | ||
271 | if (ret) | 271 | if (ret) |
272 | return ret; | 272 | return ret; |
273 | 273 | ||
274 | if (!wait_event_timeout(cdev->ep1_wait_queue, | 274 | if (!wait_event_timeout(cdev->ep1_wait_queue, |
275 | cdev->audio_parm_answer >= 0, HZ)) | 275 | cdev->audio_parm_answer >= 0, HZ)) |
276 | return -EPIPE; | 276 | return -EPIPE; |
277 | 277 | ||
278 | if (cdev->audio_parm_answer != 1) | 278 | if (cdev->audio_parm_answer != 1) |
279 | dev_dbg(dev, "unable to set the device's audio params\n"); | 279 | dev_dbg(dev, "unable to set the device's audio params\n"); |
280 | else | 280 | else |
281 | cdev->bpp = bpp; | 281 | cdev->bpp = bpp; |
282 | 282 | ||
283 | return cdev->audio_parm_answer == 1 ? 0 : -EINVAL; | 283 | return cdev->audio_parm_answer == 1 ? 0 : -EINVAL; |
284 | } | 284 | } |
285 | 285 | ||
286 | int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev, | 286 | int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev, |
287 | int digital, int analog, int erp) | 287 | int digital, int analog, int erp) |
288 | { | 288 | { |
289 | char tmp[3] = { digital, analog, erp }; | 289 | char tmp[3] = { digital, analog, erp }; |
290 | return snd_usb_caiaq_send_command(cdev, EP1_CMD_AUTO_MSG, | 290 | return snd_usb_caiaq_send_command(cdev, EP1_CMD_AUTO_MSG, |
291 | tmp, sizeof(tmp)); | 291 | tmp, sizeof(tmp)); |
292 | } | 292 | } |
293 | 293 | ||
294 | static void setup_card(struct snd_usb_caiaqdev *cdev) | 294 | static void setup_card(struct snd_usb_caiaqdev *cdev) |
295 | { | 295 | { |
296 | int ret; | 296 | int ret; |
297 | char val[4]; | 297 | char val[4]; |
298 | struct device *dev = caiaqdev_to_dev(cdev); | 298 | struct device *dev = caiaqdev_to_dev(cdev); |
299 | 299 | ||
300 | /* device-specific startup specials */ | 300 | /* device-specific startup specials */ |
301 | switch (cdev->chip.usb_id) { | 301 | switch (cdev->chip.usb_id) { |
302 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 302 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
303 | /* RigKontrol2 - display centered dash ('-') */ | 303 | /* RigKontrol2 - display centered dash ('-') */ |
304 | val[0] = 0x00; | 304 | val[0] = 0x00; |
305 | val[1] = 0x00; | 305 | val[1] = 0x00; |
306 | val[2] = 0x01; | 306 | val[2] = 0x01; |
307 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 3); | 307 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 3); |
308 | break; | 308 | break; |
309 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 309 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
310 | /* RigKontrol2 - display two centered dashes ('--') */ | 310 | /* RigKontrol2 - display two centered dashes ('--') */ |
311 | val[0] = 0x00; | 311 | val[0] = 0x00; |
312 | val[1] = 0x40; | 312 | val[1] = 0x40; |
313 | val[2] = 0x40; | 313 | val[2] = 0x40; |
314 | val[3] = 0x00; | 314 | val[3] = 0x00; |
315 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 4); | 315 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 4); |
316 | break; | 316 | break; |
317 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 317 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
318 | /* Audio Kontrol 1 - make USB-LED stop blinking */ | 318 | /* Audio Kontrol 1 - make USB-LED stop blinking */ |
319 | val[0] = 0x00; | 319 | val[0] = 0x00; |
320 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 1); | 320 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 1); |
321 | break; | 321 | break; |
322 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 322 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
323 | /* Audio 8 DJ - trigger read of current settings */ | 323 | /* Audio 8 DJ - trigger read of current settings */ |
324 | cdev->control_state[0] = 0xff; | 324 | cdev->control_state[0] = 0xff; |
325 | snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 0); | 325 | snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 0); |
326 | snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0); | 326 | snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0); |
327 | 327 | ||
328 | if (!wait_event_timeout(cdev->ep1_wait_queue, | 328 | if (!wait_event_timeout(cdev->ep1_wait_queue, |
329 | cdev->control_state[0] != 0xff, HZ)) | 329 | cdev->control_state[0] != 0xff, HZ)) |
330 | return; | 330 | return; |
331 | 331 | ||
332 | /* fix up some defaults */ | 332 | /* fix up some defaults */ |
333 | if ((cdev->control_state[1] != 2) || | 333 | if ((cdev->control_state[1] != 2) || |
334 | (cdev->control_state[2] != 3) || | 334 | (cdev->control_state[2] != 3) || |
335 | (cdev->control_state[4] != 2)) { | 335 | (cdev->control_state[4] != 2)) { |
336 | cdev->control_state[1] = 2; | 336 | cdev->control_state[1] = 2; |
337 | cdev->control_state[2] = 3; | 337 | cdev->control_state[2] = 3; |
338 | cdev->control_state[4] = 2; | 338 | cdev->control_state[4] = 2; |
339 | snd_usb_caiaq_send_command(cdev, | 339 | snd_usb_caiaq_send_command(cdev, |
340 | EP1_CMD_WRITE_IO, cdev->control_state, 6); | 340 | EP1_CMD_WRITE_IO, cdev->control_state, 6); |
341 | } | 341 | } |
342 | 342 | ||
343 | break; | 343 | break; |
344 | } | 344 | } |
345 | 345 | ||
346 | if (cdev->spec.num_analog_audio_out + | 346 | if (cdev->spec.num_analog_audio_out + |
347 | cdev->spec.num_analog_audio_in + | 347 | cdev->spec.num_analog_audio_in + |
348 | cdev->spec.num_digital_audio_out + | 348 | cdev->spec.num_digital_audio_out + |
349 | cdev->spec.num_digital_audio_in > 0) { | 349 | cdev->spec.num_digital_audio_in > 0) { |
350 | ret = snd_usb_caiaq_audio_init(cdev); | 350 | ret = snd_usb_caiaq_audio_init(cdev); |
351 | if (ret < 0) | 351 | if (ret < 0) |
352 | dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret); | 352 | dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret); |
353 | } | 353 | } |
354 | 354 | ||
355 | if (cdev->spec.num_midi_in + | 355 | if (cdev->spec.num_midi_in + |
356 | cdev->spec.num_midi_out > 0) { | 356 | cdev->spec.num_midi_out > 0) { |
357 | ret = snd_usb_caiaq_midi_init(cdev); | 357 | ret = snd_usb_caiaq_midi_init(cdev); |
358 | if (ret < 0) | 358 | if (ret < 0) |
359 | dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret); | 359 | dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret); |
360 | } | 360 | } |
361 | 361 | ||
362 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 362 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
363 | ret = snd_usb_caiaq_input_init(cdev); | 363 | ret = snd_usb_caiaq_input_init(cdev); |
364 | if (ret < 0) | 364 | if (ret < 0) |
365 | dev_err(dev, "Unable to set up input system (ret=%d)\n", ret); | 365 | dev_err(dev, "Unable to set up input system (ret=%d)\n", ret); |
366 | #endif | 366 | #endif |
367 | 367 | ||
368 | /* finally, register the card and all its sub-instances */ | 368 | /* finally, register the card and all its sub-instances */ |
369 | ret = snd_card_register(cdev->chip.card); | 369 | ret = snd_card_register(cdev->chip.card); |
370 | if (ret < 0) { | 370 | if (ret < 0) { |
371 | dev_err(dev, "snd_card_register() returned %d\n", ret); | 371 | dev_err(dev, "snd_card_register() returned %d\n", ret); |
372 | snd_card_free(cdev->chip.card); | 372 | snd_card_free(cdev->chip.card); |
373 | } | 373 | } |
374 | 374 | ||
375 | ret = snd_usb_caiaq_control_init(cdev); | 375 | ret = snd_usb_caiaq_control_init(cdev); |
376 | if (ret < 0) | 376 | if (ret < 0) |
377 | dev_err(dev, "Unable to set up control system (ret=%d)\n", ret); | 377 | dev_err(dev, "Unable to set up control system (ret=%d)\n", ret); |
378 | } | 378 | } |
379 | 379 | ||
380 | static int create_card(struct usb_device *usb_dev, | 380 | static int create_card(struct usb_device *usb_dev, |
381 | struct usb_interface *intf, | 381 | struct usb_interface *intf, |
382 | struct snd_card **cardp) | 382 | struct snd_card **cardp) |
383 | { | 383 | { |
384 | int devnum; | 384 | int devnum; |
385 | int err; | 385 | int err; |
386 | struct snd_card *card; | 386 | struct snd_card *card; |
387 | struct snd_usb_caiaqdev *cdev; | 387 | struct snd_usb_caiaqdev *cdev; |
388 | 388 | ||
389 | for (devnum = 0; devnum < SNDRV_CARDS; devnum++) | 389 | for (devnum = 0; devnum < SNDRV_CARDS; devnum++) |
390 | if (enable[devnum]) | 390 | if (enable[devnum]) |
391 | break; | 391 | break; |
392 | 392 | ||
393 | if (devnum >= SNDRV_CARDS) | 393 | if (devnum >= SNDRV_CARDS) |
394 | return -ENODEV; | 394 | return -ENODEV; |
395 | 395 | ||
396 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, | 396 | err = snd_card_create(index[devnum], id[devnum], THIS_MODULE, |
397 | sizeof(struct snd_usb_caiaqdev), &card); | 397 | sizeof(struct snd_usb_caiaqdev), &card); |
398 | if (err < 0) | 398 | if (err < 0) |
399 | return err; | 399 | return err; |
400 | 400 | ||
401 | cdev = caiaqdev(card); | 401 | cdev = caiaqdev(card); |
402 | cdev->chip.dev = usb_dev; | 402 | cdev->chip.dev = usb_dev; |
403 | cdev->chip.card = card; | 403 | cdev->chip.card = card; |
404 | cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), | 404 | cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), |
405 | le16_to_cpu(usb_dev->descriptor.idProduct)); | 405 | le16_to_cpu(usb_dev->descriptor.idProduct)); |
406 | spin_lock_init(&cdev->spinlock); | 406 | spin_lock_init(&cdev->spinlock); |
407 | snd_card_set_dev(card, &intf->dev); | 407 | snd_card_set_dev(card, &intf->dev); |
408 | 408 | ||
409 | *cardp = card; | 409 | *cardp = card; |
410 | return 0; | 410 | return 0; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int init_card(struct snd_usb_caiaqdev *cdev) | 413 | static int init_card(struct snd_usb_caiaqdev *cdev) |
414 | { | 414 | { |
415 | char *c, usbpath[32]; | 415 | char *c, usbpath[32]; |
416 | struct usb_device *usb_dev = cdev->chip.dev; | 416 | struct usb_device *usb_dev = cdev->chip.dev; |
417 | struct snd_card *card = cdev->chip.card; | 417 | struct snd_card *card = cdev->chip.card; |
418 | struct device *dev = caiaqdev_to_dev(cdev); | 418 | struct device *dev = caiaqdev_to_dev(cdev); |
419 | int err, len; | 419 | int err, len; |
420 | 420 | ||
421 | if (usb_set_interface(usb_dev, 0, 1) != 0) { | 421 | if (usb_set_interface(usb_dev, 0, 1) != 0) { |
422 | dev_err(dev, "can't set alt interface.\n"); | 422 | dev_err(dev, "can't set alt interface.\n"); |
423 | return -EIO; | 423 | return -EIO; |
424 | } | 424 | } |
425 | 425 | ||
426 | usb_init_urb(&cdev->ep1_in_urb); | 426 | usb_init_urb(&cdev->ep1_in_urb); |
427 | usb_init_urb(&cdev->midi_out_urb); | 427 | usb_init_urb(&cdev->midi_out_urb); |
428 | 428 | ||
429 | usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev, | 429 | usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev, |
430 | usb_rcvbulkpipe(usb_dev, 0x1), | 430 | usb_rcvbulkpipe(usb_dev, 0x1), |
431 | cdev->ep1_in_buf, EP1_BUFSIZE, | 431 | cdev->ep1_in_buf, EP1_BUFSIZE, |
432 | usb_ep1_command_reply_dispatch, cdev); | 432 | usb_ep1_command_reply_dispatch, cdev); |
433 | 433 | ||
434 | usb_fill_bulk_urb(&cdev->midi_out_urb, usb_dev, | 434 | usb_fill_bulk_urb(&cdev->midi_out_urb, usb_dev, |
435 | usb_sndbulkpipe(usb_dev, 0x1), | 435 | usb_sndbulkpipe(usb_dev, 0x1), |
436 | cdev->midi_out_buf, EP1_BUFSIZE, | 436 | cdev->midi_out_buf, EP1_BUFSIZE, |
437 | snd_usb_caiaq_midi_output_done, cdev); | 437 | snd_usb_caiaq_midi_output_done, cdev); |
438 | 438 | ||
439 | init_waitqueue_head(&cdev->ep1_wait_queue); | 439 | init_waitqueue_head(&cdev->ep1_wait_queue); |
440 | init_waitqueue_head(&cdev->prepare_wait_queue); | 440 | init_waitqueue_head(&cdev->prepare_wait_queue); |
441 | 441 | ||
442 | if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0) | 442 | if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0) |
443 | return -EIO; | 443 | return -EIO; |
444 | 444 | ||
445 | err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); | 445 | err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); |
446 | if (err) | 446 | if (err) |
447 | return err; | 447 | return err; |
448 | 448 | ||
449 | if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) | 449 | if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) |
450 | return -ENODEV; | 450 | return -ENODEV; |
451 | 451 | ||
452 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, | 452 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, |
453 | cdev->vendor_name, CAIAQ_USB_STR_LEN); | 453 | cdev->vendor_name, CAIAQ_USB_STR_LEN); |
454 | 454 | ||
455 | usb_string(usb_dev, usb_dev->descriptor.iProduct, | 455 | usb_string(usb_dev, usb_dev->descriptor.iProduct, |
456 | cdev->product_name, CAIAQ_USB_STR_LEN); | 456 | cdev->product_name, CAIAQ_USB_STR_LEN); |
457 | 457 | ||
458 | strlcpy(card->driver, MODNAME, sizeof(card->driver)); | 458 | strlcpy(card->driver, MODNAME, sizeof(card->driver)); |
459 | strlcpy(card->shortname, cdev->product_name, sizeof(card->shortname)); | 459 | strlcpy(card->shortname, cdev->product_name, sizeof(card->shortname)); |
460 | strlcpy(card->mixername, cdev->product_name, sizeof(card->mixername)); | 460 | strlcpy(card->mixername, cdev->product_name, sizeof(card->mixername)); |
461 | 461 | ||
462 | /* if the id was not passed as module option, fill it with a shortened | 462 | /* if the id was not passed as module option, fill it with a shortened |
463 | * version of the product string which does not contain any | 463 | * version of the product string which does not contain any |
464 | * whitespaces */ | 464 | * whitespaces */ |
465 | 465 | ||
466 | if (*card->id == '\0') { | 466 | if (*card->id == '\0') { |
467 | char id[sizeof(card->id)]; | 467 | char id[sizeof(card->id)]; |
468 | 468 | ||
469 | memset(id, 0, sizeof(id)); | 469 | memset(id, 0, sizeof(id)); |
470 | 470 | ||
471 | for (c = card->shortname, len = 0; | 471 | for (c = card->shortname, len = 0; |
472 | *c && len < sizeof(card->id); c++) | 472 | *c && len < sizeof(card->id); c++) |
473 | if (*c != ' ') | 473 | if (*c != ' ') |
474 | id[len++] = *c; | 474 | id[len++] = *c; |
475 | 475 | ||
476 | snd_card_set_id(card, id); | 476 | snd_card_set_id(card, id); |
477 | } | 477 | } |
478 | 478 | ||
479 | usb_make_path(usb_dev, usbpath, sizeof(usbpath)); | 479 | usb_make_path(usb_dev, usbpath, sizeof(usbpath)); |
480 | snprintf(card->longname, sizeof(card->longname), "%s %s (%s)", | 480 | snprintf(card->longname, sizeof(card->longname), "%s %s (%s)", |
481 | cdev->vendor_name, cdev->product_name, usbpath); | 481 | cdev->vendor_name, cdev->product_name, usbpath); |
482 | 482 | ||
483 | setup_card(cdev); | 483 | setup_card(cdev); |
484 | return 0; | 484 | return 0; |
485 | } | 485 | } |
486 | 486 | ||
487 | static int snd_probe(struct usb_interface *intf, | 487 | static int snd_probe(struct usb_interface *intf, |
488 | const struct usb_device_id *id) | 488 | const struct usb_device_id *id) |
489 | { | 489 | { |
490 | int ret; | 490 | int ret; |
491 | struct snd_card *card = NULL; | 491 | struct snd_card *card = NULL; |
492 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 492 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
493 | 493 | ||
494 | ret = create_card(usb_dev, intf, &card); | 494 | ret = create_card(usb_dev, intf, &card); |
495 | 495 | ||
496 | if (ret < 0) | 496 | if (ret < 0) |
497 | return ret; | 497 | return ret; |
498 | 498 | ||
499 | usb_set_intfdata(intf, card); | 499 | usb_set_intfdata(intf, card); |
500 | ret = init_card(caiaqdev(card)); | 500 | ret = init_card(caiaqdev(card)); |
501 | if (ret < 0) { | 501 | if (ret < 0) { |
502 | dev_err(&usb_dev->dev, "unable to init card! (ret=%d)\n", ret); | 502 | dev_err(&usb_dev->dev, "unable to init card! (ret=%d)\n", ret); |
503 | snd_card_free(card); | 503 | snd_card_free(card); |
504 | return ret; | 504 | return ret; |
505 | } | 505 | } |
506 | 506 | ||
507 | return 0; | 507 | return 0; |
508 | } | 508 | } |
509 | 509 | ||
510 | static void snd_disconnect(struct usb_interface *intf) | 510 | static void snd_disconnect(struct usb_interface *intf) |
511 | { | 511 | { |
512 | struct snd_card *card = usb_get_intfdata(intf); | 512 | struct snd_card *card = usb_get_intfdata(intf); |
513 | struct device *dev = intf->usb_dev; | 513 | struct device *dev = intf->usb_dev; |
514 | struct snd_usb_caiaqdev *cdev; | 514 | struct snd_usb_caiaqdev *cdev; |
515 | 515 | ||
516 | if (!card) | 516 | if (!card) |
517 | return; | 517 | return; |
518 | 518 | ||
519 | cdev = caiaqdev(card); | 519 | cdev = caiaqdev(card); |
520 | dev_dbg(dev, "%s(%p)\n", __func__, intf); | 520 | dev_dbg(dev, "%s(%p)\n", __func__, intf); |
521 | 521 | ||
522 | snd_card_disconnect(card); | 522 | snd_card_disconnect(card); |
523 | 523 | ||
524 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 524 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
525 | snd_usb_caiaq_input_free(cdev); | 525 | snd_usb_caiaq_input_free(cdev); |
526 | #endif | 526 | #endif |
527 | snd_usb_caiaq_audio_free(cdev); | 527 | snd_usb_caiaq_audio_free(cdev); |
528 | 528 | ||
529 | usb_kill_urb(&cdev->ep1_in_urb); | 529 | usb_kill_urb(&cdev->ep1_in_urb); |
530 | usb_kill_urb(&cdev->midi_out_urb); | 530 | usb_kill_urb(&cdev->midi_out_urb); |
531 | 531 | ||
532 | snd_card_free(card); | 532 | snd_card_free(card); |
533 | usb_reset_device(interface_to_usbdev(intf)); | 533 | usb_reset_device(interface_to_usbdev(intf)); |
534 | } | 534 | } |
535 | 535 | ||
536 | 536 | ||
537 | MODULE_DEVICE_TABLE(usb, snd_usb_id_table); | 537 | MODULE_DEVICE_TABLE(usb, snd_usb_id_table); |
538 | static struct usb_driver snd_usb_driver = { | 538 | static struct usb_driver snd_usb_driver = { |
539 | .name = MODNAME, | 539 | .name = MODNAME, |
540 | .probe = snd_probe, | 540 | .probe = snd_probe, |
541 | .disconnect = snd_disconnect, | 541 | .disconnect = snd_disconnect, |
542 | .id_table = snd_usb_id_table, | 542 | .id_table = snd_usb_id_table, |
543 | }; | 543 | }; |
544 | 544 | ||
545 | module_usb_driver(snd_usb_driver); | 545 | module_usb_driver(snd_usb_driver); |
546 | 546 |
sound/usb/usx2y/usbusx2y.c
1 | /* | 1 | /* |
2 | * usbusy2y.c - ALSA USB US-428 Driver | 2 | * usbusy2y.c - ALSA USB US-428 Driver |
3 | * | 3 | * |
4 | 2005-04-14 Karsten Wiese | 4 | 2005-04-14 Karsten Wiese |
5 | Version 0.8.7.2: | 5 | Version 0.8.7.2: |
6 | Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. | 6 | Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. |
7 | Tested ok with kernel 2.6.12-rc2. | 7 | Tested ok with kernel 2.6.12-rc2. |
8 | 8 | ||
9 | 2004-12-14 Karsten Wiese | 9 | 2004-12-14 Karsten Wiese |
10 | Version 0.8.7.1: | 10 | Version 0.8.7.1: |
11 | snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. | 11 | snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. |
12 | 12 | ||
13 | 2004-12-02 Karsten Wiese | 13 | 2004-12-02 Karsten Wiese |
14 | Version 0.8.7: | 14 | Version 0.8.7: |
15 | Use macro usb_maxpacket() for portability. | 15 | Use macro usb_maxpacket() for portability. |
16 | 16 | ||
17 | 2004-10-26 Karsten Wiese | 17 | 2004-10-26 Karsten Wiese |
18 | Version 0.8.6: | 18 | Version 0.8.6: |
19 | wake_up() process waiting in usX2Y_urbs_start() on error. | 19 | wake_up() process waiting in usX2Y_urbs_start() on error. |
20 | 20 | ||
21 | 2004-10-21 Karsten Wiese | 21 | 2004-10-21 Karsten Wiese |
22 | Version 0.8.5: | 22 | Version 0.8.5: |
23 | nrpacks is runtime or compiletime configurable now with tested values from 1 to 4. | 23 | nrpacks is runtime or compiletime configurable now with tested values from 1 to 4. |
24 | 24 | ||
25 | 2004-10-03 Karsten Wiese | 25 | 2004-10-03 Karsten Wiese |
26 | Version 0.8.2: | 26 | Version 0.8.2: |
27 | Avoid any possible racing while in prepare callback. | 27 | Avoid any possible racing while in prepare callback. |
28 | 28 | ||
29 | 2004-09-30 Karsten Wiese | 29 | 2004-09-30 Karsten Wiese |
30 | Version 0.8.0: | 30 | Version 0.8.0: |
31 | Simplified things and made ohci work again. | 31 | Simplified things and made ohci work again. |
32 | 32 | ||
33 | 2004-09-20 Karsten Wiese | 33 | 2004-09-20 Karsten Wiese |
34 | Version 0.7.3: | 34 | Version 0.7.3: |
35 | Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb(). | 35 | Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb(). |
36 | 36 | ||
37 | 2004-07-13 Karsten Wiese | 37 | 2004-07-13 Karsten Wiese |
38 | Version 0.7.1: | 38 | Version 0.7.1: |
39 | Don't sleep in START/STOP callbacks anymore. | 39 | Don't sleep in START/STOP callbacks anymore. |
40 | us428 channels C/D not handled just for this version, sorry. | 40 | us428 channels C/D not handled just for this version, sorry. |
41 | 41 | ||
42 | 2004-06-21 Karsten Wiese | 42 | 2004-06-21 Karsten Wiese |
43 | Version 0.6.4: | 43 | Version 0.6.4: |
44 | Temporarely suspend midi input | 44 | Temporarely suspend midi input |
45 | to sanely call usb_set_interface() when setting format. | 45 | to sanely call usb_set_interface() when setting format. |
46 | 46 | ||
47 | 2004-06-12 Karsten Wiese | 47 | 2004-06-12 Karsten Wiese |
48 | Version 0.6.3: | 48 | Version 0.6.3: |
49 | Made it thus the following rule is enforced: | 49 | Made it thus the following rule is enforced: |
50 | "All pcm substreams of one usX2Y have to operate at the same rate & format." | 50 | "All pcm substreams of one usX2Y have to operate at the same rate & format." |
51 | 51 | ||
52 | 2004-04-06 Karsten Wiese | 52 | 2004-04-06 Karsten Wiese |
53 | Version 0.6.0: | 53 | Version 0.6.0: |
54 | Runs on 2.6.5 kernel without any "--with-debug=" things. | 54 | Runs on 2.6.5 kernel without any "--with-debug=" things. |
55 | us224 reported running. | 55 | us224 reported running. |
56 | 56 | ||
57 | 2004-01-14 Karsten Wiese | 57 | 2004-01-14 Karsten Wiese |
58 | Version 0.5.1: | 58 | Version 0.5.1: |
59 | Runs with 2.6.1 kernel. | 59 | Runs with 2.6.1 kernel. |
60 | 60 | ||
61 | 2003-12-30 Karsten Wiese | 61 | 2003-12-30 Karsten Wiese |
62 | Version 0.4.1: | 62 | Version 0.4.1: |
63 | Fix 24Bit 4Channel capturing for the us428. | 63 | Fix 24Bit 4Channel capturing for the us428. |
64 | 64 | ||
65 | 2003-11-27 Karsten Wiese, Martin Langer | 65 | 2003-11-27 Karsten Wiese, Martin Langer |
66 | Version 0.4: | 66 | Version 0.4: |
67 | us122 support. | 67 | us122 support. |
68 | us224 could be tested by uncommenting the sections containing USB_ID_US224 | 68 | us224 could be tested by uncommenting the sections containing USB_ID_US224 |
69 | 69 | ||
70 | 2003-11-03 Karsten Wiese | 70 | 2003-11-03 Karsten Wiese |
71 | Version 0.3: | 71 | Version 0.3: |
72 | 24Bit support. | 72 | 24Bit support. |
73 | "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works. | 73 | "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works. |
74 | 74 | ||
75 | 2003-08-22 Karsten Wiese | 75 | 2003-08-22 Karsten Wiese |
76 | Version 0.0.8: | 76 | Version 0.0.8: |
77 | Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader. | 77 | Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader. |
78 | See: | 78 | See: |
79 | http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz | 79 | http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz |
80 | 80 | ||
81 | 2003-06-18 Karsten Wiese | 81 | 2003-06-18 Karsten Wiese |
82 | Version 0.0.5: | 82 | Version 0.0.5: |
83 | changed to compile with kernel 2.4.21 and alsa 0.9.4 | 83 | changed to compile with kernel 2.4.21 and alsa 0.9.4 |
84 | 84 | ||
85 | 2002-10-16 Karsten Wiese | 85 | 2002-10-16 Karsten Wiese |
86 | Version 0.0.4: | 86 | Version 0.0.4: |
87 | compiles again with alsa-current. | 87 | compiles again with alsa-current. |
88 | USB_ISO_ASAP not used anymore (most of the time), instead | 88 | USB_ISO_ASAP not used anymore (most of the time), instead |
89 | urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore. | 89 | urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore. |
90 | 90 | ||
91 | To get the best out of this: | 91 | To get the best out of this: |
92 | Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds. | 92 | Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds. |
93 | This helped me much on my slowish PII 400 & PIII 500. | 93 | This helped me much on my slowish PII 400 & PIII 500. |
94 | ACPI yet untested but might cause the same bad behaviour. | 94 | ACPI yet untested but might cause the same bad behaviour. |
95 | Use a kernel with lowlatency and preemptiv patches applied. | 95 | Use a kernel with lowlatency and preemptiv patches applied. |
96 | To autoload snd-usb-midi append a line | 96 | To autoload snd-usb-midi append a line |
97 | post-install snd-usb-us428 modprobe snd-usb-midi | 97 | post-install snd-usb-us428 modprobe snd-usb-midi |
98 | to /etc/modules.conf. | 98 | to /etc/modules.conf. |
99 | 99 | ||
100 | known problems: | 100 | known problems: |
101 | sliders, knobs, lights not yet handled except MASTER Volume slider. | 101 | sliders, knobs, lights not yet handled except MASTER Volume slider. |
102 | "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does. | 102 | "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does. |
103 | KDE3: "Enable full duplex operation" deadlocks. | 103 | KDE3: "Enable full duplex operation" deadlocks. |
104 | 104 | ||
105 | 105 | ||
106 | 2002-08-31 Karsten Wiese | 106 | 2002-08-31 Karsten Wiese |
107 | Version 0.0.3: audio also simplex; | 107 | Version 0.0.3: audio also simplex; |
108 | simplifying: iso urbs only 1 packet, melted structs. | 108 | simplifying: iso urbs only 1 packet, melted structs. |
109 | ASYNC_UNLINK not used anymore: no more crashes so far..... | 109 | ASYNC_UNLINK not used anymore: no more crashes so far..... |
110 | for alsa 0.9 rc3. | 110 | for alsa 0.9 rc3. |
111 | 111 | ||
112 | 2002-08-09 Karsten Wiese | 112 | 2002-08-09 Karsten Wiese |
113 | Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol. | 113 | Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol. |
114 | The firmware has been sniffed from win2k us-428 driver 3.09. | 114 | The firmware has been sniffed from win2k us-428 driver 3.09. |
115 | 115 | ||
116 | * Copyright (c) 2002 - 2004 Karsten Wiese | 116 | * Copyright (c) 2002 - 2004 Karsten Wiese |
117 | * | 117 | * |
118 | * This program is free software; you can redistribute it and/or modify | 118 | * This program is free software; you can redistribute it and/or modify |
119 | * it under the terms of the GNU General Public License as published by | 119 | * it under the terms of the GNU General Public License as published by |
120 | * the Free Software Foundation; either version 2 of the License, or | 120 | * the Free Software Foundation; either version 2 of the License, or |
121 | * (at your option) any later version. | 121 | * (at your option) any later version. |
122 | * | 122 | * |
123 | * This program is distributed in the hope that it will be useful, | 123 | * This program is distributed in the hope that it will be useful, |
124 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 124 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
125 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 125 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
126 | * GNU General Public License for more details. | 126 | * GNU General Public License for more details. |
127 | * | 127 | * |
128 | * You should have received a copy of the GNU General Public License | 128 | * You should have received a copy of the GNU General Public License |
129 | * along with this program; if not, write to the Free Software | 129 | * along with this program; if not, write to the Free Software |
130 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 130 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
131 | */ | 131 | */ |
132 | 132 | ||
133 | #include <linux/init.h> | 133 | #include <linux/init.h> |
134 | #include <linux/module.h> | 134 | #include <linux/module.h> |
135 | #include <linux/moduleparam.h> | 135 | #include <linux/moduleparam.h> |
136 | #include <linux/slab.h> | 136 | #include <linux/slab.h> |
137 | #include <linux/interrupt.h> | 137 | #include <linux/interrupt.h> |
138 | #include <linux/usb.h> | 138 | #include <linux/usb.h> |
139 | #include <sound/core.h> | 139 | #include <sound/core.h> |
140 | #include <sound/initval.h> | 140 | #include <sound/initval.h> |
141 | #include <sound/pcm.h> | 141 | #include <sound/pcm.h> |
142 | 142 | ||
143 | #include <sound/rawmidi.h> | 143 | #include <sound/rawmidi.h> |
144 | #include "usx2y.h" | 144 | #include "usx2y.h" |
145 | #include "usbusx2y.h" | 145 | #include "usbusx2y.h" |
146 | #include "usX2Yhwdep.h" | 146 | #include "usX2Yhwdep.h" |
147 | 147 | ||
148 | 148 | ||
149 | 149 | ||
150 | MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); | 150 | MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); |
151 | MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); | 151 | MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); |
152 | MODULE_LICENSE("GPL"); | 152 | MODULE_LICENSE("GPL"); |
153 | MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); | 153 | MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}"); |
154 | 154 | ||
155 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 155 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
156 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 156 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
157 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 157 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ |
158 | 158 | ||
159 | module_param_array(index, int, NULL, 0444); | 159 | module_param_array(index, int, NULL, 0444); |
160 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); | 160 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); |
161 | module_param_array(id, charp, NULL, 0444); | 161 | module_param_array(id, charp, NULL, 0444); |
162 | MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); | 162 | MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); |
163 | module_param_array(enable, bool, NULL, 0444); | 163 | module_param_array(enable, bool, NULL, 0444); |
164 | MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); | 164 | MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); |
165 | 165 | ||
166 | 166 | ||
167 | static int snd_usX2Y_card_used[SNDRV_CARDS]; | 167 | static int snd_usX2Y_card_used[SNDRV_CARDS]; |
168 | 168 | ||
169 | static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr); | 169 | static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr); |
170 | static void snd_usX2Y_card_private_free(struct snd_card *card); | 170 | static void snd_usX2Y_card_private_free(struct snd_card *card); |
171 | 171 | ||
172 | /* | 172 | /* |
173 | * pipe 4 is used for switching the lamps, setting samplerate, volumes .... | 173 | * pipe 4 is used for switching the lamps, setting samplerate, volumes .... |
174 | */ | 174 | */ |
175 | static void i_usX2Y_Out04Int(struct urb *urb) | 175 | static void i_usX2Y_Out04Int(struct urb *urb) |
176 | { | 176 | { |
177 | #ifdef CONFIG_SND_DEBUG | 177 | #ifdef CONFIG_SND_DEBUG |
178 | if (urb->status) { | 178 | if (urb->status) { |
179 | int i; | 179 | int i; |
180 | struct usX2Ydev *usX2Y = urb->context; | 180 | struct usX2Ydev *usX2Y = urb->context; |
181 | for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++); | 181 | for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++); |
182 | snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status); | 182 | snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status); |
183 | } | 183 | } |
184 | #endif | 184 | #endif |
185 | } | 185 | } |
186 | 186 | ||
187 | static void i_usX2Y_In04Int(struct urb *urb) | 187 | static void i_usX2Y_In04Int(struct urb *urb) |
188 | { | 188 | { |
189 | int err = 0; | 189 | int err = 0; |
190 | struct usX2Ydev *usX2Y = urb->context; | 190 | struct usX2Ydev *usX2Y = urb->context; |
191 | struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem; | 191 | struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem; |
192 | 192 | ||
193 | usX2Y->In04IntCalls++; | 193 | usX2Y->In04IntCalls++; |
194 | 194 | ||
195 | if (urb->status) { | 195 | if (urb->status) { |
196 | snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status); | 196 | snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status); |
197 | return; | 197 | return; |
198 | } | 198 | } |
199 | 199 | ||
200 | // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? | 200 | // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? |
201 | if (us428ctls) { | 201 | if (us428ctls) { |
202 | int diff = -1; | 202 | int diff = -1; |
203 | if (-2 == us428ctls->CtlSnapShotLast) { | 203 | if (-2 == us428ctls->CtlSnapShotLast) { |
204 | diff = 0; | 204 | diff = 0; |
205 | memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last)); | 205 | memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last)); |
206 | us428ctls->CtlSnapShotLast = -1; | 206 | us428ctls->CtlSnapShotLast = -1; |
207 | } else { | 207 | } else { |
208 | int i; | 208 | int i; |
209 | for (i = 0; i < 21; i++) { | 209 | for (i = 0; i < 21; i++) { |
210 | if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) { | 210 | if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) { |
211 | if (diff < 0) | 211 | if (diff < 0) |
212 | diff = i; | 212 | diff = i; |
213 | usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i]; | 213 | usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i]; |
214 | } | 214 | } |
215 | } | 215 | } |
216 | } | 216 | } |
217 | if (0 <= diff) { | 217 | if (0 <= diff) { |
218 | int n = us428ctls->CtlSnapShotLast + 1; | 218 | int n = us428ctls->CtlSnapShotLast + 1; |
219 | if (n >= N_us428_ctl_BUFS || n < 0) | 219 | if (n >= N_us428_ctl_BUFS || n < 0) |
220 | n = 0; | 220 | n = 0; |
221 | memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0])); | 221 | memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0])); |
222 | us428ctls->CtlSnapShotDiffersAt[n] = diff; | 222 | us428ctls->CtlSnapShotDiffersAt[n] = diff; |
223 | us428ctls->CtlSnapShotLast = n; | 223 | us428ctls->CtlSnapShotLast = n; |
224 | wake_up(&usX2Y->us428ctls_wait_queue_head); | 224 | wake_up(&usX2Y->us428ctls_wait_queue_head); |
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | 228 | ||
229 | if (usX2Y->US04) { | 229 | if (usX2Y->US04) { |
230 | if (0 == usX2Y->US04->submitted) | 230 | if (0 == usX2Y->US04->submitted) |
231 | do { | 231 | do { |
232 | err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC); | 232 | err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC); |
233 | } while (!err && usX2Y->US04->submitted < usX2Y->US04->len); | 233 | } while (!err && usX2Y->US04->submitted < usX2Y->US04->len); |
234 | } else | 234 | } else |
235 | if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) { | 235 | if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) { |
236 | if (us428ctls->p4outLast != us428ctls->p4outSent) { | 236 | if (us428ctls->p4outLast != us428ctls->p4outSent) { |
237 | int j, send = us428ctls->p4outSent + 1; | 237 | int j, send = us428ctls->p4outSent + 1; |
238 | if (send >= N_us428_p4out_BUFS) | 238 | if (send >= N_us428_p4out_BUFS) |
239 | send = 0; | 239 | send = 0; |
240 | for (j = 0; j < URBS_AsyncSeq && !err; ++j) | 240 | for (j = 0; j < URBS_AsyncSeq && !err; ++j) |
241 | if (0 == usX2Y->AS04.urb[j]->status) { | 241 | if (0 == usX2Y->AS04.urb[j]->status) { |
242 | struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. | 242 | struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. |
243 | usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev, | 243 | usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev, |
244 | usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol, | 244 | usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol, |
245 | p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, | 245 | p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, |
246 | i_usX2Y_Out04Int, usX2Y); | 246 | i_usX2Y_Out04Int, usX2Y); |
247 | err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); | 247 | err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); |
248 | us428ctls->p4outSent = send; | 248 | us428ctls->p4outSent = send; |
249 | break; | 249 | break; |
250 | } | 250 | } |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
254 | if (err) | 254 | if (err) |
255 | snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); | 255 | snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); |
256 | 256 | ||
257 | urb->dev = usX2Y->dev; | 257 | urb->dev = usX2Y->dev; |
258 | usb_submit_urb(urb, GFP_ATOMIC); | 258 | usb_submit_urb(urb, GFP_ATOMIC); |
259 | } | 259 | } |
260 | 260 | ||
261 | /* | 261 | /* |
262 | * Prepare some urbs | 262 | * Prepare some urbs |
263 | */ | 263 | */ |
264 | int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) | 264 | int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y) |
265 | { | 265 | { |
266 | int err = 0, | 266 | int err = 0, |
267 | i; | 267 | i; |
268 | 268 | ||
269 | if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) { | 269 | if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) { |
270 | err = -ENOMEM; | 270 | err = -ENOMEM; |
271 | } else | 271 | } else |
272 | for (i = 0; i < URBS_AsyncSeq; ++i) { | 272 | for (i = 0; i < URBS_AsyncSeq; ++i) { |
273 | if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { | 273 | if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { |
274 | err = -ENOMEM; | 274 | err = -ENOMEM; |
275 | break; | 275 | break; |
276 | } | 276 | } |
277 | usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev, | 277 | usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev, |
278 | usb_sndbulkpipe(usX2Y->dev, 0x04), | 278 | usb_sndbulkpipe(usX2Y->dev, 0x04), |
279 | usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, | 279 | usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, |
280 | i_usX2Y_Out04Int, usX2Y | 280 | i_usX2Y_Out04Int, usX2Y |
281 | ); | 281 | ); |
282 | } | 282 | } |
283 | return err; | 283 | return err; |
284 | } | 284 | } |
285 | 285 | ||
286 | int usX2Y_In04_init(struct usX2Ydev *usX2Y) | 286 | int usX2Y_In04_init(struct usX2Ydev *usX2Y) |
287 | { | 287 | { |
288 | if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL))) | 288 | if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL))) |
289 | return -ENOMEM; | 289 | return -ENOMEM; |
290 | 290 | ||
291 | if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) { | 291 | if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) { |
292 | usb_free_urb(usX2Y->In04urb); | 292 | usb_free_urb(usX2Y->In04urb); |
293 | return -ENOMEM; | 293 | return -ENOMEM; |
294 | } | 294 | } |
295 | 295 | ||
296 | init_waitqueue_head(&usX2Y->In04WaitQueue); | 296 | init_waitqueue_head(&usX2Y->In04WaitQueue); |
297 | usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4), | 297 | usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4), |
298 | usX2Y->In04Buf, 21, | 298 | usX2Y->In04Buf, 21, |
299 | i_usX2Y_In04Int, usX2Y, | 299 | i_usX2Y_In04Int, usX2Y, |
300 | 10); | 300 | 10); |
301 | return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); | 301 | return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); |
302 | } | 302 | } |
303 | 303 | ||
304 | static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) | 304 | static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) |
305 | { | 305 | { |
306 | int i; | 306 | int i; |
307 | for (i = 0; i < URBS_AsyncSeq; ++i) { | 307 | for (i = 0; i < URBS_AsyncSeq; ++i) { |
308 | if (S[i].urb) { | 308 | if (S[i].urb) { |
309 | usb_kill_urb(S->urb[i]); | 309 | usb_kill_urb(S->urb[i]); |
310 | usb_free_urb(S->urb[i]); | 310 | usb_free_urb(S->urb[i]); |
311 | S->urb[i] = NULL; | 311 | S->urb[i] = NULL; |
312 | } | 312 | } |
313 | } | 313 | } |
314 | kfree(S->buffer); | 314 | kfree(S->buffer); |
315 | } | 315 | } |
316 | 316 | ||
317 | 317 | ||
318 | static struct usb_device_id snd_usX2Y_usb_id_table[] = { | 318 | static struct usb_device_id snd_usX2Y_usb_id_table[] = { |
319 | { | 319 | { |
320 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 320 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
321 | .idVendor = 0x1604, | 321 | .idVendor = 0x1604, |
322 | .idProduct = USB_ID_US428 | 322 | .idProduct = USB_ID_US428 |
323 | }, | 323 | }, |
324 | { | 324 | { |
325 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 325 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
326 | .idVendor = 0x1604, | 326 | .idVendor = 0x1604, |
327 | .idProduct = USB_ID_US122 | 327 | .idProduct = USB_ID_US122 |
328 | }, | 328 | }, |
329 | { | 329 | { |
330 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 330 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
331 | .idVendor = 0x1604, | 331 | .idVendor = 0x1604, |
332 | .idProduct = USB_ID_US224 | 332 | .idProduct = USB_ID_US224 |
333 | }, | 333 | }, |
334 | { /* terminator */ } | 334 | { /* terminator */ } |
335 | }; | 335 | }; |
336 | 336 | ||
337 | static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) | 337 | static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp) |
338 | { | 338 | { |
339 | int dev; | 339 | int dev; |
340 | struct snd_card * card; | 340 | struct snd_card * card; |
341 | int err; | 341 | int err; |
342 | 342 | ||
343 | for (dev = 0; dev < SNDRV_CARDS; ++dev) | 343 | for (dev = 0; dev < SNDRV_CARDS; ++dev) |
344 | if (enable[dev] && !snd_usX2Y_card_used[dev]) | 344 | if (enable[dev] && !snd_usX2Y_card_used[dev]) |
345 | break; | 345 | break; |
346 | if (dev >= SNDRV_CARDS) | 346 | if (dev >= SNDRV_CARDS) |
347 | return -ENODEV; | 347 | return -ENODEV; |
348 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, | 348 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, |
349 | sizeof(struct usX2Ydev), &card); | 349 | sizeof(struct usX2Ydev), &card); |
350 | if (err < 0) | 350 | if (err < 0) |
351 | return err; | 351 | return err; |
352 | snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; | 352 | snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1; |
353 | card->private_free = snd_usX2Y_card_private_free; | 353 | card->private_free = snd_usX2Y_card_private_free; |
354 | usX2Y(card)->dev = device; | 354 | usX2Y(card)->dev = device; |
355 | init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); | 355 | init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); |
356 | mutex_init(&usX2Y(card)->prepare_mutex); | 356 | mutex_init(&usX2Y(card)->prepare_mutex); |
357 | INIT_LIST_HEAD(&usX2Y(card)->midi_list); | 357 | INIT_LIST_HEAD(&usX2Y(card)->midi_list); |
358 | strcpy(card->driver, "USB "NAME_ALLCAPS""); | 358 | strcpy(card->driver, "USB "NAME_ALLCAPS""); |
359 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); | 359 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); |
360 | sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", | 360 | sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", |
361 | card->shortname, | 361 | card->shortname, |
362 | le16_to_cpu(device->descriptor.idVendor), | 362 | le16_to_cpu(device->descriptor.idVendor), |
363 | le16_to_cpu(device->descriptor.idProduct), | 363 | le16_to_cpu(device->descriptor.idProduct), |
364 | 0,//us428(card)->usbmidi.ifnum, | 364 | 0,//us428(card)->usbmidi.ifnum, |
365 | usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum | 365 | usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum |
366 | ); | 366 | ); |
367 | *cardp = card; | 367 | *cardp = card; |
368 | return 0; | 368 | return 0; |
369 | } | 369 | } |
370 | 370 | ||
371 | 371 | ||
372 | static int usX2Y_usb_probe(struct usb_device *device, | 372 | static int usX2Y_usb_probe(struct usb_device *device, |
373 | struct usb_interface *intf, | 373 | struct usb_interface *intf, |
374 | const struct usb_device_id *device_id, | 374 | const struct usb_device_id *device_id, |
375 | struct snd_card **cardp) | 375 | struct snd_card **cardp) |
376 | { | 376 | { |
377 | int err; | 377 | int err; |
378 | struct snd_card * card; | 378 | struct snd_card * card; |
379 | 379 | ||
380 | *cardp = NULL; | 380 | *cardp = NULL; |
381 | if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || | 381 | if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || |
382 | (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && | 382 | (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && |
383 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && | 383 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && |
384 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) | 384 | le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) |
385 | return -EINVAL; | 385 | return -EINVAL; |
386 | 386 | ||
387 | err = usX2Y_create_card(device, &card); | 387 | err = usX2Y_create_card(device, &card); |
388 | if (err < 0) | 388 | if (err < 0) |
389 | return err; | 389 | return err; |
390 | snd_card_set_dev(card, &intf->dev); | 390 | snd_card_set_dev(card, &intf->dev); |
391 | if ((err = usX2Y_hwdep_new(card, device)) < 0 || | 391 | if ((err = usX2Y_hwdep_new(card, device)) < 0 || |
392 | (err = snd_card_register(card)) < 0) { | 392 | (err = snd_card_register(card)) < 0) { |
393 | snd_card_free(card); | 393 | snd_card_free(card); |
394 | return err; | 394 | return err; |
395 | } | 395 | } |
396 | *cardp = card; | 396 | *cardp = card; |
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | /* | 400 | /* |
401 | * new 2.5 USB kernel API | 401 | * new 2.5 USB kernel API |
402 | */ | 402 | */ |
403 | static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) | 403 | static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id) |
404 | { | 404 | { |
405 | struct snd_card *card; | 405 | struct snd_card *card; |
406 | int err; | 406 | int err; |
407 | 407 | ||
408 | err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); | 408 | err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card); |
409 | if (err < 0) | 409 | if (err < 0) |
410 | return err; | 410 | return err; |
411 | dev_set_drvdata(&intf->dev, card); | 411 | dev_set_drvdata(&intf->dev, card); |
412 | return 0; | 412 | return 0; |
413 | } | 413 | } |
414 | 414 | ||
415 | static void snd_usX2Y_disconnect(struct usb_interface *intf) | 415 | static void snd_usX2Y_disconnect(struct usb_interface *intf) |
416 | { | 416 | { |
417 | usX2Y_usb_disconnect(interface_to_usbdev(intf), | 417 | usX2Y_usb_disconnect(interface_to_usbdev(intf), |
418 | usb_get_intfdata(intf)); | 418 | usb_get_intfdata(intf)); |
419 | } | 419 | } |
420 | 420 | ||
421 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); | 421 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); |
422 | static struct usb_driver snd_usX2Y_usb_driver = { | 422 | static struct usb_driver snd_usX2Y_usb_driver = { |
423 | .name = "snd-usb-usx2y", | 423 | .name = "snd-usb-usx2y", |
424 | .probe = snd_usX2Y_probe, | 424 | .probe = snd_usX2Y_probe, |
425 | .disconnect = snd_usX2Y_disconnect, | 425 | .disconnect = snd_usX2Y_disconnect, |
426 | .id_table = snd_usX2Y_usb_id_table, | 426 | .id_table = snd_usX2Y_usb_id_table, |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static void snd_usX2Y_card_private_free(struct snd_card *card) | 429 | static void snd_usX2Y_card_private_free(struct snd_card *card) |
430 | { | 430 | { |
431 | kfree(usX2Y(card)->In04Buf); | 431 | kfree(usX2Y(card)->In04Buf); |
432 | usb_free_urb(usX2Y(card)->In04urb); | 432 | usb_free_urb(usX2Y(card)->In04urb); |
433 | if (usX2Y(card)->us428ctls_sharedmem) | 433 | if (usX2Y(card)->us428ctls_sharedmem) |
434 | snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem)); | 434 | snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem)); |
435 | if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS) | 435 | if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS) |
436 | snd_usX2Y_card_used[usX2Y(card)->card_index] = 0; | 436 | snd_usX2Y_card_used[usX2Y(card)->card_index] = 0; |
437 | } | 437 | } |
438 | 438 | ||
439 | /* | 439 | /* |
440 | * Frees the device. | 440 | * Frees the device. |
441 | */ | 441 | */ |
442 | static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) | 442 | static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) |
443 | { | 443 | { |
444 | if (ptr) { | 444 | if (ptr) { |
445 | struct snd_card *card = ptr; | 445 | struct snd_card *card = ptr; |
446 | struct usX2Ydev *usX2Y = usX2Y(card); | 446 | struct usX2Ydev *usX2Y = usX2Y(card); |
447 | struct list_head *p; | 447 | struct list_head *p; |
448 | usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; | 448 | usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; |
449 | usX2Y_unlinkSeq(&usX2Y->AS04); | 449 | usX2Y_unlinkSeq(&usX2Y->AS04); |
450 | usb_kill_urb(usX2Y->In04urb); | 450 | usb_kill_urb(usX2Y->In04urb); |
451 | snd_card_disconnect(card); | 451 | snd_card_disconnect(card); |
452 | /* release the midi resources */ | 452 | /* release the midi resources */ |
453 | list_for_each(p, &usX2Y->midi_list) { | 453 | list_for_each(p, &usX2Y->midi_list) { |
454 | snd_usbmidi_disconnect(p); | 454 | snd_usbmidi_disconnect(p); |
455 | } | 455 | } |
456 | if (usX2Y->us428ctls_sharedmem) | 456 | if (usX2Y->us428ctls_sharedmem) |
457 | wake_up(&usX2Y->us428ctls_wait_queue_head); | 457 | wake_up(&usX2Y->us428ctls_wait_queue_head); |
458 | snd_card_free(card); | 458 | snd_card_free(card); |
459 | } | 459 | } |
460 | } | 460 | } |
461 | 461 | ||
462 | module_usb_driver(snd_usX2Y_usb_driver); | 462 | module_usb_driver(snd_usX2Y_usb_driver); |
463 | 463 |