Skip to content

Commit

Permalink
ALSA: usb/caiaq: Add support for Traktor Kontrol X1
Browse files Browse the repository at this point in the history
This device does not have audio controllers and backlit buttons only.
Input data is handled over a dedicated USB endpoint.

All functions are supported by the driver now.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Daniel Mack authored and Takashi Iwai committed Mar 22, 2010
1 parent fc8aa7b commit 6da7a2a
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 45 deletions.
1 change: 1 addition & 0 deletions sound/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ config SND_USB_CAIAQ
* Native Instruments Audio 8 DJ
* Native Instruments Guitar Rig Session I/O
* Native Instruments Guitar Rig mobile
* Native Instruments Traktor Kontrol X1

To compile this driver as a module, choose M here: the module
will be called snd-usb-caiaq.
Expand Down
99 changes: 78 additions & 21 deletions sound/usb/caiaq/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,41 @@ static int control_info(struct snd_kcontrol *kcontrol,
struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
int pos = kcontrol->private_value;
int is_intval = pos & CNT_INTVAL;
unsigned int id = dev->chip.usb_id;
int maxval = 63;

uinfo->count = 1;
pos &= ~CNT_INTVAL;

if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)
&& (pos == 0)) {
/* current input mode of A8DJ */
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 2;
return 0;
}
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
if (pos == 0) {
/* current input mode of A8DJ */
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 2;
return 0;
}
break;

if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)
&& (pos == 0)) {
/* current input mode of A4DJ */
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
if (pos == 0) {
/* current input mode of A4DJ */
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
maxval = 127;
break;
}

if (is_intval) {
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 64;
uinfo->value.integer.max = maxval;
} else {
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->value.integer.min = 0;
Expand Down Expand Up @@ -102,9 +110,10 @@ static int control_put(struct snd_kcontrol *kcontrol,
struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
int pos = kcontrol->private_value;
unsigned char cmd = EP1_CMD_WRITE_IO;

if (dev->chip.usb_id ==
USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) {
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): {
/* A4DJ has only one control */
/* do not expose hardware input mode 0 */
dev->control_state[0] = ucontrol->value.integer.value[0] + 1;
Expand All @@ -113,18 +122,23 @@ static int control_put(struct snd_kcontrol *kcontrol,
return 1;
}

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
cmd = EP1_CMD_DIMM_LEDS;
break;
}

if (pos & CNT_INTVAL) {
dev->control_state[pos & ~CNT_INTVAL]
= ucontrol->value.integer.value[0];
snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO,
snd_usb_caiaq_send_command(dev, cmd,
dev->control_state, sizeof(dev->control_state));
} else {
if (ucontrol->value.integer.value[0])
dev->control_state[pos / 8] |= 1 << (pos % 8);
else
dev->control_state[pos / 8] &= ~(1 << (pos % 8));

snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO,
snd_usb_caiaq_send_command(dev, cmd,
dev->control_state, sizeof(dev->control_state));
}

Expand Down Expand Up @@ -273,6 +287,43 @@ static struct caiaq_controller a4dj_controller[] = {
{ "Current input mode", 0 | CNT_INTVAL }
};

static struct caiaq_controller kontrolx1_controller[] = {
{ "LED FX A: ON", 7 | CNT_INTVAL },
{ "LED FX A: 1", 6 | CNT_INTVAL },
{ "LED FX A: 2", 5 | CNT_INTVAL },
{ "LED FX A: 3", 4 | CNT_INTVAL },
{ "LED FX B: ON", 3 | CNT_INTVAL },
{ "LED FX B: 1", 2 | CNT_INTVAL },
{ "LED FX B: 2", 1 | CNT_INTVAL },
{ "LED FX B: 3", 0 | CNT_INTVAL },

{ "LED Hotcue", 28 | CNT_INTVAL },
{ "LED Shift (white)", 29 | CNT_INTVAL },
{ "LED Shift (green)", 30 | CNT_INTVAL },

{ "LED Deck A: FX1", 24 | CNT_INTVAL },
{ "LED Deck A: FX2", 25 | CNT_INTVAL },
{ "LED Deck A: IN", 17 | CNT_INTVAL },
{ "LED Deck A: OUT", 16 | CNT_INTVAL },
{ "LED Deck A: < BEAT", 19 | CNT_INTVAL },
{ "LED Deck A: BEAT >", 18 | CNT_INTVAL },
{ "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
{ "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
{ "LED Deck A: PLAY", 23 | CNT_INTVAL },
{ "LED Deck A: SYNC", 22 | CNT_INTVAL },

{ "LED Deck B: FX1", 26 | CNT_INTVAL },
{ "LED Deck B: FX2", 27 | CNT_INTVAL },
{ "LED Deck B: IN", 15 | CNT_INTVAL },
{ "LED Deck B: OUT", 14 | CNT_INTVAL },
{ "LED Deck B: < BEAT", 13 | CNT_INTVAL },
{ "LED Deck B: BEAT >", 12 | CNT_INTVAL },
{ "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
{ "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
{ "LED Deck B: PLAY", 9 | CNT_INTVAL },
{ "LED Deck B: SYNC", 8 | CNT_INTVAL },
};

static int __devinit add_controls(struct caiaq_controller *c, int num,
struct snd_usb_caiaqdev *dev)
{
Expand Down Expand Up @@ -321,10 +372,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
ret = add_controls(a8dj_controller,
ARRAY_SIZE(a8dj_controller), dev);
break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
ret = add_controls(a4dj_controller,
ARRAY_SIZE(a4dj_controller), dev);
break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
ret = add_controls(kontrolx1_controller,
ARRAY_SIZE(kontrolx1_controller), dev);
break;
}

return ret;
Expand Down
8 changes: 7 additions & 1 deletion sound/usb/caiaq/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, Audio 4 DJ},"
"{Native Instruments, Audio 8 DJ},"
"{Native Instruments, Session I/O},"
"{Native Instruments, GuitarRig mobile}");
"{Native Instruments, GuitarRig mobile}"
"{Native Instruments, Traktor Kontrol X1}");

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
Expand Down Expand Up @@ -127,6 +128,11 @@ static struct usb_device_id snd_usb_id_table[] = {
.idVendor = USB_VID_NATIVEINSTRUMENTS,
.idProduct = USB_PID_AUDIO2DJ
},
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = USB_VID_NATIVEINSTRUMENTS,
.idProduct = USB_PID_TRAKTORKONTROLX1
},
{ /* terminator */ }
};

Expand Down
24 changes: 14 additions & 10 deletions sound/usb/caiaq/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@

#define USB_VID_NATIVEINSTRUMENTS 0x17cc

#define USB_PID_RIGKONTROL2 0x1969
#define USB_PID_RIGKONTROL3 0x1940
#define USB_PID_KORECONTROLLER 0x4711
#define USB_PID_KORECONTROLLER2 0x4712
#define USB_PID_AK1 0x0815
#define USB_PID_AUDIO2DJ 0x041c
#define USB_PID_AUDIO4DJ 0x0839
#define USB_PID_AUDIO8DJ 0x1978
#define USB_PID_SESSIONIO 0x1915
#define USB_PID_GUITARRIGMOBILE 0x0d8d
#define USB_PID_RIGKONTROL2 0x1969
#define USB_PID_RIGKONTROL3 0x1940
#define USB_PID_KORECONTROLLER 0x4711
#define USB_PID_KORECONTROLLER2 0x4712
#define USB_PID_AK1 0x0815
#define USB_PID_AUDIO2DJ 0x041c
#define USB_PID_AUDIO4DJ 0x0839
#define USB_PID_AUDIO8DJ 0x1978
#define USB_PID_SESSIONIO 0x1915
#define USB_PID_GUITARRIGMOBILE 0x0d8d
#define USB_PID_TRAKTORKONTROLX1 0x2305

#define EP1_BUFSIZE 64
#define EP4_BUFSIZE 512
#define CAIAQ_USB_STR_LEN 0xff
#define MAX_STREAMS 32

Expand Down Expand Up @@ -104,6 +106,8 @@ struct snd_usb_caiaqdev {
struct input_dev *input_dev;
char phys[64]; /* physical device path */
unsigned short keycode[64];
struct urb *ep4_in_urb;
unsigned char ep4_in_buf[EP4_BUFSIZE];
#endif

/* ALSA */
Expand Down
Loading

0 comments on commit 6da7a2a

Please sign in to comment.