Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270446
b: refs/heads/master
c: e653510
h: refs/heads/master
v: v3
  • Loading branch information
William Light authored and Takashi Iwai committed Oct 13, 2011
1 parent 459f11c commit b495d1f
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3d37fbe44112b06279efa04ad91a0e4b7a0c600c
refs/heads/master: e653510a27e63b41a5bae3c46eb093375e17ca2d
2 changes: 2 additions & 0 deletions trunk/sound/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ config SND_USB_CAIAQ
* Native Instruments Guitar Rig mobile
* Native Instruments Traktor Kontrol X1
* Native Instruments Traktor Kontrol S4
* Native Instruments Maschine Controller

To compile this driver as a module, choose M here: the module
will be called snd-usb-caiaq.
Expand All @@ -85,6 +86,7 @@ config SND_USB_CAIAQ_INPUT
* Native Instruments Kore Controller 2
* Native Instruments Audio Kontrol 1
* Native Instruments Traktor Kontrol S4
* Native Instruments Maschine Controller

config SND_USB_US122L
tristate "Tascam US-122L USB driver"
Expand Down
8 changes: 7 additions & 1 deletion trunk/sound/usb/caiaq/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, Session I/O},"
"{Native Instruments, GuitarRig mobile}"
"{Native Instruments, Traktor Kontrol X1}"
"{Native Instruments, Traktor Kontrol S4}");
"{Native Instruments, Traktor Kontrol S4}"
"{Native Instruments, Maschine Controller}");

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 @@ -146,6 +147,11 @@ static struct usb_device_id snd_usb_id_table[] = {
.idVendor = USB_VID_NATIVEINSTRUMENTS,
.idProduct = USB_PID_TRAKTORAUDIO2
},
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = USB_VID_NATIVEINSTRUMENTS,
.idProduct = USB_PID_MASCHINECONTROLLER
},
{ /* terminator */ }
};

Expand Down
1 change: 1 addition & 0 deletions trunk/sound/usb/caiaq/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define USB_PID_TRAKTORKONTROLX1 0x2305
#define USB_PID_TRAKTORKONTROLS4 0xbaff
#define USB_PID_TRAKTORAUDIO2 0x041d
#define USB_PID_MASCHINECONTROLLER 0x0808

#define EP1_BUFSIZE 64
#define EP4_BUFSIZE 512
Expand Down
151 changes: 150 additions & 1 deletion trunk/sound/usb/caiaq/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,61 @@ static unsigned short keycode_kore[] = {
KEY_BRL_DOT5
};

#define MASCHINE_BUTTONS (42)
#define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
#define MASCHINE_PADS (16)
#define MASCHINE_PAD(X) ((X) + ABS_PRESSURE)

static unsigned short keycode_maschine[] = {
MASCHINE_BUTTON(40), /* mute */
MASCHINE_BUTTON(39), /* solo */
MASCHINE_BUTTON(38), /* select */
MASCHINE_BUTTON(37), /* duplicate */
MASCHINE_BUTTON(36), /* navigate */
MASCHINE_BUTTON(35), /* pad mode */
MASCHINE_BUTTON(34), /* pattern */
MASCHINE_BUTTON(33), /* scene */
KEY_RESERVED, /* spacer */

MASCHINE_BUTTON(30), /* rec */
MASCHINE_BUTTON(31), /* erase */
MASCHINE_BUTTON(32), /* shift */
MASCHINE_BUTTON(28), /* grid */
MASCHINE_BUTTON(27), /* > */
MASCHINE_BUTTON(26), /* < */
MASCHINE_BUTTON(25), /* restart */

MASCHINE_BUTTON(21), /* E */
MASCHINE_BUTTON(22), /* F */
MASCHINE_BUTTON(23), /* G */
MASCHINE_BUTTON(24), /* H */
MASCHINE_BUTTON(20), /* D */
MASCHINE_BUTTON(19), /* C */
MASCHINE_BUTTON(18), /* B */
MASCHINE_BUTTON(17), /* A */

MASCHINE_BUTTON(0), /* control */
MASCHINE_BUTTON(2), /* browse */
MASCHINE_BUTTON(4), /* < */
MASCHINE_BUTTON(6), /* snap */
MASCHINE_BUTTON(7), /* autowrite */
MASCHINE_BUTTON(5), /* > */
MASCHINE_BUTTON(3), /* sampling */
MASCHINE_BUTTON(1), /* step */

MASCHINE_BUTTON(15), /* 8 softkeys */
MASCHINE_BUTTON(14),
MASCHINE_BUTTON(13),
MASCHINE_BUTTON(12),
MASCHINE_BUTTON(11),
MASCHINE_BUTTON(10),
MASCHINE_BUTTON(9),
MASCHINE_BUTTON(8),

MASCHINE_BUTTON(16), /* note repeat */
MASCHINE_BUTTON(29) /* play */
};

#define KONTROLX1_INPUTS (40)
#define KONTROLS4_BUTTONS (12 * 8)
#define KONTROLS4_AXIS (46)
Expand Down Expand Up @@ -218,6 +273,29 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
input_report_abs(input_dev, ABS_HAT3Y, i);
input_sync(input_dev);
break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
/* 4 under the left screen */
input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20]));
input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14]));
input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8]));
input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2]));

/* 4 under the right screen */
input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18]));
input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12]));
input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6]));
input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0]));

/* volume */
input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16]));
/* tempo */
input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10]));
/* swing */
input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4]));

input_sync(input_dev);
break;
}
}

Expand Down Expand Up @@ -400,6 +478,25 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
input_sync(dev->input_dev);
}

#define MASCHINE_MSGBLOCK_SIZE 2

static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev,
const unsigned char *buf,
unsigned int len)
{
unsigned int i, pad_id;
uint16_t pressure;

for (i = 0; i < MASCHINE_PADS; i++) {
pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]);
pad_id = pressure >> 12;

input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff);
}

input_sync(dev->input_dev);
}

static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
{
struct snd_usb_caiaqdev *dev = urb->context;
Expand All @@ -425,6 +522,13 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE))
goto requeue;

snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length);
break;
}

requeue:
Expand All @@ -444,6 +548,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev)
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
return -EIO;
break;
Expand All @@ -462,6 +567,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev)
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
usb_kill_urb(dev->ep4_in_urb);
break;
}
Expand Down Expand Up @@ -652,6 +758,50 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)

break;

case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) |
BIT_MASK(ABS_RZ);

BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine));
memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine));
input->keycodemax = ARRAY_SIZE(keycode_maschine);

for (i = 0; i < MASCHINE_PADS; i++) {
input->absbit[0] |= MASCHINE_PAD(i);
input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10);
}

input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
input_set_abs_params(input, ABS_RX, 0, 999, 0, 10);
input_set_abs_params(input, ABS_RY, 0, 999, 0, 10);
input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10);

dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->ep4_in_urb) {
ret = -ENOMEM;
goto exit_free_idev;
}

usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
usb_rcvbulkpipe(usb_dev, 0x4),
dev->ep4_in_buf, EP4_BUFSIZE,
snd_usb_caiaq_ep4_reply_dispatch, dev);

snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
break;

default:
/* no input methods supported on this device */
goto exit_free_idev;
Expand Down Expand Up @@ -690,4 +840,3 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
input_unregister_device(dev->input_dev);
dev->input_dev = NULL;
}

0 comments on commit b495d1f

Please sign in to comment.