xref: /kernel/linux/linux-6.6/sound/usb/caiaq/input.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *   Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
462306a36Sopenharmony_ci*/
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/device.h>
762306a36Sopenharmony_ci#include <linux/gfp.h>
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/usb.h>
1062306a36Sopenharmony_ci#include <linux/usb/input.h>
1162306a36Sopenharmony_ci#include <sound/core.h>
1262306a36Sopenharmony_ci#include <sound/pcm.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "device.h"
1562306a36Sopenharmony_ci#include "input.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic const unsigned short keycode_ak1[] =  { KEY_C, KEY_B, KEY_A };
1862306a36Sopenharmony_cistatic const unsigned short keycode_rk2[] =  { KEY_1, KEY_2, KEY_3, KEY_4,
1962306a36Sopenharmony_ci					 KEY_5, KEY_6, KEY_7 };
2062306a36Sopenharmony_cistatic const unsigned short keycode_rk3[] =  { KEY_1, KEY_2, KEY_3, KEY_4,
2162306a36Sopenharmony_ci					 KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 };
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic const unsigned short keycode_kore[] = {
2462306a36Sopenharmony_ci	KEY_FN_F1,      /* "menu"               */
2562306a36Sopenharmony_ci	KEY_FN_F7,      /* "lcd backlight       */
2662306a36Sopenharmony_ci	KEY_FN_F2,      /* "control"            */
2762306a36Sopenharmony_ci	KEY_FN_F3,      /* "enter"              */
2862306a36Sopenharmony_ci	KEY_FN_F4,      /* "view"               */
2962306a36Sopenharmony_ci	KEY_FN_F5,      /* "esc"                */
3062306a36Sopenharmony_ci	KEY_FN_F6,      /* "sound"              */
3162306a36Sopenharmony_ci	KEY_FN_F8,      /* array spacer, never triggered. */
3262306a36Sopenharmony_ci	KEY_RIGHT,
3362306a36Sopenharmony_ci	KEY_DOWN,
3462306a36Sopenharmony_ci	KEY_UP,
3562306a36Sopenharmony_ci	KEY_LEFT,
3662306a36Sopenharmony_ci	KEY_SOUND,      /* "listen"             */
3762306a36Sopenharmony_ci	KEY_RECORD,
3862306a36Sopenharmony_ci	KEY_PLAYPAUSE,
3962306a36Sopenharmony_ci	KEY_STOP,
4062306a36Sopenharmony_ci	BTN_4,          /* 8 softkeys */
4162306a36Sopenharmony_ci	BTN_3,
4262306a36Sopenharmony_ci	BTN_2,
4362306a36Sopenharmony_ci	BTN_1,
4462306a36Sopenharmony_ci	BTN_8,
4562306a36Sopenharmony_ci	BTN_7,
4662306a36Sopenharmony_ci	BTN_6,
4762306a36Sopenharmony_ci	BTN_5,
4862306a36Sopenharmony_ci	KEY_BRL_DOT4,   /* touch sensitive knobs */
4962306a36Sopenharmony_ci	KEY_BRL_DOT3,
5062306a36Sopenharmony_ci	KEY_BRL_DOT2,
5162306a36Sopenharmony_ci	KEY_BRL_DOT1,
5262306a36Sopenharmony_ci	KEY_BRL_DOT8,
5362306a36Sopenharmony_ci	KEY_BRL_DOT7,
5462306a36Sopenharmony_ci	KEY_BRL_DOT6,
5562306a36Sopenharmony_ci	KEY_BRL_DOT5
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define MASCHINE_BUTTONS   (42)
5962306a36Sopenharmony_ci#define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
6062306a36Sopenharmony_ci#define MASCHINE_PADS      (16)
6162306a36Sopenharmony_ci#define MASCHINE_PAD(X)    ((X) + ABS_PRESSURE)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic const unsigned short keycode_maschine[] = {
6462306a36Sopenharmony_ci	MASCHINE_BUTTON(40), /* mute       */
6562306a36Sopenharmony_ci	MASCHINE_BUTTON(39), /* solo       */
6662306a36Sopenharmony_ci	MASCHINE_BUTTON(38), /* select     */
6762306a36Sopenharmony_ci	MASCHINE_BUTTON(37), /* duplicate  */
6862306a36Sopenharmony_ci	MASCHINE_BUTTON(36), /* navigate   */
6962306a36Sopenharmony_ci	MASCHINE_BUTTON(35), /* pad mode   */
7062306a36Sopenharmony_ci	MASCHINE_BUTTON(34), /* pattern    */
7162306a36Sopenharmony_ci	MASCHINE_BUTTON(33), /* scene      */
7262306a36Sopenharmony_ci	KEY_RESERVED, /* spacer */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	MASCHINE_BUTTON(30), /* rec        */
7562306a36Sopenharmony_ci	MASCHINE_BUTTON(31), /* erase      */
7662306a36Sopenharmony_ci	MASCHINE_BUTTON(32), /* shift      */
7762306a36Sopenharmony_ci	MASCHINE_BUTTON(28), /* grid       */
7862306a36Sopenharmony_ci	MASCHINE_BUTTON(27), /* >          */
7962306a36Sopenharmony_ci	MASCHINE_BUTTON(26), /* <          */
8062306a36Sopenharmony_ci	MASCHINE_BUTTON(25), /* restart    */
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	MASCHINE_BUTTON(21), /* E          */
8362306a36Sopenharmony_ci	MASCHINE_BUTTON(22), /* F          */
8462306a36Sopenharmony_ci	MASCHINE_BUTTON(23), /* G          */
8562306a36Sopenharmony_ci	MASCHINE_BUTTON(24), /* H          */
8662306a36Sopenharmony_ci	MASCHINE_BUTTON(20), /* D          */
8762306a36Sopenharmony_ci	MASCHINE_BUTTON(19), /* C          */
8862306a36Sopenharmony_ci	MASCHINE_BUTTON(18), /* B          */
8962306a36Sopenharmony_ci	MASCHINE_BUTTON(17), /* A          */
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	MASCHINE_BUTTON(0),  /* control    */
9262306a36Sopenharmony_ci	MASCHINE_BUTTON(2),  /* browse     */
9362306a36Sopenharmony_ci	MASCHINE_BUTTON(4),  /* <          */
9462306a36Sopenharmony_ci	MASCHINE_BUTTON(6),  /* snap       */
9562306a36Sopenharmony_ci	MASCHINE_BUTTON(7),  /* autowrite  */
9662306a36Sopenharmony_ci	MASCHINE_BUTTON(5),  /* >          */
9762306a36Sopenharmony_ci	MASCHINE_BUTTON(3),  /* sampling   */
9862306a36Sopenharmony_ci	MASCHINE_BUTTON(1),  /* step       */
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	MASCHINE_BUTTON(15), /* 8 softkeys */
10162306a36Sopenharmony_ci	MASCHINE_BUTTON(14),
10262306a36Sopenharmony_ci	MASCHINE_BUTTON(13),
10362306a36Sopenharmony_ci	MASCHINE_BUTTON(12),
10462306a36Sopenharmony_ci	MASCHINE_BUTTON(11),
10562306a36Sopenharmony_ci	MASCHINE_BUTTON(10),
10662306a36Sopenharmony_ci	MASCHINE_BUTTON(9),
10762306a36Sopenharmony_ci	MASCHINE_BUTTON(8),
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	MASCHINE_BUTTON(16), /* note repeat */
11062306a36Sopenharmony_ci	MASCHINE_BUTTON(29)  /* play        */
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define KONTROLX1_INPUTS	(40)
11462306a36Sopenharmony_ci#define KONTROLS4_BUTTONS	(12 * 8)
11562306a36Sopenharmony_ci#define KONTROLS4_AXIS		(46)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define KONTROLS4_BUTTON(X)	((X) + BTN_MISC)
11862306a36Sopenharmony_ci#define KONTROLS4_ABS(X)	((X) + ABS_HAT0X)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define DEG90		(range / 2)
12162306a36Sopenharmony_ci#define DEG180		(range)
12262306a36Sopenharmony_ci#define DEG270		(DEG90 + DEG180)
12362306a36Sopenharmony_ci#define DEG360		(DEG180 * 2)
12462306a36Sopenharmony_ci#define HIGH_PEAK	(268)
12562306a36Sopenharmony_ci#define LOW_PEAK	(-7)
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/* some of these devices have endless rotation potentiometers
12862306a36Sopenharmony_ci * built in which use two tapers, 90 degrees phase shifted.
12962306a36Sopenharmony_ci * this algorithm decodes them to one single value, ranging
13062306a36Sopenharmony_ci * from 0 to 999 */
13162306a36Sopenharmony_cistatic unsigned int decode_erp(unsigned char a, unsigned char b)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	int weight_a, weight_b;
13462306a36Sopenharmony_ci	int pos_a, pos_b;
13562306a36Sopenharmony_ci	int ret;
13662306a36Sopenharmony_ci	int range = HIGH_PEAK - LOW_PEAK;
13762306a36Sopenharmony_ci	int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	weight_b = abs(mid_value - a) - (range / 2 - 100) / 2;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	if (weight_b < 0)
14262306a36Sopenharmony_ci		weight_b = 0;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (weight_b > 100)
14562306a36Sopenharmony_ci		weight_b = 100;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	weight_a = 100 - weight_b;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	if (a < mid_value) {
15062306a36Sopenharmony_ci		/* 0..90 and 270..360 degrees */
15162306a36Sopenharmony_ci		pos_b = b - LOW_PEAK + DEG270;
15262306a36Sopenharmony_ci		if (pos_b >= DEG360)
15362306a36Sopenharmony_ci			pos_b -= DEG360;
15462306a36Sopenharmony_ci	} else
15562306a36Sopenharmony_ci		/* 90..270 degrees */
15662306a36Sopenharmony_ci		pos_b = HIGH_PEAK - b + DEG90;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	if (b > mid_value)
16062306a36Sopenharmony_ci		/* 0..180 degrees */
16162306a36Sopenharmony_ci		pos_a = a - LOW_PEAK;
16262306a36Sopenharmony_ci	else
16362306a36Sopenharmony_ci		/* 180..360 degrees */
16462306a36Sopenharmony_ci		pos_a = HIGH_PEAK - a + DEG180;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	/* interpolate both slider values, depending on weight factors */
16762306a36Sopenharmony_ci	/* 0..99 x DEG360 */
16862306a36Sopenharmony_ci	ret = pos_a * weight_a + pos_b * weight_b;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/* normalize to 0..999 */
17162306a36Sopenharmony_ci	ret *= 10;
17262306a36Sopenharmony_ci	ret /= DEG360;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	if (ret < 0)
17562306a36Sopenharmony_ci		ret += 1000;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	if (ret >= 1000)
17862306a36Sopenharmony_ci		ret -= 1000;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	return ret;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#undef DEG90
18462306a36Sopenharmony_ci#undef DEG180
18562306a36Sopenharmony_ci#undef DEG270
18662306a36Sopenharmony_ci#undef DEG360
18762306a36Sopenharmony_ci#undef HIGH_PEAK
18862306a36Sopenharmony_ci#undef LOW_PEAK
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_cistatic inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *cdev,
19162306a36Sopenharmony_ci					      int axis, const unsigned char *buf,
19262306a36Sopenharmony_ci					      int offset)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	input_report_abs(cdev->input_dev, axis,
19562306a36Sopenharmony_ci			 (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
19662306a36Sopenharmony_ci}
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_cistatic void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *cdev,
19962306a36Sopenharmony_ci					const unsigned char *buf,
20062306a36Sopenharmony_ci					unsigned int len)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	struct input_dev *input_dev = cdev->input_dev;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
20562306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
20662306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_X, buf, 2);
20762306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 0);
20862306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 1);
20962306a36Sopenharmony_ci		break;
21062306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
21162306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
21262306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
21362306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_X, buf, 0);
21462306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 1);
21562306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 2);
21662306a36Sopenharmony_ci		break;
21762306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
21862306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT0X, buf, 4);
21962306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT0Y, buf, 2);
22062306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT1X, buf, 6);
22162306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT1Y, buf, 1);
22262306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT2X, buf, 7);
22362306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT2Y, buf, 0);
22462306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT3X, buf, 5);
22562306a36Sopenharmony_ci		snd_caiaq_input_report_abs(cdev, ABS_HAT3Y, buf, 3);
22662306a36Sopenharmony_ci		break;
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	input_sync(input_dev);
23062306a36Sopenharmony_ci}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistatic void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *cdev,
23362306a36Sopenharmony_ci				     const char *buf, unsigned int len)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	struct input_dev *input_dev = cdev->input_dev;
23662306a36Sopenharmony_ci	int i;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
23962306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
24062306a36Sopenharmony_ci		i = decode_erp(buf[0], buf[1]);
24162306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_X, i);
24262306a36Sopenharmony_ci		input_sync(input_dev);
24362306a36Sopenharmony_ci		break;
24462306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
24562306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
24662306a36Sopenharmony_ci		i = decode_erp(buf[7], buf[5]);
24762306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT0X, i);
24862306a36Sopenharmony_ci		i = decode_erp(buf[12], buf[14]);
24962306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT0Y, i);
25062306a36Sopenharmony_ci		i = decode_erp(buf[15], buf[13]);
25162306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT1X, i);
25262306a36Sopenharmony_ci		i = decode_erp(buf[0], buf[2]);
25362306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT1Y, i);
25462306a36Sopenharmony_ci		i = decode_erp(buf[3], buf[1]);
25562306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT2X, i);
25662306a36Sopenharmony_ci		i = decode_erp(buf[8], buf[10]);
25762306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT2Y, i);
25862306a36Sopenharmony_ci		i = decode_erp(buf[11], buf[9]);
25962306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT3X, i);
26062306a36Sopenharmony_ci		i = decode_erp(buf[4], buf[6]);
26162306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT3Y, i);
26262306a36Sopenharmony_ci		input_sync(input_dev);
26362306a36Sopenharmony_ci		break;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
26662306a36Sopenharmony_ci		/* 4 under the left screen */
26762306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20]));
26862306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14]));
26962306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9],  buf[8]));
27062306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3],  buf[2]));
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci		/* 4 under the right screen */
27362306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18]));
27462306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12]));
27562306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7],  buf[6]));
27662306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1],  buf[0]));
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci		/* volume */
27962306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16]));
28062306a36Sopenharmony_ci		/* tempo */
28162306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10]));
28262306a36Sopenharmony_ci		/* swing */
28362306a36Sopenharmony_ci		input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5],  buf[4]));
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci		input_sync(input_dev);
28662306a36Sopenharmony_ci		break;
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *cdev,
29162306a36Sopenharmony_ci				    unsigned char *buf, unsigned int len)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	struct input_dev *input_dev = cdev->input_dev;
29462306a36Sopenharmony_ci	unsigned short *keycode = input_dev->keycode;
29562306a36Sopenharmony_ci	int i;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	if (!keycode)
29862306a36Sopenharmony_ci		return;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	if (input_dev->id.product == USB_PID_RIGKONTROL2)
30162306a36Sopenharmony_ci		for (i = 0; i < len; i++)
30262306a36Sopenharmony_ci			buf[i] = ~buf[i];
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	for (i = 0; i < input_dev->keycodemax && i < len * 8; i++)
30562306a36Sopenharmony_ci		input_report_key(input_dev, keycode[i],
30662306a36Sopenharmony_ci				 buf[i / 8] & (1 << (i % 8)));
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
30962306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
31062306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
31162306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, ABS_MISC, 255 - buf[4]);
31262306a36Sopenharmony_ci		break;
31362306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
31462306a36Sopenharmony_ci		/* rotary encoders */
31562306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, ABS_X, buf[5] & 0xf);
31662306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, ABS_Y, buf[5] >> 4);
31762306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, ABS_Z, buf[6] & 0xf);
31862306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, ABS_MISC, buf[6] >> 4);
31962306a36Sopenharmony_ci		break;
32062306a36Sopenharmony_ci	}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	input_sync(input_dev);
32362306a36Sopenharmony_ci}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci#define TKS4_MSGBLOCK_SIZE	16
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistatic void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *cdev,
32862306a36Sopenharmony_ci					const unsigned char *buf,
32962306a36Sopenharmony_ci					unsigned int len)
33062306a36Sopenharmony_ci{
33162306a36Sopenharmony_ci	struct device *dev = caiaqdev_to_dev(cdev);
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	while (len) {
33462306a36Sopenharmony_ci		unsigned int i, block_id = (buf[0] << 8) | buf[1];
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		switch (block_id) {
33762306a36Sopenharmony_ci		case 0:
33862306a36Sopenharmony_ci			/* buttons */
33962306a36Sopenharmony_ci			for (i = 0; i < KONTROLS4_BUTTONS; i++)
34062306a36Sopenharmony_ci				input_report_key(cdev->input_dev, KONTROLS4_BUTTON(i),
34162306a36Sopenharmony_ci						 (buf[4 + (i / 8)] >> (i % 8)) & 1);
34262306a36Sopenharmony_ci			break;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci		case 1:
34562306a36Sopenharmony_ci			/* left wheel */
34662306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
34762306a36Sopenharmony_ci			/* right wheel */
34862306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci			/* rotary encoders */
35162306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
35262306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
35362306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
35462306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
35562306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
35662306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
35762306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
35862306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
35962306a36Sopenharmony_ci			input_report_abs(cdev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci			break;
36262306a36Sopenharmony_ci		case 2:
36362306a36Sopenharmony_ci			/* Volume Fader Channel D */
36462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(0), buf, 1);
36562306a36Sopenharmony_ci			/* Volume Fader Channel B */
36662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(1), buf, 2);
36762306a36Sopenharmony_ci			/* Volume Fader Channel A */
36862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(2), buf, 3);
36962306a36Sopenharmony_ci			/* Volume Fader Channel C */
37062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(3), buf, 4);
37162306a36Sopenharmony_ci			/* Loop Volume */
37262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(4), buf, 6);
37362306a36Sopenharmony_ci			/* Crossfader */
37462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(7), buf, 7);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci			break;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci		case 3:
37962306a36Sopenharmony_ci			/* Tempo Fader R */
38062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(6), buf, 3);
38162306a36Sopenharmony_ci			/* Tempo Fader L */
38262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(5), buf, 4);
38362306a36Sopenharmony_ci			/* Mic Volume */
38462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(8), buf, 6);
38562306a36Sopenharmony_ci			/* Cue Mix */
38662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(9), buf, 7);
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci			break;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci		case 4:
39162306a36Sopenharmony_ci			/* Wheel distance sensor L */
39262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(10), buf, 1);
39362306a36Sopenharmony_ci			/* Wheel distance sensor R */
39462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(11), buf, 2);
39562306a36Sopenharmony_ci			/* Channel D EQ - Filter */
39662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(12), buf, 3);
39762306a36Sopenharmony_ci			/* Channel D EQ - Low */
39862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(13), buf, 4);
39962306a36Sopenharmony_ci			/* Channel D EQ - Mid */
40062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(14), buf, 5);
40162306a36Sopenharmony_ci			/* Channel D EQ - Hi */
40262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(15), buf, 6);
40362306a36Sopenharmony_ci			/* FX2 - dry/wet */
40462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(16), buf, 7);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci			break;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci		case 5:
40962306a36Sopenharmony_ci			/* FX2 - 1 */
41062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(17), buf, 1);
41162306a36Sopenharmony_ci			/* FX2 - 2 */
41262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(18), buf, 2);
41362306a36Sopenharmony_ci			/* FX2 - 3 */
41462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(19), buf, 3);
41562306a36Sopenharmony_ci			/* Channel B EQ - Filter */
41662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(20), buf, 4);
41762306a36Sopenharmony_ci			/* Channel B EQ - Low */
41862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(21), buf, 5);
41962306a36Sopenharmony_ci			/* Channel B EQ - Mid */
42062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(22), buf, 6);
42162306a36Sopenharmony_ci			/* Channel B EQ - Hi */
42262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(23), buf, 7);
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci			break;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci		case 6:
42762306a36Sopenharmony_ci			/* Channel A EQ - Filter */
42862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(24), buf, 1);
42962306a36Sopenharmony_ci			/* Channel A EQ - Low */
43062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(25), buf, 2);
43162306a36Sopenharmony_ci			/* Channel A EQ - Mid */
43262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(26), buf, 3);
43362306a36Sopenharmony_ci			/* Channel A EQ - Hi */
43462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(27), buf, 4);
43562306a36Sopenharmony_ci			/* Channel C EQ - Filter */
43662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(28), buf, 5);
43762306a36Sopenharmony_ci			/* Channel C EQ - Low */
43862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(29), buf, 6);
43962306a36Sopenharmony_ci			/* Channel C EQ - Mid */
44062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(30), buf, 7);
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci			break;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci		case 7:
44562306a36Sopenharmony_ci			/* Channel C EQ - Hi */
44662306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(31), buf, 1);
44762306a36Sopenharmony_ci			/* FX1 - wet/dry */
44862306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(32), buf, 2);
44962306a36Sopenharmony_ci			/* FX1 - 1 */
45062306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(33), buf, 3);
45162306a36Sopenharmony_ci			/* FX1 - 2 */
45262306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(34), buf, 4);
45362306a36Sopenharmony_ci			/* FX1 - 3 */
45462306a36Sopenharmony_ci			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(35), buf, 5);
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci			break;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci		default:
45962306a36Sopenharmony_ci			dev_dbg(dev, "%s(): bogus block (id %d)\n",
46062306a36Sopenharmony_ci				__func__, block_id);
46162306a36Sopenharmony_ci			return;
46262306a36Sopenharmony_ci		}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci		len -= TKS4_MSGBLOCK_SIZE;
46562306a36Sopenharmony_ci		buf += TKS4_MSGBLOCK_SIZE;
46662306a36Sopenharmony_ci	}
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	input_sync(cdev->input_dev);
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci#define MASCHINE_MSGBLOCK_SIZE 2
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *cdev,
47462306a36Sopenharmony_ci					const unsigned char *buf,
47562306a36Sopenharmony_ci					unsigned int len)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	unsigned int i, pad_id;
47862306a36Sopenharmony_ci	__le16 *pressure = (__le16 *) buf;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	for (i = 0; i < MASCHINE_PADS; i++) {
48162306a36Sopenharmony_ci		pad_id = le16_to_cpu(*pressure) >> 12;
48262306a36Sopenharmony_ci		input_report_abs(cdev->input_dev, MASCHINE_PAD(pad_id),
48362306a36Sopenharmony_ci				 le16_to_cpu(*pressure) & 0xfff);
48462306a36Sopenharmony_ci		pressure++;
48562306a36Sopenharmony_ci	}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	input_sync(cdev->input_dev);
48862306a36Sopenharmony_ci}
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_cistatic void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
49162306a36Sopenharmony_ci{
49262306a36Sopenharmony_ci	struct snd_usb_caiaqdev *cdev = urb->context;
49362306a36Sopenharmony_ci	unsigned char *buf = urb->transfer_buffer;
49462306a36Sopenharmony_ci	struct device *dev = &urb->dev->dev;
49562306a36Sopenharmony_ci	int ret;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	if (urb->status || !cdev || urb != cdev->ep4_in_urb)
49862306a36Sopenharmony_ci		return;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
50162306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
50262306a36Sopenharmony_ci		if (urb->actual_length < 24)
50362306a36Sopenharmony_ci			goto requeue;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci		if (buf[0] & 0x3)
50662306a36Sopenharmony_ci			snd_caiaq_input_read_io(cdev, buf + 1, 7);
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci		if (buf[0] & 0x4)
50962306a36Sopenharmony_ci			snd_caiaq_input_read_analog(cdev, buf + 8, 16);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci		break;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
51462306a36Sopenharmony_ci		snd_usb_caiaq_tks4_dispatch(cdev, buf, urb->actual_length);
51562306a36Sopenharmony_ci		break;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
51862306a36Sopenharmony_ci		if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE))
51962306a36Sopenharmony_ci			goto requeue;
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci		snd_usb_caiaq_maschine_dispatch(cdev, buf, urb->actual_length);
52262306a36Sopenharmony_ci		break;
52362306a36Sopenharmony_ci	}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_cirequeue:
52662306a36Sopenharmony_ci	cdev->ep4_in_urb->actual_length = 0;
52762306a36Sopenharmony_ci	ret = usb_submit_urb(cdev->ep4_in_urb, GFP_ATOMIC);
52862306a36Sopenharmony_ci	if (ret < 0)
52962306a36Sopenharmony_ci		dev_err(dev, "unable to submit urb. OOM!?\n");
53062306a36Sopenharmony_ci}
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic int snd_usb_caiaq_input_open(struct input_dev *idev)
53362306a36Sopenharmony_ci{
53462306a36Sopenharmony_ci	struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev);
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	if (!cdev)
53762306a36Sopenharmony_ci		return -EINVAL;
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
54062306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
54162306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
54262306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
54362306a36Sopenharmony_ci		if (usb_submit_urb(cdev->ep4_in_urb, GFP_KERNEL) != 0)
54462306a36Sopenharmony_ci			return -EIO;
54562306a36Sopenharmony_ci		break;
54662306a36Sopenharmony_ci	}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	return 0;
54962306a36Sopenharmony_ci}
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_cistatic void snd_usb_caiaq_input_close(struct input_dev *idev)
55262306a36Sopenharmony_ci{
55362306a36Sopenharmony_ci	struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev);
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	if (!cdev)
55662306a36Sopenharmony_ci		return;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
55962306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
56062306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
56162306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
56262306a36Sopenharmony_ci		usb_kill_urb(cdev->ep4_in_urb);
56362306a36Sopenharmony_ci		break;
56462306a36Sopenharmony_ci	}
56562306a36Sopenharmony_ci}
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_civoid snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev,
56862306a36Sopenharmony_ci				  char *buf,
56962306a36Sopenharmony_ci				  unsigned int len)
57062306a36Sopenharmony_ci{
57162306a36Sopenharmony_ci	if (!cdev->input_dev || len < 1)
57262306a36Sopenharmony_ci		return;
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci	switch (buf[0]) {
57562306a36Sopenharmony_ci	case EP1_CMD_READ_ANALOG:
57662306a36Sopenharmony_ci		snd_caiaq_input_read_analog(cdev, buf + 1, len - 1);
57762306a36Sopenharmony_ci		break;
57862306a36Sopenharmony_ci	case EP1_CMD_READ_ERP:
57962306a36Sopenharmony_ci		snd_caiaq_input_read_erp(cdev, buf + 1, len - 1);
58062306a36Sopenharmony_ci		break;
58162306a36Sopenharmony_ci	case EP1_CMD_READ_IO:
58262306a36Sopenharmony_ci		snd_caiaq_input_read_io(cdev, buf + 1, len - 1);
58362306a36Sopenharmony_ci		break;
58462306a36Sopenharmony_ci	}
58562306a36Sopenharmony_ci}
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ciint snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
58862306a36Sopenharmony_ci{
58962306a36Sopenharmony_ci	struct usb_device *usb_dev = cdev->chip.dev;
59062306a36Sopenharmony_ci	struct input_dev *input;
59162306a36Sopenharmony_ci	int i, ret = 0;
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	input = input_allocate_device();
59462306a36Sopenharmony_ci	if (!input)
59562306a36Sopenharmony_ci		return -ENOMEM;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	usb_make_path(usb_dev, cdev->phys, sizeof(cdev->phys));
59862306a36Sopenharmony_ci	strlcat(cdev->phys, "/input0", sizeof(cdev->phys));
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci	input->name = cdev->product_name;
60162306a36Sopenharmony_ci	input->phys = cdev->phys;
60262306a36Sopenharmony_ci	usb_to_input_id(usb_dev, &input->id);
60362306a36Sopenharmony_ci	input->dev.parent = &usb_dev->dev;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	input_set_drvdata(input, cdev);
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	switch (cdev->chip.usb_id) {
60862306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
60962306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
61062306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
61162306a36Sopenharmony_ci			BIT_MASK(ABS_Z);
61262306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk2));
61362306a36Sopenharmony_ci		memcpy(cdev->keycode, keycode_rk2, sizeof(keycode_rk2));
61462306a36Sopenharmony_ci		input->keycodemax = ARRAY_SIZE(keycode_rk2);
61562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
61662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
61762306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
61862306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0);
61962306a36Sopenharmony_ci		break;
62062306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
62162306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
62262306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
62362306a36Sopenharmony_ci			BIT_MASK(ABS_Z);
62462306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk3));
62562306a36Sopenharmony_ci		memcpy(cdev->keycode, keycode_rk3, sizeof(keycode_rk3));
62662306a36Sopenharmony_ci		input->keycodemax = ARRAY_SIZE(keycode_rk3);
62762306a36Sopenharmony_ci		input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
62862306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
62962306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
63062306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0);
63162306a36Sopenharmony_ci		break;
63262306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
63362306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
63462306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_X);
63562306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_ak1));
63662306a36Sopenharmony_ci		memcpy(cdev->keycode, keycode_ak1, sizeof(keycode_ak1));
63762306a36Sopenharmony_ci		input->keycodemax = ARRAY_SIZE(keycode_ak1);
63862306a36Sopenharmony_ci		input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
63962306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 5);
64062306a36Sopenharmony_ci		break;
64162306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
64262306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
64362306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
64462306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
64562306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
64662306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
64762306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
64862306a36Sopenharmony_ci				   BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
64962306a36Sopenharmony_ci				   BIT_MASK(ABS_Z);
65062306a36Sopenharmony_ci		input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
65162306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_kore));
65262306a36Sopenharmony_ci		memcpy(cdev->keycode, keycode_kore, sizeof(keycode_kore));
65362306a36Sopenharmony_ci		input->keycodemax = ARRAY_SIZE(keycode_kore);
65462306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
65562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
65662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
65762306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
65862306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
65962306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
66062306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
66162306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
66262306a36Sopenharmony_ci		input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
66362306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
66462306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
66562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
66662306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
66762306a36Sopenharmony_ci		break;
66862306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
66962306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
67062306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
67162306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
67262306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
67362306a36Sopenharmony_ci				   BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
67462306a36Sopenharmony_ci				   BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
67562306a36Sopenharmony_ci				   BIT_MASK(ABS_Z);
67662306a36Sopenharmony_ci		input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
67762306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLX1_INPUTS);
67862306a36Sopenharmony_ci		for (i = 0; i < KONTROLX1_INPUTS; i++)
67962306a36Sopenharmony_ci			cdev->keycode[i] = BTN_MISC + i;
68062306a36Sopenharmony_ci		input->keycodemax = KONTROLX1_INPUTS;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci		/* analog potentiometers */
68362306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
68462306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
68562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
68662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
68762306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
68862306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
68962306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
69062306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci		/* rotary encoders */
69362306a36Sopenharmony_ci		input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
69462306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
69562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
69662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci		cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
69962306a36Sopenharmony_ci		if (!cdev->ep4_in_urb) {
70062306a36Sopenharmony_ci			ret = -ENOMEM;
70162306a36Sopenharmony_ci			goto exit_free_idev;
70262306a36Sopenharmony_ci		}
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
70562306a36Sopenharmony_ci				  usb_rcvbulkpipe(usb_dev, 0x4),
70662306a36Sopenharmony_ci				  cdev->ep4_in_buf, EP4_BUFSIZE,
70762306a36Sopenharmony_ci				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
70862306a36Sopenharmony_ci		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
70962306a36Sopenharmony_ci		if (ret < 0)
71062306a36Sopenharmony_ci			goto exit_free_idev;
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci		break;
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
71762306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
71862306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLS4_BUTTONS);
71962306a36Sopenharmony_ci		for (i = 0; i < KONTROLS4_BUTTONS; i++)
72062306a36Sopenharmony_ci			cdev->keycode[i] = KONTROLS4_BUTTON(i);
72162306a36Sopenharmony_ci		input->keycodemax = KONTROLS4_BUTTONS;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci		for (i = 0; i < KONTROLS4_AXIS; i++) {
72462306a36Sopenharmony_ci			int axis = KONTROLS4_ABS(i);
72562306a36Sopenharmony_ci			input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
72662306a36Sopenharmony_ci		}
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci		/* 36 analog potentiometers and faders */
72962306a36Sopenharmony_ci		for (i = 0; i < 36; i++)
73062306a36Sopenharmony_ci			input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci		/* 2 encoder wheels */
73362306a36Sopenharmony_ci		input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
73462306a36Sopenharmony_ci		input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci		/* 9 rotary encoders */
73762306a36Sopenharmony_ci		for (i = 0; i < 9; i++)
73862306a36Sopenharmony_ci			input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci		cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
74162306a36Sopenharmony_ci		if (!cdev->ep4_in_urb) {
74262306a36Sopenharmony_ci			ret = -ENOMEM;
74362306a36Sopenharmony_ci			goto exit_free_idev;
74462306a36Sopenharmony_ci		}
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
74762306a36Sopenharmony_ci				  usb_rcvbulkpipe(usb_dev, 0x4),
74862306a36Sopenharmony_ci				  cdev->ep4_in_buf, EP4_BUFSIZE,
74962306a36Sopenharmony_ci				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
75062306a36Sopenharmony_ci		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
75162306a36Sopenharmony_ci		if (ret < 0)
75262306a36Sopenharmony_ci			goto exit_free_idev;
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci		break;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
75962306a36Sopenharmony_ci		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
76062306a36Sopenharmony_ci		input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
76162306a36Sopenharmony_ci			BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
76262306a36Sopenharmony_ci			BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
76362306a36Sopenharmony_ci			BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
76462306a36Sopenharmony_ci			BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) |
76562306a36Sopenharmony_ci			BIT_MASK(ABS_RZ);
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_maschine));
76862306a36Sopenharmony_ci		memcpy(cdev->keycode, keycode_maschine, sizeof(keycode_maschine));
76962306a36Sopenharmony_ci		input->keycodemax = ARRAY_SIZE(keycode_maschine);
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci		for (i = 0; i < MASCHINE_PADS; i++) {
77262306a36Sopenharmony_ci			input->absbit[0] |= MASCHINE_PAD(i);
77362306a36Sopenharmony_ci			input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10);
77462306a36Sopenharmony_ci		}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
77762306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
77862306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
77962306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
78062306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
78162306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
78262306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
78362306a36Sopenharmony_ci		input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
78462306a36Sopenharmony_ci		input_set_abs_params(input, ABS_RX, 0, 999, 0, 10);
78562306a36Sopenharmony_ci		input_set_abs_params(input, ABS_RY, 0, 999, 0, 10);
78662306a36Sopenharmony_ci		input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10);
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci		cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
78962306a36Sopenharmony_ci		if (!cdev->ep4_in_urb) {
79062306a36Sopenharmony_ci			ret = -ENOMEM;
79162306a36Sopenharmony_ci			goto exit_free_idev;
79262306a36Sopenharmony_ci		}
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
79562306a36Sopenharmony_ci				  usb_rcvbulkpipe(usb_dev, 0x4),
79662306a36Sopenharmony_ci				  cdev->ep4_in_buf, EP4_BUFSIZE,
79762306a36Sopenharmony_ci				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
79862306a36Sopenharmony_ci		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
79962306a36Sopenharmony_ci		if (ret < 0)
80062306a36Sopenharmony_ci			goto exit_free_idev;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
80362306a36Sopenharmony_ci		break;
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci	default:
80662306a36Sopenharmony_ci		/* no input methods supported on this device */
80762306a36Sopenharmony_ci		ret = -EINVAL;
80862306a36Sopenharmony_ci		goto exit_free_idev;
80962306a36Sopenharmony_ci	}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	input->open = snd_usb_caiaq_input_open;
81262306a36Sopenharmony_ci	input->close = snd_usb_caiaq_input_close;
81362306a36Sopenharmony_ci	input->keycode = cdev->keycode;
81462306a36Sopenharmony_ci	input->keycodesize = sizeof(unsigned short);
81562306a36Sopenharmony_ci	for (i = 0; i < input->keycodemax; i++)
81662306a36Sopenharmony_ci		__set_bit(cdev->keycode[i], input->keybit);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	cdev->input_dev = input;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci	ret = input_register_device(input);
82162306a36Sopenharmony_ci	if (ret < 0)
82262306a36Sopenharmony_ci		goto exit_free_idev;
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	return 0;
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ciexit_free_idev:
82762306a36Sopenharmony_ci	input_free_device(input);
82862306a36Sopenharmony_ci	cdev->input_dev = NULL;
82962306a36Sopenharmony_ci	return ret;
83062306a36Sopenharmony_ci}
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_civoid snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
83362306a36Sopenharmony_ci{
83462306a36Sopenharmony_ci	if (!cdev || !cdev->input_dev)
83562306a36Sopenharmony_ci		return;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	usb_kill_urb(cdev->ep4_in_urb);
83862306a36Sopenharmony_ci	usb_free_urb(cdev->ep4_in_urb);
83962306a36Sopenharmony_ci	cdev->ep4_in_urb = NULL;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	input_unregister_device(cdev->input_dev);
84262306a36Sopenharmony_ci	cdev->input_dev = NULL;
84362306a36Sopenharmony_ci}
844