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