18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz 48c2ecf20Sopenharmony_ci*/ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/device.h> 78c2ecf20Sopenharmony_ci#include <linux/gfp.h> 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/usb.h> 108c2ecf20Sopenharmony_ci#include <linux/usb/input.h> 118c2ecf20Sopenharmony_ci#include <sound/core.h> 128c2ecf20Sopenharmony_ci#include <sound/pcm.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "device.h" 158c2ecf20Sopenharmony_ci#include "input.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic const unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; 188c2ecf20Sopenharmony_cistatic const unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, 198c2ecf20Sopenharmony_ci KEY_5, KEY_6, KEY_7 }; 208c2ecf20Sopenharmony_cistatic const unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, 218c2ecf20Sopenharmony_ci KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic const unsigned short keycode_kore[] = { 248c2ecf20Sopenharmony_ci KEY_FN_F1, /* "menu" */ 258c2ecf20Sopenharmony_ci KEY_FN_F7, /* "lcd backlight */ 268c2ecf20Sopenharmony_ci KEY_FN_F2, /* "control" */ 278c2ecf20Sopenharmony_ci KEY_FN_F3, /* "enter" */ 288c2ecf20Sopenharmony_ci KEY_FN_F4, /* "view" */ 298c2ecf20Sopenharmony_ci KEY_FN_F5, /* "esc" */ 308c2ecf20Sopenharmony_ci KEY_FN_F6, /* "sound" */ 318c2ecf20Sopenharmony_ci KEY_FN_F8, /* array spacer, never triggered. */ 328c2ecf20Sopenharmony_ci KEY_RIGHT, 338c2ecf20Sopenharmony_ci KEY_DOWN, 348c2ecf20Sopenharmony_ci KEY_UP, 358c2ecf20Sopenharmony_ci KEY_LEFT, 368c2ecf20Sopenharmony_ci KEY_SOUND, /* "listen" */ 378c2ecf20Sopenharmony_ci KEY_RECORD, 388c2ecf20Sopenharmony_ci KEY_PLAYPAUSE, 398c2ecf20Sopenharmony_ci KEY_STOP, 408c2ecf20Sopenharmony_ci BTN_4, /* 8 softkeys */ 418c2ecf20Sopenharmony_ci BTN_3, 428c2ecf20Sopenharmony_ci BTN_2, 438c2ecf20Sopenharmony_ci BTN_1, 448c2ecf20Sopenharmony_ci BTN_8, 458c2ecf20Sopenharmony_ci BTN_7, 468c2ecf20Sopenharmony_ci BTN_6, 478c2ecf20Sopenharmony_ci BTN_5, 488c2ecf20Sopenharmony_ci KEY_BRL_DOT4, /* touch sensitive knobs */ 498c2ecf20Sopenharmony_ci KEY_BRL_DOT3, 508c2ecf20Sopenharmony_ci KEY_BRL_DOT2, 518c2ecf20Sopenharmony_ci KEY_BRL_DOT1, 528c2ecf20Sopenharmony_ci KEY_BRL_DOT8, 538c2ecf20Sopenharmony_ci KEY_BRL_DOT7, 548c2ecf20Sopenharmony_ci KEY_BRL_DOT6, 558c2ecf20Sopenharmony_ci KEY_BRL_DOT5 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define MASCHINE_BUTTONS (42) 598c2ecf20Sopenharmony_ci#define MASCHINE_BUTTON(X) ((X) + BTN_MISC) 608c2ecf20Sopenharmony_ci#define MASCHINE_PADS (16) 618c2ecf20Sopenharmony_ci#define MASCHINE_PAD(X) ((X) + ABS_PRESSURE) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic const unsigned short keycode_maschine[] = { 648c2ecf20Sopenharmony_ci MASCHINE_BUTTON(40), /* mute */ 658c2ecf20Sopenharmony_ci MASCHINE_BUTTON(39), /* solo */ 668c2ecf20Sopenharmony_ci MASCHINE_BUTTON(38), /* select */ 678c2ecf20Sopenharmony_ci MASCHINE_BUTTON(37), /* duplicate */ 688c2ecf20Sopenharmony_ci MASCHINE_BUTTON(36), /* navigate */ 698c2ecf20Sopenharmony_ci MASCHINE_BUTTON(35), /* pad mode */ 708c2ecf20Sopenharmony_ci MASCHINE_BUTTON(34), /* pattern */ 718c2ecf20Sopenharmony_ci MASCHINE_BUTTON(33), /* scene */ 728c2ecf20Sopenharmony_ci KEY_RESERVED, /* spacer */ 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci MASCHINE_BUTTON(30), /* rec */ 758c2ecf20Sopenharmony_ci MASCHINE_BUTTON(31), /* erase */ 768c2ecf20Sopenharmony_ci MASCHINE_BUTTON(32), /* shift */ 778c2ecf20Sopenharmony_ci MASCHINE_BUTTON(28), /* grid */ 788c2ecf20Sopenharmony_ci MASCHINE_BUTTON(27), /* > */ 798c2ecf20Sopenharmony_ci MASCHINE_BUTTON(26), /* < */ 808c2ecf20Sopenharmony_ci MASCHINE_BUTTON(25), /* restart */ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci MASCHINE_BUTTON(21), /* E */ 838c2ecf20Sopenharmony_ci MASCHINE_BUTTON(22), /* F */ 848c2ecf20Sopenharmony_ci MASCHINE_BUTTON(23), /* G */ 858c2ecf20Sopenharmony_ci MASCHINE_BUTTON(24), /* H */ 868c2ecf20Sopenharmony_ci MASCHINE_BUTTON(20), /* D */ 878c2ecf20Sopenharmony_ci MASCHINE_BUTTON(19), /* C */ 888c2ecf20Sopenharmony_ci MASCHINE_BUTTON(18), /* B */ 898c2ecf20Sopenharmony_ci MASCHINE_BUTTON(17), /* A */ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci MASCHINE_BUTTON(0), /* control */ 928c2ecf20Sopenharmony_ci MASCHINE_BUTTON(2), /* browse */ 938c2ecf20Sopenharmony_ci MASCHINE_BUTTON(4), /* < */ 948c2ecf20Sopenharmony_ci MASCHINE_BUTTON(6), /* snap */ 958c2ecf20Sopenharmony_ci MASCHINE_BUTTON(7), /* autowrite */ 968c2ecf20Sopenharmony_ci MASCHINE_BUTTON(5), /* > */ 978c2ecf20Sopenharmony_ci MASCHINE_BUTTON(3), /* sampling */ 988c2ecf20Sopenharmony_ci MASCHINE_BUTTON(1), /* step */ 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci MASCHINE_BUTTON(15), /* 8 softkeys */ 1018c2ecf20Sopenharmony_ci MASCHINE_BUTTON(14), 1028c2ecf20Sopenharmony_ci MASCHINE_BUTTON(13), 1038c2ecf20Sopenharmony_ci MASCHINE_BUTTON(12), 1048c2ecf20Sopenharmony_ci MASCHINE_BUTTON(11), 1058c2ecf20Sopenharmony_ci MASCHINE_BUTTON(10), 1068c2ecf20Sopenharmony_ci MASCHINE_BUTTON(9), 1078c2ecf20Sopenharmony_ci MASCHINE_BUTTON(8), 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci MASCHINE_BUTTON(16), /* note repeat */ 1108c2ecf20Sopenharmony_ci MASCHINE_BUTTON(29) /* play */ 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci#define KONTROLX1_INPUTS (40) 1148c2ecf20Sopenharmony_ci#define KONTROLS4_BUTTONS (12 * 8) 1158c2ecf20Sopenharmony_ci#define KONTROLS4_AXIS (46) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define KONTROLS4_BUTTON(X) ((X) + BTN_MISC) 1188c2ecf20Sopenharmony_ci#define KONTROLS4_ABS(X) ((X) + ABS_HAT0X) 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define DEG90 (range / 2) 1218c2ecf20Sopenharmony_ci#define DEG180 (range) 1228c2ecf20Sopenharmony_ci#define DEG270 (DEG90 + DEG180) 1238c2ecf20Sopenharmony_ci#define DEG360 (DEG180 * 2) 1248c2ecf20Sopenharmony_ci#define HIGH_PEAK (268) 1258c2ecf20Sopenharmony_ci#define LOW_PEAK (-7) 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci/* some of these devices have endless rotation potentiometers 1288c2ecf20Sopenharmony_ci * built in which use two tapers, 90 degrees phase shifted. 1298c2ecf20Sopenharmony_ci * this algorithm decodes them to one single value, ranging 1308c2ecf20Sopenharmony_ci * from 0 to 999 */ 1318c2ecf20Sopenharmony_cistatic unsigned int decode_erp(unsigned char a, unsigned char b) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci int weight_a, weight_b; 1348c2ecf20Sopenharmony_ci int pos_a, pos_b; 1358c2ecf20Sopenharmony_ci int ret; 1368c2ecf20Sopenharmony_ci int range = HIGH_PEAK - LOW_PEAK; 1378c2ecf20Sopenharmony_ci int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci weight_b = abs(mid_value - a) - (range / 2 - 100) / 2; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci if (weight_b < 0) 1428c2ecf20Sopenharmony_ci weight_b = 0; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci if (weight_b > 100) 1458c2ecf20Sopenharmony_ci weight_b = 100; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci weight_a = 100 - weight_b; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci if (a < mid_value) { 1508c2ecf20Sopenharmony_ci /* 0..90 and 270..360 degrees */ 1518c2ecf20Sopenharmony_ci pos_b = b - LOW_PEAK + DEG270; 1528c2ecf20Sopenharmony_ci if (pos_b >= DEG360) 1538c2ecf20Sopenharmony_ci pos_b -= DEG360; 1548c2ecf20Sopenharmony_ci } else 1558c2ecf20Sopenharmony_ci /* 90..270 degrees */ 1568c2ecf20Sopenharmony_ci pos_b = HIGH_PEAK - b + DEG90; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci if (b > mid_value) 1608c2ecf20Sopenharmony_ci /* 0..180 degrees */ 1618c2ecf20Sopenharmony_ci pos_a = a - LOW_PEAK; 1628c2ecf20Sopenharmony_ci else 1638c2ecf20Sopenharmony_ci /* 180..360 degrees */ 1648c2ecf20Sopenharmony_ci pos_a = HIGH_PEAK - a + DEG180; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci /* interpolate both slider values, depending on weight factors */ 1678c2ecf20Sopenharmony_ci /* 0..99 x DEG360 */ 1688c2ecf20Sopenharmony_ci ret = pos_a * weight_a + pos_b * weight_b; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* normalize to 0..999 */ 1718c2ecf20Sopenharmony_ci ret *= 10; 1728c2ecf20Sopenharmony_ci ret /= DEG360; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci if (ret < 0) 1758c2ecf20Sopenharmony_ci ret += 1000; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci if (ret >= 1000) 1788c2ecf20Sopenharmony_ci ret -= 1000; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci return ret; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#undef DEG90 1848c2ecf20Sopenharmony_ci#undef DEG180 1858c2ecf20Sopenharmony_ci#undef DEG270 1868c2ecf20Sopenharmony_ci#undef DEG360 1878c2ecf20Sopenharmony_ci#undef HIGH_PEAK 1888c2ecf20Sopenharmony_ci#undef LOW_PEAK 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *cdev, 1918c2ecf20Sopenharmony_ci int axis, const unsigned char *buf, 1928c2ecf20Sopenharmony_ci int offset) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, axis, 1958c2ecf20Sopenharmony_ci (buf[offset * 2] << 8) | buf[offset * 2 + 1]); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *cdev, 1998c2ecf20Sopenharmony_ci const unsigned char *buf, 2008c2ecf20Sopenharmony_ci unsigned int len) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci struct input_dev *input_dev = cdev->input_dev; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 2058c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 2068c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_X, buf, 2); 2078c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 0); 2088c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 1); 2098c2ecf20Sopenharmony_ci break; 2108c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 2118c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 2128c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 2138c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_X, buf, 0); 2148c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 1); 2158c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 2); 2168c2ecf20Sopenharmony_ci break; 2178c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 2188c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT0X, buf, 4); 2198c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT0Y, buf, 2); 2208c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT1X, buf, 6); 2218c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT1Y, buf, 1); 2228c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT2X, buf, 7); 2238c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT2Y, buf, 0); 2248c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT3X, buf, 5); 2258c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, ABS_HAT3Y, buf, 3); 2268c2ecf20Sopenharmony_ci break; 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci input_sync(input_dev); 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *cdev, 2338c2ecf20Sopenharmony_ci const char *buf, unsigned int len) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci struct input_dev *input_dev = cdev->input_dev; 2368c2ecf20Sopenharmony_ci int i; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 2398c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 2408c2ecf20Sopenharmony_ci i = decode_erp(buf[0], buf[1]); 2418c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_X, i); 2428c2ecf20Sopenharmony_ci input_sync(input_dev); 2438c2ecf20Sopenharmony_ci break; 2448c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 2458c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 2468c2ecf20Sopenharmony_ci i = decode_erp(buf[7], buf[5]); 2478c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT0X, i); 2488c2ecf20Sopenharmony_ci i = decode_erp(buf[12], buf[14]); 2498c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT0Y, i); 2508c2ecf20Sopenharmony_ci i = decode_erp(buf[15], buf[13]); 2518c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT1X, i); 2528c2ecf20Sopenharmony_ci i = decode_erp(buf[0], buf[2]); 2538c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT1Y, i); 2548c2ecf20Sopenharmony_ci i = decode_erp(buf[3], buf[1]); 2558c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT2X, i); 2568c2ecf20Sopenharmony_ci i = decode_erp(buf[8], buf[10]); 2578c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT2Y, i); 2588c2ecf20Sopenharmony_ci i = decode_erp(buf[11], buf[9]); 2598c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT3X, i); 2608c2ecf20Sopenharmony_ci i = decode_erp(buf[4], buf[6]); 2618c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT3Y, i); 2628c2ecf20Sopenharmony_ci input_sync(input_dev); 2638c2ecf20Sopenharmony_ci break; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): 2668c2ecf20Sopenharmony_ci /* 4 under the left screen */ 2678c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20])); 2688c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14])); 2698c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8])); 2708c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2])); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci /* 4 under the right screen */ 2738c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18])); 2748c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12])); 2758c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6])); 2768c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0])); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci /* volume */ 2798c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16])); 2808c2ecf20Sopenharmony_ci /* tempo */ 2818c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10])); 2828c2ecf20Sopenharmony_ci /* swing */ 2838c2ecf20Sopenharmony_ci input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4])); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci input_sync(input_dev); 2868c2ecf20Sopenharmony_ci break; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistatic void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *cdev, 2918c2ecf20Sopenharmony_ci unsigned char *buf, unsigned int len) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci struct input_dev *input_dev = cdev->input_dev; 2948c2ecf20Sopenharmony_ci unsigned short *keycode = input_dev->keycode; 2958c2ecf20Sopenharmony_ci int i; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci if (!keycode) 2988c2ecf20Sopenharmony_ci return; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci if (input_dev->id.product == USB_PID_RIGKONTROL2) 3018c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 3028c2ecf20Sopenharmony_ci buf[i] = ~buf[i]; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci for (i = 0; i < input_dev->keycodemax && i < len * 8; i++) 3058c2ecf20Sopenharmony_ci input_report_key(input_dev, keycode[i], 3068c2ecf20Sopenharmony_ci buf[i / 8] & (1 << (i % 8))); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 3098c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 3108c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 3118c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, ABS_MISC, 255 - buf[4]); 3128c2ecf20Sopenharmony_ci break; 3138c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 3148c2ecf20Sopenharmony_ci /* rotary encoders */ 3158c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, ABS_X, buf[5] & 0xf); 3168c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, ABS_Y, buf[5] >> 4); 3178c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, ABS_Z, buf[6] & 0xf); 3188c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, ABS_MISC, buf[6] >> 4); 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci input_sync(input_dev); 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci#define TKS4_MSGBLOCK_SIZE 16 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cistatic void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *cdev, 3288c2ecf20Sopenharmony_ci const unsigned char *buf, 3298c2ecf20Sopenharmony_ci unsigned int len) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci struct device *dev = caiaqdev_to_dev(cdev); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci while (len) { 3348c2ecf20Sopenharmony_ci unsigned int i, block_id = (buf[0] << 8) | buf[1]; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci switch (block_id) { 3378c2ecf20Sopenharmony_ci case 0: 3388c2ecf20Sopenharmony_ci /* buttons */ 3398c2ecf20Sopenharmony_ci for (i = 0; i < KONTROLS4_BUTTONS; i++) 3408c2ecf20Sopenharmony_ci input_report_key(cdev->input_dev, KONTROLS4_BUTTON(i), 3418c2ecf20Sopenharmony_ci (buf[4 + (i / 8)] >> (i % 8)) & 1); 3428c2ecf20Sopenharmony_ci break; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci case 1: 3458c2ecf20Sopenharmony_ci /* left wheel */ 3468c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8)); 3478c2ecf20Sopenharmony_ci /* right wheel */ 3488c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8)); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci /* rotary encoders */ 3518c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf); 3528c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4); 3538c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf); 3548c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4); 3558c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf); 3568c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4); 3578c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf); 3588c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4); 3598c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci break; 3628c2ecf20Sopenharmony_ci case 2: 3638c2ecf20Sopenharmony_ci /* Volume Fader Channel D */ 3648c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(0), buf, 1); 3658c2ecf20Sopenharmony_ci /* Volume Fader Channel B */ 3668c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(1), buf, 2); 3678c2ecf20Sopenharmony_ci /* Volume Fader Channel A */ 3688c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(2), buf, 3); 3698c2ecf20Sopenharmony_ci /* Volume Fader Channel C */ 3708c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(3), buf, 4); 3718c2ecf20Sopenharmony_ci /* Loop Volume */ 3728c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(4), buf, 6); 3738c2ecf20Sopenharmony_ci /* Crossfader */ 3748c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(7), buf, 7); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci break; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci case 3: 3798c2ecf20Sopenharmony_ci /* Tempo Fader R */ 3808c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(6), buf, 3); 3818c2ecf20Sopenharmony_ci /* Tempo Fader L */ 3828c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(5), buf, 4); 3838c2ecf20Sopenharmony_ci /* Mic Volume */ 3848c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(8), buf, 6); 3858c2ecf20Sopenharmony_ci /* Cue Mix */ 3868c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(9), buf, 7); 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci break; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci case 4: 3918c2ecf20Sopenharmony_ci /* Wheel distance sensor L */ 3928c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(10), buf, 1); 3938c2ecf20Sopenharmony_ci /* Wheel distance sensor R */ 3948c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(11), buf, 2); 3958c2ecf20Sopenharmony_ci /* Channel D EQ - Filter */ 3968c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(12), buf, 3); 3978c2ecf20Sopenharmony_ci /* Channel D EQ - Low */ 3988c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(13), buf, 4); 3998c2ecf20Sopenharmony_ci /* Channel D EQ - Mid */ 4008c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(14), buf, 5); 4018c2ecf20Sopenharmony_ci /* Channel D EQ - Hi */ 4028c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(15), buf, 6); 4038c2ecf20Sopenharmony_ci /* FX2 - dry/wet */ 4048c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(16), buf, 7); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci break; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci case 5: 4098c2ecf20Sopenharmony_ci /* FX2 - 1 */ 4108c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(17), buf, 1); 4118c2ecf20Sopenharmony_ci /* FX2 - 2 */ 4128c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(18), buf, 2); 4138c2ecf20Sopenharmony_ci /* FX2 - 3 */ 4148c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(19), buf, 3); 4158c2ecf20Sopenharmony_ci /* Channel B EQ - Filter */ 4168c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(20), buf, 4); 4178c2ecf20Sopenharmony_ci /* Channel B EQ - Low */ 4188c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(21), buf, 5); 4198c2ecf20Sopenharmony_ci /* Channel B EQ - Mid */ 4208c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(22), buf, 6); 4218c2ecf20Sopenharmony_ci /* Channel B EQ - Hi */ 4228c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(23), buf, 7); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci break; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci case 6: 4278c2ecf20Sopenharmony_ci /* Channel A EQ - Filter */ 4288c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(24), buf, 1); 4298c2ecf20Sopenharmony_ci /* Channel A EQ - Low */ 4308c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(25), buf, 2); 4318c2ecf20Sopenharmony_ci /* Channel A EQ - Mid */ 4328c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(26), buf, 3); 4338c2ecf20Sopenharmony_ci /* Channel A EQ - Hi */ 4348c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(27), buf, 4); 4358c2ecf20Sopenharmony_ci /* Channel C EQ - Filter */ 4368c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(28), buf, 5); 4378c2ecf20Sopenharmony_ci /* Channel C EQ - Low */ 4388c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(29), buf, 6); 4398c2ecf20Sopenharmony_ci /* Channel C EQ - Mid */ 4408c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(30), buf, 7); 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci break; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci case 7: 4458c2ecf20Sopenharmony_ci /* Channel C EQ - Hi */ 4468c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(31), buf, 1); 4478c2ecf20Sopenharmony_ci /* FX1 - wet/dry */ 4488c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(32), buf, 2); 4498c2ecf20Sopenharmony_ci /* FX1 - 1 */ 4508c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(33), buf, 3); 4518c2ecf20Sopenharmony_ci /* FX1 - 2 */ 4528c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(34), buf, 4); 4538c2ecf20Sopenharmony_ci /* FX1 - 3 */ 4548c2ecf20Sopenharmony_ci snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(35), buf, 5); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci break; 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci default: 4598c2ecf20Sopenharmony_ci dev_dbg(dev, "%s(): bogus block (id %d)\n", 4608c2ecf20Sopenharmony_ci __func__, block_id); 4618c2ecf20Sopenharmony_ci return; 4628c2ecf20Sopenharmony_ci } 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci len -= TKS4_MSGBLOCK_SIZE; 4658c2ecf20Sopenharmony_ci buf += TKS4_MSGBLOCK_SIZE; 4668c2ecf20Sopenharmony_ci } 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci input_sync(cdev->input_dev); 4698c2ecf20Sopenharmony_ci} 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci#define MASCHINE_MSGBLOCK_SIZE 2 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_cistatic void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *cdev, 4748c2ecf20Sopenharmony_ci const unsigned char *buf, 4758c2ecf20Sopenharmony_ci unsigned int len) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci unsigned int i, pad_id; 4788c2ecf20Sopenharmony_ci __le16 *pressure = (__le16 *) buf; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci for (i = 0; i < MASCHINE_PADS; i++) { 4818c2ecf20Sopenharmony_ci pad_id = le16_to_cpu(*pressure) >> 12; 4828c2ecf20Sopenharmony_ci input_report_abs(cdev->input_dev, MASCHINE_PAD(pad_id), 4838c2ecf20Sopenharmony_ci le16_to_cpu(*pressure) & 0xfff); 4848c2ecf20Sopenharmony_ci pressure++; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci input_sync(cdev->input_dev); 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_cistatic void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) 4918c2ecf20Sopenharmony_ci{ 4928c2ecf20Sopenharmony_ci struct snd_usb_caiaqdev *cdev = urb->context; 4938c2ecf20Sopenharmony_ci unsigned char *buf = urb->transfer_buffer; 4948c2ecf20Sopenharmony_ci struct device *dev = &urb->dev->dev; 4958c2ecf20Sopenharmony_ci int ret; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci if (urb->status || !cdev || urb != cdev->ep4_in_urb) 4988c2ecf20Sopenharmony_ci return; 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 5018c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 5028c2ecf20Sopenharmony_ci if (urb->actual_length < 24) 5038c2ecf20Sopenharmony_ci goto requeue; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci if (buf[0] & 0x3) 5068c2ecf20Sopenharmony_ci snd_caiaq_input_read_io(cdev, buf + 1, 7); 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci if (buf[0] & 0x4) 5098c2ecf20Sopenharmony_ci snd_caiaq_input_read_analog(cdev, buf + 8, 16); 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci break; 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 5148c2ecf20Sopenharmony_ci snd_usb_caiaq_tks4_dispatch(cdev, buf, urb->actual_length); 5158c2ecf20Sopenharmony_ci break; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): 5188c2ecf20Sopenharmony_ci if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) 5198c2ecf20Sopenharmony_ci goto requeue; 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci snd_usb_caiaq_maschine_dispatch(cdev, buf, urb->actual_length); 5228c2ecf20Sopenharmony_ci break; 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_cirequeue: 5268c2ecf20Sopenharmony_ci cdev->ep4_in_urb->actual_length = 0; 5278c2ecf20Sopenharmony_ci ret = usb_submit_urb(cdev->ep4_in_urb, GFP_ATOMIC); 5288c2ecf20Sopenharmony_ci if (ret < 0) 5298c2ecf20Sopenharmony_ci dev_err(dev, "unable to submit urb. OOM!?\n"); 5308c2ecf20Sopenharmony_ci} 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_cistatic int snd_usb_caiaq_input_open(struct input_dev *idev) 5338c2ecf20Sopenharmony_ci{ 5348c2ecf20Sopenharmony_ci struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev); 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci if (!cdev) 5378c2ecf20Sopenharmony_ci return -EINVAL; 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 5408c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 5418c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 5428c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): 5438c2ecf20Sopenharmony_ci if (usb_submit_urb(cdev->ep4_in_urb, GFP_KERNEL) != 0) 5448c2ecf20Sopenharmony_ci return -EIO; 5458c2ecf20Sopenharmony_ci break; 5468c2ecf20Sopenharmony_ci } 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci return 0; 5498c2ecf20Sopenharmony_ci} 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_cistatic void snd_usb_caiaq_input_close(struct input_dev *idev) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci if (!cdev) 5568c2ecf20Sopenharmony_ci return; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 5598c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 5608c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 5618c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): 5628c2ecf20Sopenharmony_ci usb_kill_urb(cdev->ep4_in_urb); 5638c2ecf20Sopenharmony_ci break; 5648c2ecf20Sopenharmony_ci } 5658c2ecf20Sopenharmony_ci} 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_civoid snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, 5688c2ecf20Sopenharmony_ci char *buf, 5698c2ecf20Sopenharmony_ci unsigned int len) 5708c2ecf20Sopenharmony_ci{ 5718c2ecf20Sopenharmony_ci if (!cdev->input_dev || len < 1) 5728c2ecf20Sopenharmony_ci return; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci switch (buf[0]) { 5758c2ecf20Sopenharmony_ci case EP1_CMD_READ_ANALOG: 5768c2ecf20Sopenharmony_ci snd_caiaq_input_read_analog(cdev, buf + 1, len - 1); 5778c2ecf20Sopenharmony_ci break; 5788c2ecf20Sopenharmony_ci case EP1_CMD_READ_ERP: 5798c2ecf20Sopenharmony_ci snd_caiaq_input_read_erp(cdev, buf + 1, len - 1); 5808c2ecf20Sopenharmony_ci break; 5818c2ecf20Sopenharmony_ci case EP1_CMD_READ_IO: 5828c2ecf20Sopenharmony_ci snd_caiaq_input_read_io(cdev, buf + 1, len - 1); 5838c2ecf20Sopenharmony_ci break; 5848c2ecf20Sopenharmony_ci } 5858c2ecf20Sopenharmony_ci} 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ciint snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev) 5888c2ecf20Sopenharmony_ci{ 5898c2ecf20Sopenharmony_ci struct usb_device *usb_dev = cdev->chip.dev; 5908c2ecf20Sopenharmony_ci struct input_dev *input; 5918c2ecf20Sopenharmony_ci int i, ret = 0; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci input = input_allocate_device(); 5948c2ecf20Sopenharmony_ci if (!input) 5958c2ecf20Sopenharmony_ci return -ENOMEM; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci usb_make_path(usb_dev, cdev->phys, sizeof(cdev->phys)); 5988c2ecf20Sopenharmony_ci strlcat(cdev->phys, "/input0", sizeof(cdev->phys)); 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci input->name = cdev->product_name; 6018c2ecf20Sopenharmony_ci input->phys = cdev->phys; 6028c2ecf20Sopenharmony_ci usb_to_input_id(usb_dev, &input->id); 6038c2ecf20Sopenharmony_ci input->dev.parent = &usb_dev->dev; 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci input_set_drvdata(input, cdev); 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci switch (cdev->chip.usb_id) { 6088c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 6098c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 6108c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 6118c2ecf20Sopenharmony_ci BIT_MASK(ABS_Z); 6128c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk2)); 6138c2ecf20Sopenharmony_ci memcpy(cdev->keycode, keycode_rk2, sizeof(keycode_rk2)); 6148c2ecf20Sopenharmony_ci input->keycodemax = ARRAY_SIZE(keycode_rk2); 6158c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); 6168c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); 6178c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); 6188c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0); 6198c2ecf20Sopenharmony_ci break; 6208c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 6218c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 6228c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 6238c2ecf20Sopenharmony_ci BIT_MASK(ABS_Z); 6248c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk3)); 6258c2ecf20Sopenharmony_ci memcpy(cdev->keycode, keycode_rk3, sizeof(keycode_rk3)); 6268c2ecf20Sopenharmony_ci input->keycodemax = ARRAY_SIZE(keycode_rk3); 6278c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_X, 0, 1024, 0, 10); 6288c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10); 6298c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10); 6308c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0); 6318c2ecf20Sopenharmony_ci break; 6328c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 6338c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 6348c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_X); 6358c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_ak1)); 6368c2ecf20Sopenharmony_ci memcpy(cdev->keycode, keycode_ak1, sizeof(keycode_ak1)); 6378c2ecf20Sopenharmony_ci input->keycodemax = ARRAY_SIZE(keycode_ak1); 6388c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_X, 0, 999, 0, 10); 6398c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 5); 6408c2ecf20Sopenharmony_ci break; 6418c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 6428c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 6438c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 6448c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | 6458c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | 6468c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | 6478c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | 6488c2ecf20Sopenharmony_ci BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 6498c2ecf20Sopenharmony_ci BIT_MASK(ABS_Z); 6508c2ecf20Sopenharmony_ci input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); 6518c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_kore)); 6528c2ecf20Sopenharmony_ci memcpy(cdev->keycode, keycode_kore, sizeof(keycode_kore)); 6538c2ecf20Sopenharmony_ci input->keycodemax = ARRAY_SIZE(keycode_kore); 6548c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); 6558c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); 6568c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); 6578c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); 6588c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); 6598c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); 6608c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); 6618c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); 6628c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); 6638c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); 6648c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); 6658c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); 6668c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); 6678c2ecf20Sopenharmony_ci break; 6688c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 6698c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 6708c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | 6718c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | 6728c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | 6738c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | 6748c2ecf20Sopenharmony_ci BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 6758c2ecf20Sopenharmony_ci BIT_MASK(ABS_Z); 6768c2ecf20Sopenharmony_ci input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); 6778c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLX1_INPUTS); 6788c2ecf20Sopenharmony_ci for (i = 0; i < KONTROLX1_INPUTS; i++) 6798c2ecf20Sopenharmony_ci cdev->keycode[i] = BTN_MISC + i; 6808c2ecf20Sopenharmony_ci input->keycodemax = KONTROLX1_INPUTS; 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci /* analog potentiometers */ 6838c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10); 6848c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10); 6858c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10); 6868c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10); 6878c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10); 6888c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10); 6898c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10); 6908c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci /* rotary encoders */ 6938c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1); 6948c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1); 6958c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1); 6968c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1); 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_ci cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); 6998c2ecf20Sopenharmony_ci if (!cdev->ep4_in_urb) { 7008c2ecf20Sopenharmony_ci ret = -ENOMEM; 7018c2ecf20Sopenharmony_ci goto exit_free_idev; 7028c2ecf20Sopenharmony_ci } 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, 7058c2ecf20Sopenharmony_ci usb_rcvbulkpipe(usb_dev, 0x4), 7068c2ecf20Sopenharmony_ci cdev->ep4_in_buf, EP4_BUFSIZE, 7078c2ecf20Sopenharmony_ci snd_usb_caiaq_ep4_reply_dispatch, cdev); 7088c2ecf20Sopenharmony_ci ret = usb_urb_ep_type_check(cdev->ep4_in_urb); 7098c2ecf20Sopenharmony_ci if (ret < 0) 7108c2ecf20Sopenharmony_ci goto exit_free_idev; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); 7138c2ecf20Sopenharmony_ci 7148c2ecf20Sopenharmony_ci break; 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): 7178c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 7188c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLS4_BUTTONS); 7198c2ecf20Sopenharmony_ci for (i = 0; i < KONTROLS4_BUTTONS; i++) 7208c2ecf20Sopenharmony_ci cdev->keycode[i] = KONTROLS4_BUTTON(i); 7218c2ecf20Sopenharmony_ci input->keycodemax = KONTROLS4_BUTTONS; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci for (i = 0; i < KONTROLS4_AXIS; i++) { 7248c2ecf20Sopenharmony_ci int axis = KONTROLS4_ABS(i); 7258c2ecf20Sopenharmony_ci input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); 7268c2ecf20Sopenharmony_ci } 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci /* 36 analog potentiometers and faders */ 7298c2ecf20Sopenharmony_ci for (i = 0; i < 36; i++) 7308c2ecf20Sopenharmony_ci input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10); 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci /* 2 encoder wheels */ 7338c2ecf20Sopenharmony_ci input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1); 7348c2ecf20Sopenharmony_ci input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci /* 9 rotary encoders */ 7378c2ecf20Sopenharmony_ci for (i = 0; i < 9; i++) 7388c2ecf20Sopenharmony_ci input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1); 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); 7418c2ecf20Sopenharmony_ci if (!cdev->ep4_in_urb) { 7428c2ecf20Sopenharmony_ci ret = -ENOMEM; 7438c2ecf20Sopenharmony_ci goto exit_free_idev; 7448c2ecf20Sopenharmony_ci } 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, 7478c2ecf20Sopenharmony_ci usb_rcvbulkpipe(usb_dev, 0x4), 7488c2ecf20Sopenharmony_ci cdev->ep4_in_buf, EP4_BUFSIZE, 7498c2ecf20Sopenharmony_ci snd_usb_caiaq_ep4_reply_dispatch, cdev); 7508c2ecf20Sopenharmony_ci ret = usb_urb_ep_type_check(cdev->ep4_in_urb); 7518c2ecf20Sopenharmony_ci if (ret < 0) 7528c2ecf20Sopenharmony_ci goto exit_free_idev; 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_ci break; 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): 7598c2ecf20Sopenharmony_ci input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 7608c2ecf20Sopenharmony_ci input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | 7618c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | 7628c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | 7638c2ecf20Sopenharmony_ci BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | 7648c2ecf20Sopenharmony_ci BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | 7658c2ecf20Sopenharmony_ci BIT_MASK(ABS_RZ); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_maschine)); 7688c2ecf20Sopenharmony_ci memcpy(cdev->keycode, keycode_maschine, sizeof(keycode_maschine)); 7698c2ecf20Sopenharmony_ci input->keycodemax = ARRAY_SIZE(keycode_maschine); 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci for (i = 0; i < MASCHINE_PADS; i++) { 7728c2ecf20Sopenharmony_ci input->absbit[0] |= MASCHINE_PAD(i); 7738c2ecf20Sopenharmony_ci input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10); 7748c2ecf20Sopenharmony_ci } 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); 7778c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); 7788c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); 7798c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); 7808c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); 7818c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); 7828c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); 7838c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); 7848c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_RX, 0, 999, 0, 10); 7858c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); 7868c2ecf20Sopenharmony_ci input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); 7898c2ecf20Sopenharmony_ci if (!cdev->ep4_in_urb) { 7908c2ecf20Sopenharmony_ci ret = -ENOMEM; 7918c2ecf20Sopenharmony_ci goto exit_free_idev; 7928c2ecf20Sopenharmony_ci } 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, 7958c2ecf20Sopenharmony_ci usb_rcvbulkpipe(usb_dev, 0x4), 7968c2ecf20Sopenharmony_ci cdev->ep4_in_buf, EP4_BUFSIZE, 7978c2ecf20Sopenharmony_ci snd_usb_caiaq_ep4_reply_dispatch, cdev); 7988c2ecf20Sopenharmony_ci ret = usb_urb_ep_type_check(cdev->ep4_in_urb); 7998c2ecf20Sopenharmony_ci if (ret < 0) 8008c2ecf20Sopenharmony_ci goto exit_free_idev; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); 8038c2ecf20Sopenharmony_ci break; 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci default: 8068c2ecf20Sopenharmony_ci /* no input methods supported on this device */ 8078c2ecf20Sopenharmony_ci ret = -EINVAL; 8088c2ecf20Sopenharmony_ci goto exit_free_idev; 8098c2ecf20Sopenharmony_ci } 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_ci input->open = snd_usb_caiaq_input_open; 8128c2ecf20Sopenharmony_ci input->close = snd_usb_caiaq_input_close; 8138c2ecf20Sopenharmony_ci input->keycode = cdev->keycode; 8148c2ecf20Sopenharmony_ci input->keycodesize = sizeof(unsigned short); 8158c2ecf20Sopenharmony_ci for (i = 0; i < input->keycodemax; i++) 8168c2ecf20Sopenharmony_ci __set_bit(cdev->keycode[i], input->keybit); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci cdev->input_dev = input; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci ret = input_register_device(input); 8218c2ecf20Sopenharmony_ci if (ret < 0) 8228c2ecf20Sopenharmony_ci goto exit_free_idev; 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci return 0; 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_ciexit_free_idev: 8278c2ecf20Sopenharmony_ci input_free_device(input); 8288c2ecf20Sopenharmony_ci cdev->input_dev = NULL; 8298c2ecf20Sopenharmony_ci return ret; 8308c2ecf20Sopenharmony_ci} 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_civoid snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev) 8338c2ecf20Sopenharmony_ci{ 8348c2ecf20Sopenharmony_ci if (!cdev || !cdev->input_dev) 8358c2ecf20Sopenharmony_ci return; 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci usb_kill_urb(cdev->ep4_in_urb); 8388c2ecf20Sopenharmony_ci usb_free_urb(cdev->ep4_in_urb); 8398c2ecf20Sopenharmony_ci cdev->ep4_in_urb = NULL; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci input_unregister_device(cdev->input_dev); 8428c2ecf20Sopenharmony_ci cdev->input_dev = NULL; 8438c2ecf20Sopenharmony_ci} 844