diff options
author | Daniel Mack <daniel@caiaq.de> | 2007-11-22 11:40:04 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:29:28 +0100 |
commit | 8e3cd08ed8e590952aa9a656758cb24d4ba898f8 (patch) | |
tree | 162fa11dcaff39a1f5e2fff6f7f03670321a558d /sound/usb/caiaq/caiaq-device.c | |
parent | e5f73e2ae813aa216b480728548e5ffbebcc170a (diff) | |
download | lwn-8e3cd08ed8e590952aa9a656758cb24d4ba898f8.tar.gz lwn-8e3cd08ed8e590952aa9a656758cb24d4ba898f8.zip |
[ALSA] caiaq - add control API and more input features
- added support for all input controllers on Native Instrument's 'Kore
controller'.
- added ALSA controls to switch LEDs on 'RigKontrol 2', 'RigKontrol3',
'Audio Kontrol 1' and 'Kore controller'.
- added ALSA controls to switch input mode, software lock and ground
lift features on 'Audio 8 DJ'.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/usb/caiaq/caiaq-device.c')
-rw-r--r-- | sound/usb/caiaq/caiaq-device.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index 58af8142c571..dc2e7f7fef0f 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c @@ -31,17 +31,19 @@ #include <sound/initval.h> #include <sound/pcm.h> #include <sound/rawmidi.h> +#include <sound/control.h> #include "caiaq-device.h" #include "caiaq-audio.h" #include "caiaq-midi.h" +#include "caiaq-control.h" #ifdef CONFIG_SND_USB_CAIAQ_INPUT #include "caiaq-input.h" #endif MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); -MODULE_DESCRIPTION("caiaq USB audio, version 1.2.0"); +MODULE_DESCRIPTION("caiaq USB audio, version 1.3.0"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, RigKontrol3}," @@ -140,14 +142,21 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb) case EP1_CMD_MIDI_READ: snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); break; - + case EP1_CMD_READ_IO: + if (dev->chip.usb_id == + USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { + if (urb->actual_length > sizeof(dev->control_state)) + urb->actual_length = sizeof(dev->control_state); + memcpy(dev->control_state, buf + 1, urb->actual_length); + wake_up(&dev->ep1_wait_queue); + break; + } #ifdef CONFIG_SND_USB_CAIAQ_INPUT case EP1_CMD_READ_ERP: case EP1_CMD_READ_ANALOG: - case EP1_CMD_READ_IO: snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); - break; #endif + break; } dev->ep1_in_urb.actual_length = 0; @@ -156,10 +165,10 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb) log("unable to submit urb. OOM!?\n"); } -static int send_command (struct snd_usb_caiaqdev *dev, - unsigned char command, - const unsigned char *buffer, - int len) +int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, + unsigned char command, + const unsigned char *buffer, + int len) { int actual_len; struct usb_device *usb_dev = dev->chip.dev; @@ -207,7 +216,8 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, rate, depth, bpp); dev->audio_parm_answer = -1; - ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); + ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS, + tmp, sizeof(tmp)); if (ret) return ret; @@ -226,7 +236,8 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp) { char tmp[3] = { digital, analog, erp }; - return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); + return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG, + tmp, sizeof(tmp)); } static void setup_card(struct snd_usb_caiaqdev *dev) @@ -241,7 +252,7 @@ static void setup_card(struct snd_usb_caiaqdev *dev) val[0] = 0x00; val[1] = 0x00; val[2] = 0x01; - send_command(dev, EP1_CMD_WRITE_IO, val, 3); + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3); break; case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): /* RigKontrol2 - display two centered dashes ('--') */ @@ -249,12 +260,34 @@ static void setup_card(struct snd_usb_caiaqdev *dev) val[1] = 0x40; val[2] = 0x40; val[3] = 0x00; - send_command(dev, EP1_CMD_WRITE_IO, val, 4); + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4); break; case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): /* Audio Kontrol 1 - make USB-LED stop blinking */ val[0] = 0x00; - send_command(dev, EP1_CMD_WRITE_IO, val, 1); + snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): + /* Audio 8 DJ - trigger read of current settings */ + dev->control_state[0] = 0xff; + snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0); + snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0); + + if (!wait_event_timeout(dev->ep1_wait_queue, + dev->control_state[0] != 0xff, HZ)) + return; + + /* fix up some defaults */ + if ((dev->control_state[1] != 2) || + (dev->control_state[2] != 3) || + (dev->control_state[4] != 2)) { + dev->control_state[1] = 2; + dev->control_state[2] = 3; + dev->control_state[4] = 2; + snd_usb_caiaq_send_command(dev, + EP1_CMD_WRITE_IO, dev->control_state, 6); + } + break; } @@ -278,6 +311,10 @@ static void setup_card(struct snd_usb_caiaqdev *dev) log("snd_card_register() returned %d\n", ret); snd_card_free(dev->chip.card); } + + ret = snd_usb_caiaq_control_init(dev); + if (ret < 0) + log("Unable to set up control system (ret=%d)\n", ret); } static struct snd_card* create_card(struct usb_device* usb_dev) @@ -340,7 +377,7 @@ static int init_card(struct snd_usb_caiaqdev *dev) if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) return -EIO; - err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); + err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); if (err) return err; |