// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
*/

#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <sound/core.h>
#include <sound/pcm.h>

#include "device.h"
#include "input.h"

static const unsigned short keycode_ak1[] =  { KEY_C, KEY_B, KEY_A };
static const unsigned short keycode_rk2[] =  { KEY_1, KEY_2, KEY_3, KEY_4,
					 KEY_5, KEY_6, KEY_7 };
static const unsigned short keycode_rk3[] =  { KEY_1, KEY_2, KEY_3, KEY_4,
					 KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 };

static const unsigned short keycode_kore[] = {
	KEY_FN_F1,      /* "menu"               */
	KEY_FN_F7,      /* "lcd backlight       */
	KEY_FN_F2,      /* "control"            */
	KEY_FN_F3,      /* "enter"              */
	KEY_FN_F4,      /* "view"               */
	KEY_FN_F5,      /* "esc"                */
	KEY_FN_F6,      /* "sound"              */
	KEY_FN_F8,      /* array spacer, never triggered. */
	KEY_RIGHT,
	KEY_DOWN,
	KEY_UP,
	KEY_LEFT,
	KEY_SOUND,      /* "listen"             */
	KEY_RECORD,
	KEY_PLAYPAUSE,
	KEY_STOP,
	BTN_4,          /* 8 softkeys */
	BTN_3,
	BTN_2,
	BTN_1,
	BTN_8,
	BTN_7,
	BTN_6,
	BTN_5,
	KEY_BRL_DOT4,   /* touch sensitive knobs */
	KEY_BRL_DOT3,
	KEY_BRL_DOT2,
	KEY_BRL_DOT1,
	KEY_BRL_DOT8,
	KEY_BRL_DOT7,
	KEY_BRL_DOT6,
	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 const 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)

#define KONTROLS4_BUTTON(X)	((X) + BTN_MISC)
#define KONTROLS4_ABS(X)	((X) + ABS_HAT0X)

#define DEG90		(range / 2)
#define DEG180		(range)
#define DEG270		(DEG90 + DEG180)
#define DEG360		(DEG180 * 2)
#define HIGH_PEAK	(268)
#define LOW_PEAK	(-7)

/* some of these devices have endless rotation potentiometers
 * built in which use two tapers, 90 degrees phase shifted.
 * this algorithm decodes them to one single value, ranging
 * from 0 to 999 */
static unsigned int decode_erp(unsigned char a, unsigned char b)
{
	int weight_a, weight_b;
	int pos_a, pos_b;
	int ret;
	int range = HIGH_PEAK - LOW_PEAK;
	int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;

	weight_b = abs(mid_value - a) - (range / 2 - 100) / 2;

	if (weight_b < 0)
		weight_b = 0;

	if (weight_b > 100)
		weight_b = 100;

	weight_a = 100 - weight_b;

	if (a < mid_value) {
		/* 0..90 and 270..360 degrees */
		pos_b = b - LOW_PEAK + DEG270;
		if (pos_b >= DEG360)
			pos_b -= DEG360;
	} else
		/* 90..270 degrees */
		pos_b = HIGH_PEAK - b + DEG90;


	if (b > mid_value)
		/* 0..180 degrees */
		pos_a = a - LOW_PEAK;
	else
		/* 180..360 degrees */
		pos_a = HIGH_PEAK - a + DEG180;

	/* interpolate both slider values, depending on weight factors */
	/* 0..99 x DEG360 */
	ret = pos_a * weight_a + pos_b * weight_b;

	/* normalize to 0..999 */
	ret *= 10;
	ret /= DEG360;

	if (ret < 0)
		ret += 1000;

	if (ret >= 1000)
		ret -= 1000;

	return ret;
}

#undef DEG90
#undef DEG180
#undef DEG270
#undef DEG360
#undef HIGH_PEAK
#undef LOW_PEAK

static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *cdev,
					      int axis, const unsigned char *buf,
					      int offset)
{
	input_report_abs(cdev->input_dev, axis,
			 (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
}

static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *cdev,
					const unsigned char *buf,
					unsigned int len)
{
	struct input_dev *input_dev = cdev->input_dev;

	switch (cdev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
		snd_caiaq_input_report_abs(cdev, ABS_X, buf, 2);
		snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 0);
		snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 1);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
		snd_caiaq_input_report_abs(cdev, ABS_X, buf, 0);
		snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 1);
		snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 2);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
		snd_caiaq_input_report_abs(cdev, ABS_HAT0X, buf, 4);
		snd_caiaq_input_report_abs(cdev, ABS_HAT0Y, buf, 2);
		snd_caiaq_input_report_abs(cdev, ABS_HAT1X, buf, 6);
		snd_caiaq_input_report_abs(cdev, ABS_HAT1Y, buf, 1);
		snd_caiaq_input_report_abs(cdev, ABS_HAT2X, buf, 7);
		snd_caiaq_input_report_abs(cdev, ABS_HAT2Y, buf, 0);
		snd_caiaq_input_report_abs(cdev, ABS_HAT3X, buf, 5);
		snd_caiaq_input_report_abs(cdev, ABS_HAT3Y, buf, 3);
		break;
	}

	input_sync(input_dev);
}

static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *cdev,
				     const char *buf, unsigned int len)
{
	struct input_dev *input_dev = cdev->input_dev;
	int i;

	switch (cdev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
		i = decode_erp(buf[0], buf[1]);
		input_report_abs(input_dev, ABS_X, i);
		input_sync(input_dev);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
		i = decode_erp(buf[7], buf[5]);
		input_report_abs(input_dev, ABS_HAT0X, i);
		i = decode_erp(buf[12], buf[14]);
		input_report_abs(input_dev, ABS_HAT0Y, i);
		i = decode_erp(buf[15], buf[13]);
		input_report_abs(input_dev, ABS_HAT1X, i);
		i = decode_erp(buf[0], buf[2]);
		input_report_abs(input_dev, ABS_HAT1Y, i);
		i = decode_erp(buf[3], buf[1]);
		input_report_abs(input_dev, ABS_HAT2X, i);
		i = decode_erp(buf[8], buf[10]);
		input_report_abs(input_dev, ABS_HAT2Y, i);
		i = decode_erp(buf[11], buf[9]);
		input_report_abs(input_dev, ABS_HAT3X, i);
		i = decode_erp(buf[4], buf[6]);
		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;
	}
}

static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *cdev,
				    unsigned char *buf, unsigned int len)
{
	struct input_dev *input_dev = cdev->input_dev;
	unsigned short *keycode = input_dev->keycode;
	int i;

	if (!keycode)
		return;

	if (input_dev->id.product == USB_PID_RIGKONTROL2)
		for (i = 0; i < len; i++)
			buf[i] = ~buf[i];

	for (i = 0; i < input_dev->keycodemax && i < len * 8; i++)
		input_report_key(input_dev, keycode[i],
				 buf[i / 8] & (1 << (i % 8)));

	switch (cdev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
		input_report_abs(cdev->input_dev, ABS_MISC, 255 - buf[4]);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
		/* rotary encoders */
		input_report_abs(cdev->input_dev, ABS_X, buf[5] & 0xf);
		input_report_abs(cdev->input_dev, ABS_Y, buf[5] >> 4);
		input_report_abs(cdev->input_dev, ABS_Z, buf[6] & 0xf);
		input_report_abs(cdev->input_dev, ABS_MISC, buf[6] >> 4);
		break;
	}

	input_sync(input_dev);
}

#define TKS4_MSGBLOCK_SIZE	16

static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *cdev,
					const unsigned char *buf,
					unsigned int len)
{
	struct device *dev = caiaqdev_to_dev(cdev);

	while (len) {
		unsigned int i, block_id = (buf[0] << 8) | buf[1];

		switch (block_id) {
		case 0:
			/* buttons */
			for (i = 0; i < KONTROLS4_BUTTONS; i++)
				input_report_key(cdev->input_dev, KONTROLS4_BUTTON(i),
						 (buf[4 + (i / 8)] >> (i % 8)) & 1);
			break;

		case 1:
			/* left wheel */
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
			/* right wheel */
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));

			/* rotary encoders */
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
			input_report_abs(cdev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);

			break;
		case 2:
			/* Volume Fader Channel D */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(0), buf, 1);
			/* Volume Fader Channel B */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(1), buf, 2);
			/* Volume Fader Channel A */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(2), buf, 3);
			/* Volume Fader Channel C */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(3), buf, 4);
			/* Loop Volume */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(4), buf, 6);
			/* Crossfader */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(7), buf, 7);

			break;

		case 3:
			/* Tempo Fader R */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(6), buf, 3);
			/* Tempo Fader L */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(5), buf, 4);
			/* Mic Volume */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(8), buf, 6);
			/* Cue Mix */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(9), buf, 7);

			break;

		case 4:
			/* Wheel distance sensor L */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(10), buf, 1);
			/* Wheel distance sensor R */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(11), buf, 2);
			/* Channel D EQ - Filter */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(12), buf, 3);
			/* Channel D EQ - Low */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(13), buf, 4);
			/* Channel D EQ - Mid */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(14), buf, 5);
			/* Channel D EQ - Hi */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(15), buf, 6);
			/* FX2 - dry/wet */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(16), buf, 7);

			break;

		case 5:
			/* FX2 - 1 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(17), buf, 1);
			/* FX2 - 2 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(18), buf, 2);
			/* FX2 - 3 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(19), buf, 3);
			/* Channel B EQ - Filter */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(20), buf, 4);
			/* Channel B EQ - Low */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(21), buf, 5);
			/* Channel B EQ - Mid */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(22), buf, 6);
			/* Channel B EQ - Hi */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(23), buf, 7);

			break;

		case 6:
			/* Channel A EQ - Filter */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(24), buf, 1);
			/* Channel A EQ - Low */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(25), buf, 2);
			/* Channel A EQ - Mid */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(26), buf, 3);
			/* Channel A EQ - Hi */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(27), buf, 4);
			/* Channel C EQ - Filter */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(28), buf, 5);
			/* Channel C EQ - Low */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(29), buf, 6);
			/* Channel C EQ - Mid */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(30), buf, 7);

			break;

		case 7:
			/* Channel C EQ - Hi */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(31), buf, 1);
			/* FX1 - wet/dry */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(32), buf, 2);
			/* FX1 - 1 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(33), buf, 3);
			/* FX1 - 2 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(34), buf, 4);
			/* FX1 - 3 */
			snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(35), buf, 5);

			break;

		default:
			dev_dbg(dev, "%s(): bogus block (id %d)\n",
				__func__, block_id);
			return;
		}

		len -= TKS4_MSGBLOCK_SIZE;
		buf += TKS4_MSGBLOCK_SIZE;
	}

	input_sync(cdev->input_dev);
}

#define MASCHINE_MSGBLOCK_SIZE 2

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

	for (i = 0; i < MASCHINE_PADS; i++) {
		pad_id = le16_to_cpu(*pressure) >> 12;
		input_report_abs(cdev->input_dev, MASCHINE_PAD(pad_id),
				 le16_to_cpu(*pressure) & 0xfff);
		pressure++;
	}

	input_sync(cdev->input_dev);
}

static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
{
	struct snd_usb_caiaqdev *cdev = urb->context;
	unsigned char *buf = urb->transfer_buffer;
	struct device *dev = &urb->dev->dev;
	int ret;

	if (urb->status || !cdev || urb != cdev->ep4_in_urb)
		return;

	switch (cdev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
		if (urb->actual_length < 24)
			goto requeue;

		if (buf[0] & 0x3)
			snd_caiaq_input_read_io(cdev, buf + 1, 7);

		if (buf[0] & 0x4)
			snd_caiaq_input_read_analog(cdev, buf + 8, 16);

		break;

	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
		snd_usb_caiaq_tks4_dispatch(cdev, 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(cdev, buf, urb->actual_length);
		break;
	}

requeue:
	cdev->ep4_in_urb->actual_length = 0;
	ret = usb_submit_urb(cdev->ep4_in_urb, GFP_ATOMIC);
	if (ret < 0)
		dev_err(dev, "unable to submit urb. OOM!?\n");
}

static int snd_usb_caiaq_input_open(struct input_dev *idev)
{
	struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev);

	if (!cdev)
		return -EINVAL;

	switch (cdev->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(cdev->ep4_in_urb, GFP_KERNEL) != 0)
			return -EIO;
		break;
	}

	return 0;
}

static void snd_usb_caiaq_input_close(struct input_dev *idev)
{
	struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev);

	if (!cdev)
		return;

	switch (cdev->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(cdev->ep4_in_urb);
		break;
	}
}

void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev,
				  char *buf,
				  unsigned int len)
{
	if (!cdev->input_dev || len < 1)
		return;

	switch (buf[0]) {
	case EP1_CMD_READ_ANALOG:
		snd_caiaq_input_read_analog(cdev, buf + 1, len - 1);
		break;
	case EP1_CMD_READ_ERP:
		snd_caiaq_input_read_erp(cdev, buf + 1, len - 1);
		break;
	case EP1_CMD_READ_IO:
		snd_caiaq_input_read_io(cdev, buf + 1, len - 1);
		break;
	}
}

int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
{
	struct usb_device *usb_dev = cdev->chip.dev;
	struct input_dev *input;
	int i, ret = 0;

	input = input_allocate_device();
	if (!input)
		return -ENOMEM;

	usb_make_path(usb_dev, cdev->phys, sizeof(cdev->phys));
	strlcat(cdev->phys, "/input0", sizeof(cdev->phys));

	input->name = cdev->product_name;
	input->phys = cdev->phys;
	usb_to_input_id(usb_dev, &input->id);
	input->dev.parent = &usb_dev->dev;

	input_set_drvdata(input, cdev);

	switch (cdev->chip.usb_id) {
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
			BIT_MASK(ABS_Z);
		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk2));
		memcpy(cdev->keycode, keycode_rk2, sizeof(keycode_rk2));
		input->keycodemax = ARRAY_SIZE(keycode_rk2);
		input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
			BIT_MASK(ABS_Z);
		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk3));
		memcpy(cdev->keycode, keycode_rk3, sizeof(keycode_rk3));
		input->keycodemax = ARRAY_SIZE(keycode_rk3);
		input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
		input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
		input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
		input->absbit[0] = BIT_MASK(ABS_X);
		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_ak1));
		memcpy(cdev->keycode, keycode_ak1, sizeof(keycode_ak1));
		input->keycodemax = ARRAY_SIZE(keycode_ak1);
		input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
		snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 5);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
		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_X) | BIT_MASK(ABS_Y) |
				   BIT_MASK(ABS_Z);
		input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
		BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_kore));
		memcpy(cdev->keycode, keycode_kore, sizeof(keycode_kore));
		input->keycodemax = ARRAY_SIZE(keycode_kore);
		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_X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);
		break;
	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
		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_X) | BIT_MASK(ABS_Y) |
				   BIT_MASK(ABS_Z);
		input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
		BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLX1_INPUTS);
		for (i = 0; i < KONTROLX1_INPUTS; i++)
			cdev->keycode[i] = BTN_MISC + i;
		input->keycodemax = KONTROLX1_INPUTS;

		/* analog potentiometers */
		input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
		input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);

		/* rotary encoders */
		input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
		input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
		input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
		input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);

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

		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);

		break;

	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
		BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLS4_BUTTONS);
		for (i = 0; i < KONTROLS4_BUTTONS; i++)
			cdev->keycode[i] = KONTROLS4_BUTTON(i);
		input->keycodemax = KONTROLS4_BUTTONS;

		for (i = 0; i < KONTROLS4_AXIS; i++) {
			int axis = KONTROLS4_ABS(i);
			input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
		}

		/* 36 analog potentiometers and faders */
		for (i = 0; i < 36; i++)
			input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);

		/* 2 encoder wheels */
		input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
		input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);

		/* 9 rotary encoders */
		for (i = 0; i < 9; i++)
			input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);

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

		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

		snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5);

		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(cdev->keycode) < sizeof(keycode_maschine));
		memcpy(cdev->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);

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

		usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev,
				  usb_rcvbulkpipe(usb_dev, 0x4),
				  cdev->ep4_in_buf, EP4_BUFSIZE,
				  snd_usb_caiaq_ep4_reply_dispatch, cdev);
		ret = usb_urb_ep_type_check(cdev->ep4_in_urb);
		if (ret < 0)
			goto exit_free_idev;

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

	default:
		/* no input methods supported on this device */
		goto exit_free_idev;
	}

	input->open = snd_usb_caiaq_input_open;
	input->close = snd_usb_caiaq_input_close;
	input->keycode = cdev->keycode;
	input->keycodesize = sizeof(unsigned short);
	for (i = 0; i < input->keycodemax; i++)
		__set_bit(cdev->keycode[i], input->keybit);

	cdev->input_dev = input;

	ret = input_register_device(input);
	if (ret < 0)
		goto exit_free_idev;

	return 0;

exit_free_idev:
	input_free_device(input);
	cdev->input_dev = NULL;
	return ret;
}

void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
{
	if (!cdev || !cdev->input_dev)
		return;

	usb_kill_urb(cdev->ep4_in_urb);
	usb_free_urb(cdev->ep4_in_urb);
	cdev->ep4_in_urb = NULL;

	input_unregister_device(cdev->input_dev);
	cdev->input_dev = NULL;
}
