diff options
Diffstat (limited to 'sound/usb/caiaq/caiaq-device.c')
-rw-r--r-- | sound/usb/caiaq/caiaq-device.c | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index 58af8142c571..58d25e4e7d6c 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c | |||
@@ -26,26 +26,28 @@ | |||
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/input.h> | 27 | #include <linux/input.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <sound/driver.h> | ||
30 | #include <sound/core.h> | 29 | #include <sound/core.h> |
31 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
32 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
33 | #include <sound/rawmidi.h> | 32 | #include <sound/rawmidi.h> |
33 | #include <sound/control.h> | ||
34 | 34 | ||
35 | #include "caiaq-device.h" | 35 | #include "caiaq-device.h" |
36 | #include "caiaq-audio.h" | 36 | #include "caiaq-audio.h" |
37 | #include "caiaq-midi.h" | 37 | #include "caiaq-midi.h" |
38 | #include "caiaq-control.h" | ||
38 | 39 | ||
39 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 40 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
40 | #include "caiaq-input.h" | 41 | #include "caiaq-input.h" |
41 | #endif | 42 | #endif |
42 | 43 | ||
43 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 44 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
44 | MODULE_DESCRIPTION("caiaq USB audio, version 1.2.0"); | 45 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.2"); |
45 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
46 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | 47 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," |
47 | "{Native Instruments, RigKontrol3}," | 48 | "{Native Instruments, RigKontrol3}," |
48 | "{Native Instruments, Kore Controller}," | 49 | "{Native Instruments, Kore Controller}," |
50 | "{Native Instruments, Kore Controller 2}," | ||
49 | "{Native Instruments, Audio Kontrol 1}" | 51 | "{Native Instruments, Audio Kontrol 1}" |
50 | "{Native Instruments, Audio 8 DJ}}"); | 52 | "{Native Instruments, Audio 8 DJ}}"); |
51 | 53 | ||
@@ -94,6 +96,11 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
94 | .idProduct = USB_PID_KORECONTROLLER | 96 | .idProduct = USB_PID_KORECONTROLLER |
95 | }, | 97 | }, |
96 | { | 98 | { |
99 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
100 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
101 | .idProduct = USB_PID_KORECONTROLLER2 | ||
102 | }, | ||
103 | { | ||
97 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 104 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
98 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 105 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
99 | .idProduct = USB_PID_AK1 | 106 | .idProduct = USB_PID_AK1 |
@@ -140,14 +147,21 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb) | |||
140 | case EP1_CMD_MIDI_READ: | 147 | case EP1_CMD_MIDI_READ: |
141 | snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); | 148 | snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); |
142 | break; | 149 | break; |
143 | 150 | case EP1_CMD_READ_IO: | |
151 | if (dev->chip.usb_id == | ||
152 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { | ||
153 | if (urb->actual_length > sizeof(dev->control_state)) | ||
154 | urb->actual_length = sizeof(dev->control_state); | ||
155 | memcpy(dev->control_state, buf + 1, urb->actual_length); | ||
156 | wake_up(&dev->ep1_wait_queue); | ||
157 | break; | ||
158 | } | ||
144 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 159 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
145 | case EP1_CMD_READ_ERP: | 160 | case EP1_CMD_READ_ERP: |
146 | case EP1_CMD_READ_ANALOG: | 161 | case EP1_CMD_READ_ANALOG: |
147 | case EP1_CMD_READ_IO: | ||
148 | snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); | 162 | snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); |
149 | break; | ||
150 | #endif | 163 | #endif |
164 | break; | ||
151 | } | 165 | } |
152 | 166 | ||
153 | dev->ep1_in_urb.actual_length = 0; | 167 | dev->ep1_in_urb.actual_length = 0; |
@@ -156,10 +170,10 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb) | |||
156 | log("unable to submit urb. OOM!?\n"); | 170 | log("unable to submit urb. OOM!?\n"); |
157 | } | 171 | } |
158 | 172 | ||
159 | static int send_command (struct snd_usb_caiaqdev *dev, | 173 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, |
160 | unsigned char command, | 174 | unsigned char command, |
161 | const unsigned char *buffer, | 175 | const unsigned char *buffer, |
162 | int len) | 176 | int len) |
163 | { | 177 | { |
164 | int actual_len; | 178 | int actual_len; |
165 | struct usb_device *usb_dev = dev->chip.dev; | 179 | struct usb_device *usb_dev = dev->chip.dev; |
@@ -207,7 +221,8 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | |||
207 | rate, depth, bpp); | 221 | rate, depth, bpp); |
208 | 222 | ||
209 | dev->audio_parm_answer = -1; | 223 | dev->audio_parm_answer = -1; |
210 | ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); | 224 | ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS, |
225 | tmp, sizeof(tmp)); | ||
211 | 226 | ||
212 | if (ret) | 227 | if (ret) |
213 | return ret; | 228 | return ret; |
@@ -226,7 +241,8 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, | |||
226 | int digital, int analog, int erp) | 241 | int digital, int analog, int erp) |
227 | { | 242 | { |
228 | char tmp[3] = { digital, analog, erp }; | 243 | char tmp[3] = { digital, analog, erp }; |
229 | return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); | 244 | return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG, |
245 | tmp, sizeof(tmp)); | ||
230 | } | 246 | } |
231 | 247 | ||
232 | static void setup_card(struct snd_usb_caiaqdev *dev) | 248 | static void setup_card(struct snd_usb_caiaqdev *dev) |
@@ -241,7 +257,7 @@ static void setup_card(struct snd_usb_caiaqdev *dev) | |||
241 | val[0] = 0x00; | 257 | val[0] = 0x00; |
242 | val[1] = 0x00; | 258 | val[1] = 0x00; |
243 | val[2] = 0x01; | 259 | val[2] = 0x01; |
244 | send_command(dev, EP1_CMD_WRITE_IO, val, 3); | 260 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3); |
245 | break; | 261 | break; |
246 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 262 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
247 | /* RigKontrol2 - display two centered dashes ('--') */ | 263 | /* RigKontrol2 - display two centered dashes ('--') */ |
@@ -249,22 +265,52 @@ static void setup_card(struct snd_usb_caiaqdev *dev) | |||
249 | val[1] = 0x40; | 265 | val[1] = 0x40; |
250 | val[2] = 0x40; | 266 | val[2] = 0x40; |
251 | val[3] = 0x00; | 267 | val[3] = 0x00; |
252 | send_command(dev, EP1_CMD_WRITE_IO, val, 4); | 268 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4); |
253 | break; | 269 | break; |
254 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 270 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
255 | /* Audio Kontrol 1 - make USB-LED stop blinking */ | 271 | /* Audio Kontrol 1 - make USB-LED stop blinking */ |
256 | val[0] = 0x00; | 272 | val[0] = 0x00; |
257 | send_command(dev, EP1_CMD_WRITE_IO, val, 1); | 273 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1); |
274 | break; | ||
275 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | ||
276 | /* Audio 8 DJ - trigger read of current settings */ | ||
277 | dev->control_state[0] = 0xff; | ||
278 | snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0); | ||
279 | snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0); | ||
280 | |||
281 | if (!wait_event_timeout(dev->ep1_wait_queue, | ||
282 | dev->control_state[0] != 0xff, HZ)) | ||
283 | return; | ||
284 | |||
285 | /* fix up some defaults */ | ||
286 | if ((dev->control_state[1] != 2) || | ||
287 | (dev->control_state[2] != 3) || | ||
288 | (dev->control_state[4] != 2)) { | ||
289 | dev->control_state[1] = 2; | ||
290 | dev->control_state[2] = 3; | ||
291 | dev->control_state[4] = 2; | ||
292 | snd_usb_caiaq_send_command(dev, | ||
293 | EP1_CMD_WRITE_IO, dev->control_state, 6); | ||
294 | } | ||
295 | |||
258 | break; | 296 | break; |
259 | } | 297 | } |
260 | 298 | ||
261 | ret = snd_usb_caiaq_audio_init(dev); | 299 | if (dev->spec.num_analog_audio_out + |
262 | if (ret < 0) | 300 | dev->spec.num_analog_audio_in + |
263 | log("Unable to set up audio system (ret=%d)\n", ret); | 301 | dev->spec.num_digital_audio_out + |
302 | dev->spec.num_digital_audio_in > 0) { | ||
303 | ret = snd_usb_caiaq_audio_init(dev); | ||
304 | if (ret < 0) | ||
305 | log("Unable to set up audio system (ret=%d)\n", ret); | ||
306 | } | ||
264 | 307 | ||
265 | ret = snd_usb_caiaq_midi_init(dev); | 308 | if (dev->spec.num_midi_in + |
266 | if (ret < 0) | 309 | dev->spec.num_midi_out > 0) { |
267 | log("Unable to set up MIDI system (ret=%d)\n", ret); | 310 | ret = snd_usb_caiaq_midi_init(dev); |
311 | if (ret < 0) | ||
312 | log("Unable to set up MIDI system (ret=%d)\n", ret); | ||
313 | } | ||
268 | 314 | ||
269 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 315 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
270 | ret = snd_usb_caiaq_input_init(dev); | 316 | ret = snd_usb_caiaq_input_init(dev); |
@@ -278,6 +324,10 @@ static void setup_card(struct snd_usb_caiaqdev *dev) | |||
278 | log("snd_card_register() returned %d\n", ret); | 324 | log("snd_card_register() returned %d\n", ret); |
279 | snd_card_free(dev->chip.card); | 325 | snd_card_free(dev->chip.card); |
280 | } | 326 | } |
327 | |||
328 | ret = snd_usb_caiaq_control_init(dev); | ||
329 | if (ret < 0) | ||
330 | log("Unable to set up control system (ret=%d)\n", ret); | ||
281 | } | 331 | } |
282 | 332 | ||
283 | static struct snd_card* create_card(struct usb_device* usb_dev) | 333 | static struct snd_card* create_card(struct usb_device* usb_dev) |
@@ -340,7 +390,7 @@ static int init_card(struct snd_usb_caiaqdev *dev) | |||
340 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) | 390 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) |
341 | return -EIO; | 391 | return -EIO; |
342 | 392 | ||
343 | err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); | 393 | err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); |
344 | if (err) | 394 | if (err) |
345 | return err; | 395 | return err; |
346 | 396 | ||