summaryrefslogtreecommitdiffstats
path: root/sound/usb/caiaq/caiaq-device.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2007-11-22 11:40:04 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:28 +0100
commit8e3cd08ed8e590952aa9a656758cb24d4ba898f8 (patch)
tree162fa11dcaff39a1f5e2fff6f7f03670321a558d /sound/usb/caiaq/caiaq-device.c
parent[ALSA] caiaq - input device support must depend on CONFIG_INPUT (diff)
downloadlinux-8e3cd08ed8e590952aa9a656758cb24d4ba898f8.tar.xz
linux-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.c65
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;