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