2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2007-03-26 19:11:24 +02:00
/*
* Copyright ( c ) 2006 , 2007 Daniel Mack , Tim Ruetz
*/
2013-03-03 20:46:22 +01:00
# include <linux/device.h>
2010-03-30 02:52:29 +09:00
# include <linux/gfp.h>
2007-03-26 19:11:24 +02:00
# include <linux/init.h>
# include <linux/usb.h>
2007-11-21 16:45:23 +01:00
# include <linux/usb/input.h>
2010-03-22 13:13:37 +01:00
# include <sound/core.h>
2007-03-26 19:11:24 +02:00
# include <sound/pcm.h>
2009-04-01 19:05:39 +02:00
# include "device.h"
# include "input.h"
2007-03-26 19:11:24 +02:00
2007-11-21 16:45:23 +01:00
static unsigned short keycode_ak1 [ ] = { KEY_C , KEY_B , KEY_A } ;
static unsigned short keycode_rk2 [ ] = { KEY_1 , KEY_2 , KEY_3 , KEY_4 ,
KEY_5 , KEY_6 , KEY_7 } ;
static unsigned short keycode_rk3 [ ] = { KEY_1 , KEY_2 , KEY_3 , KEY_4 ,
2011-08-06 09:13:08 +02:00
KEY_5 , KEY_6 , KEY_7 , KEY_8 , KEY_9 } ;
2007-03-26 19:11:24 +02:00
2007-11-22 11:40:04 +01:00
static unsigned short keycode_kore [ ] = {
KEY_FN_F1 , /* "menu" */
KEY_FN_F7 , /* "lcd backlight */
KEY_FN_F2 , /* "control" */
KEY_FN_F3 , /* "enter" */
KEY_FN_F4 , /* "view" */
KEY_FN_F5 , /* "esc" */
KEY_FN_F6 , /* "sound" */
KEY_FN_F8 , /* array spacer, never triggered. */
KEY_RIGHT ,
KEY_DOWN ,
KEY_UP ,
KEY_LEFT ,
KEY_SOUND , /* "listen" */
KEY_RECORD ,
KEY_PLAYPAUSE ,
KEY_STOP ,
BTN_4 , /* 8 softkeys */
BTN_3 ,
BTN_2 ,
BTN_1 ,
BTN_8 ,
BTN_7 ,
BTN_6 ,
BTN_5 ,
KEY_BRL_DOT4 , /* touch sensitive knobs */
KEY_BRL_DOT3 ,
KEY_BRL_DOT2 ,
KEY_BRL_DOT1 ,
KEY_BRL_DOT8 ,
KEY_BRL_DOT7 ,
KEY_BRL_DOT6 ,
KEY_BRL_DOT5
} ;
2011-10-10 15:54:23 +00:00
# define MASCHINE_BUTTONS (42)
# define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
# define MASCHINE_PADS (16)
# define MASCHINE_PAD(X) ((X) + ABS_PRESSURE)
static unsigned short keycode_maschine [ ] = {
MASCHINE_BUTTON ( 40 ) , /* mute */
MASCHINE_BUTTON ( 39 ) , /* solo */
MASCHINE_BUTTON ( 38 ) , /* select */
MASCHINE_BUTTON ( 37 ) , /* duplicate */
MASCHINE_BUTTON ( 36 ) , /* navigate */
MASCHINE_BUTTON ( 35 ) , /* pad mode */
MASCHINE_BUTTON ( 34 ) , /* pattern */
MASCHINE_BUTTON ( 33 ) , /* scene */
KEY_RESERVED , /* spacer */
MASCHINE_BUTTON ( 30 ) , /* rec */
MASCHINE_BUTTON ( 31 ) , /* erase */
MASCHINE_BUTTON ( 32 ) , /* shift */
MASCHINE_BUTTON ( 28 ) , /* grid */
MASCHINE_BUTTON ( 27 ) , /* > */
MASCHINE_BUTTON ( 26 ) , /* < */
MASCHINE_BUTTON ( 25 ) , /* restart */
MASCHINE_BUTTON ( 21 ) , /* E */
MASCHINE_BUTTON ( 22 ) , /* F */
MASCHINE_BUTTON ( 23 ) , /* G */
MASCHINE_BUTTON ( 24 ) , /* H */
MASCHINE_BUTTON ( 20 ) , /* D */
MASCHINE_BUTTON ( 19 ) , /* C */
MASCHINE_BUTTON ( 18 ) , /* B */
MASCHINE_BUTTON ( 17 ) , /* A */
MASCHINE_BUTTON ( 0 ) , /* control */
MASCHINE_BUTTON ( 2 ) , /* browse */
MASCHINE_BUTTON ( 4 ) , /* < */
MASCHINE_BUTTON ( 6 ) , /* snap */
MASCHINE_BUTTON ( 7 ) , /* autowrite */
MASCHINE_BUTTON ( 5 ) , /* > */
MASCHINE_BUTTON ( 3 ) , /* sampling */
MASCHINE_BUTTON ( 1 ) , /* step */
MASCHINE_BUTTON ( 15 ) , /* 8 softkeys */
MASCHINE_BUTTON ( 14 ) ,
MASCHINE_BUTTON ( 13 ) ,
MASCHINE_BUTTON ( 12 ) ,
MASCHINE_BUTTON ( 11 ) ,
MASCHINE_BUTTON ( 10 ) ,
MASCHINE_BUTTON ( 9 ) ,
MASCHINE_BUTTON ( 8 ) ,
MASCHINE_BUTTON ( 16 ) , /* note repeat */
MASCHINE_BUTTON ( 29 ) /* play */
} ;
2010-09-10 17:04:57 +08:00
# define KONTROLX1_INPUTS (40)
# define KONTROLS4_BUTTONS (12 * 8)
# define KONTROLS4_AXIS (46)
# define KONTROLS4_BUTTON(X) ((X) + BTN_MISC)
# define KONTROLS4_ABS(X) ((X) + ABS_HAT0X)
2010-03-22 13:13:37 +01:00
2007-11-21 16:45:23 +01:00
# define DEG90 (range / 2)
# define DEG180 (range)
# define DEG270 (DEG90 + DEG180)
# define DEG360 (DEG180 * 2)
# define HIGH_PEAK (268)
# define LOW_PEAK (-7)
2007-03-26 19:11:24 +02:00
/* some of these devices have endless rotation potentiometers
* built in which use two tapers , 90 degrees phase shifted .
* this algorithm decodes them to one single value , ranging
* from 0 to 999 */
static unsigned int decode_erp ( unsigned char a , unsigned char b )
{
int weight_a , weight_b ;
int pos_a , pos_b ;
int ret ;
int range = HIGH_PEAK - LOW_PEAK ;
int mid_value = ( HIGH_PEAK + LOW_PEAK ) / 2 ;
2007-11-21 16:45:23 +01:00
weight_b = abs ( mid_value - a ) - ( range / 2 - 100 ) / 2 ;
2007-03-26 19:11:24 +02:00
if ( weight_b < 0 )
weight_b = 0 ;
if ( weight_b > 100 )
weight_b = 100 ;
weight_a = 100 - weight_b ;
if ( a < mid_value ) {
/* 0..90 and 270..360 degrees */
pos_b = b - LOW_PEAK + DEG270 ;
if ( pos_b > = DEG360 )
pos_b - = DEG360 ;
} else
/* 90..270 degrees */
pos_b = HIGH_PEAK - b + DEG90 ;
if ( b > mid_value )
/* 0..180 degrees */
pos_a = a - LOW_PEAK ;
else
/* 180..360 degrees */
pos_a = HIGH_PEAK - a + DEG180 ;
/* interpolate both slider values, depending on weight factors */
/* 0..99 x DEG360 */
ret = pos_a * weight_a + pos_b * weight_b ;
/* normalize to 0..999 */
ret * = 10 ;
ret / = DEG360 ;
if ( ret < 0 )
ret + = 1000 ;
2007-11-21 16:45:23 +01:00
2007-03-26 19:11:24 +02:00
if ( ret > = 1000 )
ret - = 1000 ;
return ret ;
}
# undef DEG90
# undef DEG180
# undef DEG270
# undef DEG360
# undef HIGH_PEAK
# undef LOW_PEAK
2013-03-03 20:46:21 +01:00
static inline void snd_caiaq_input_report_abs ( struct snd_usb_caiaqdev * cdev ,
2010-09-10 17:04:57 +08:00
int axis , const unsigned char * buf ,
int offset )
{
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , axis ,
2010-09-10 17:04:57 +08:00
( buf [ offset * 2 ] < < 8 ) | buf [ offset * 2 + 1 ] ) ;
}
2007-03-26 19:11:24 +02:00
2013-03-03 20:46:21 +01:00
static void snd_caiaq_input_read_analog ( struct snd_usb_caiaqdev * cdev ,
2007-09-17 14:45:14 +02:00
const unsigned char * buf ,
unsigned int len )
2007-03-26 19:11:24 +02:00
{
2013-03-03 20:46:21 +01:00
struct input_dev * input_dev = cdev - > input_dev ;
2007-11-21 16:45:23 +01:00
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2007-11-22 11:40:04 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_RIGKONTROL2 ) :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , ABS_X , buf , 2 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_Y , buf , 0 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_Z , buf , 1 ) ;
2007-03-26 19:11:24 +02:00
break ;
2007-11-22 11:40:04 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_RIGKONTROL3 ) :
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER ) :
2007-11-26 09:00:56 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER2 ) :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , ABS_X , buf , 0 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_Y , buf , 1 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_Z , buf , 2 ) ;
2007-09-17 14:45:14 +02:00
break ;
2010-03-22 13:13:37 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , ABS_HAT0X , buf , 4 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT0Y , buf , 2 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT1X , buf , 6 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT1Y , buf , 1 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT2X , buf , 7 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT2Y , buf , 0 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT3X , buf , 5 ) ;
snd_caiaq_input_report_abs ( cdev , ABS_HAT3Y , buf , 3 ) ;
2010-03-22 13:13:37 +01:00
break ;
2007-03-26 19:11:24 +02:00
}
2010-09-10 17:04:57 +08:00
input_sync ( input_dev ) ;
2007-03-26 19:11:24 +02:00
}
2013-03-03 20:46:21 +01:00
static void snd_caiaq_input_read_erp ( struct snd_usb_caiaqdev * cdev ,
2007-03-26 19:11:24 +02:00
const char * buf , unsigned int len )
{
2013-03-03 20:46:21 +01:00
struct input_dev * input_dev = cdev - > input_dev ;
2007-03-26 19:11:24 +02:00
int i ;
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2007-11-22 11:40:04 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_AK1 ) :
2007-03-26 19:11:24 +02:00
i = decode_erp ( buf [ 0 ] , buf [ 1 ] ) ;
2007-11-21 16:45:23 +01:00
input_report_abs ( input_dev , ABS_X , i ) ;
input_sync ( input_dev ) ;
2007-03-26 19:11:24 +02:00
break ;
2007-11-22 11:40:04 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER ) :
2007-11-26 09:00:56 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER2 ) :
2007-11-22 11:40:04 +01:00
i = decode_erp ( buf [ 7 ] , buf [ 5 ] ) ;
input_report_abs ( input_dev , ABS_HAT0X , i ) ;
i = decode_erp ( buf [ 12 ] , buf [ 14 ] ) ;
input_report_abs ( input_dev , ABS_HAT0Y , i ) ;
i = decode_erp ( buf [ 15 ] , buf [ 13 ] ) ;
input_report_abs ( input_dev , ABS_HAT1X , i ) ;
i = decode_erp ( buf [ 0 ] , buf [ 2 ] ) ;
input_report_abs ( input_dev , ABS_HAT1Y , i ) ;
i = decode_erp ( buf [ 3 ] , buf [ 1 ] ) ;
input_report_abs ( input_dev , ABS_HAT2X , i ) ;
i = decode_erp ( buf [ 8 ] , buf [ 10 ] ) ;
input_report_abs ( input_dev , ABS_HAT2Y , i ) ;
i = decode_erp ( buf [ 11 ] , buf [ 9 ] ) ;
input_report_abs ( input_dev , ABS_HAT3X , i ) ;
i = decode_erp ( buf [ 4 ] , buf [ 6 ] ) ;
input_report_abs ( input_dev , ABS_HAT3Y , i ) ;
input_sync ( input_dev ) ;
break ;
2011-10-10 15:54:23 +00:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_MASCHINECONTROLLER ) :
/* 4 under the left screen */
input_report_abs ( input_dev , ABS_HAT0X , decode_erp ( buf [ 21 ] , buf [ 20 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT0Y , decode_erp ( buf [ 15 ] , buf [ 14 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT1X , decode_erp ( buf [ 9 ] , buf [ 8 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT1Y , decode_erp ( buf [ 3 ] , buf [ 2 ] ) ) ;
/* 4 under the right screen */
input_report_abs ( input_dev , ABS_HAT2X , decode_erp ( buf [ 19 ] , buf [ 18 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT2Y , decode_erp ( buf [ 13 ] , buf [ 12 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT3X , decode_erp ( buf [ 7 ] , buf [ 6 ] ) ) ;
input_report_abs ( input_dev , ABS_HAT3Y , decode_erp ( buf [ 1 ] , buf [ 0 ] ) ) ;
/* volume */
input_report_abs ( input_dev , ABS_RX , decode_erp ( buf [ 17 ] , buf [ 16 ] ) ) ;
/* tempo */
input_report_abs ( input_dev , ABS_RY , decode_erp ( buf [ 11 ] , buf [ 10 ] ) ) ;
/* swing */
input_report_abs ( input_dev , ABS_RZ , decode_erp ( buf [ 5 ] , buf [ 4 ] ) ) ;
input_sync ( input_dev ) ;
break ;
2007-03-26 19:11:24 +02:00
}
}
2013-03-03 20:46:21 +01:00
static void snd_caiaq_input_read_io ( struct snd_usb_caiaqdev * cdev ,
2010-03-22 13:13:37 +01:00
unsigned char * buf , unsigned int len )
2007-03-26 19:11:24 +02:00
{
2013-03-03 20:46:21 +01:00
struct input_dev * input_dev = cdev - > input_dev ;
2007-11-21 16:45:23 +01:00
unsigned short * keycode = input_dev - > keycode ;
2007-03-26 19:11:24 +02:00
int i ;
if ( ! keycode )
return ;
2007-11-21 16:45:23 +01:00
if ( input_dev - > id . product = = USB_PID_RIGKONTROL2 )
for ( i = 0 ; i < len ; i + + )
2007-03-26 19:11:24 +02:00
buf [ i ] = ~ buf [ i ] ;
2007-11-22 11:40:04 +01:00
for ( i = 0 ; i < input_dev - > keycodemax & & i < len * 8 ; i + + )
2007-11-21 16:45:23 +01:00
input_report_key ( input_dev , keycode [ i ] ,
buf [ i / 8 ] & ( 1 < < ( i % 8 ) ) ) ;
2007-03-26 19:11:24 +02:00
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2010-03-22 13:13:37 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER ) :
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER2 ) :
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , ABS_MISC , 255 - buf [ 4 ] ) ;
2010-03-22 13:13:37 +01:00
break ;
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
/* rotary encoders */
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , ABS_X , buf [ 5 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , ABS_Y , buf [ 5 ] > > 4 ) ;
input_report_abs ( cdev - > input_dev , ABS_Z , buf [ 6 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , ABS_MISC , buf [ 6 ] > > 4 ) ;
2010-03-22 13:13:37 +01:00
break ;
}
2007-11-22 11:40:04 +01:00
2007-11-21 16:45:23 +01:00
input_sync ( input_dev ) ;
2007-03-26 19:11:24 +02:00
}
2010-09-10 17:04:57 +08:00
# define TKS4_MSGBLOCK_SIZE 16
2013-03-03 20:46:21 +01:00
static void snd_usb_caiaq_tks4_dispatch ( struct snd_usb_caiaqdev * cdev ,
2010-09-10 17:04:57 +08:00
const unsigned char * buf ,
unsigned int len )
{
2013-03-03 20:46:22 +01:00
struct device * dev = caiaqdev_to_dev ( cdev ) ;
2010-09-10 17:04:57 +08:00
while ( len ) {
unsigned int i , block_id = ( buf [ 0 ] < < 8 ) | buf [ 1 ] ;
switch ( block_id ) {
case 0 :
/* buttons */
for ( i = 0 ; i < KONTROLS4_BUTTONS ; i + + )
2013-03-03 20:46:21 +01:00
input_report_key ( cdev - > input_dev , KONTROLS4_BUTTON ( i ) ,
2010-09-10 17:04:57 +08:00
( buf [ 4 + ( i / 8 ) ] > > ( i % 8 ) ) & 1 ) ;
break ;
case 1 :
/* left wheel */
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 36 ) , buf [ 9 ] | ( ( buf [ 8 ] & 0x3 ) < < 8 ) ) ;
2010-09-10 17:04:57 +08:00
/* right wheel */
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 37 ) , buf [ 13 ] | ( ( buf [ 12 ] & 0x3 ) < < 8 ) ) ;
2010-09-10 17:04:57 +08:00
/* rotary encoders */
2013-03-03 20:46:21 +01:00
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 38 ) , buf [ 3 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 39 ) , buf [ 4 ] > > 4 ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 40 ) , buf [ 4 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 41 ) , buf [ 5 ] > > 4 ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 42 ) , buf [ 5 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 43 ) , buf [ 6 ] > > 4 ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 44 ) , buf [ 6 ] & 0xf ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 45 ) , buf [ 7 ] > > 4 ) ;
input_report_abs ( cdev - > input_dev , KONTROLS4_ABS ( 46 ) , buf [ 7 ] & 0xf ) ;
2010-09-10 17:04:57 +08:00
break ;
case 2 :
/* Volume Fader Channel D */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 0 ) , buf , 1 ) ;
2010-09-10 17:04:57 +08:00
/* Volume Fader Channel B */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 1 ) , buf , 2 ) ;
2010-09-10 17:04:57 +08:00
/* Volume Fader Channel A */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 2 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* Volume Fader Channel C */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 3 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* Loop Volume */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 4 ) , buf , 6 ) ;
2010-09-10 17:04:57 +08:00
/* Crossfader */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 7 ) , buf , 7 ) ;
2010-09-10 17:04:57 +08:00
break ;
case 3 :
/* Tempo Fader R */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 6 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* Tempo Fader L */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 5 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* Mic Volume */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 8 ) , buf , 6 ) ;
2010-09-10 17:04:57 +08:00
/* Cue Mix */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 9 ) , buf , 7 ) ;
2010-09-10 17:04:57 +08:00
break ;
case 4 :
/* Wheel distance sensor L */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 10 ) , buf , 1 ) ;
2010-09-10 17:04:57 +08:00
/* Wheel distance sensor R */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 11 ) , buf , 2 ) ;
2010-09-10 17:04:57 +08:00
/* Channel D EQ - Filter */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 12 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* Channel D EQ - Low */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 13 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* Channel D EQ - Mid */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 14 ) , buf , 5 ) ;
2010-09-10 17:04:57 +08:00
/* Channel D EQ - Hi */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 15 ) , buf , 6 ) ;
2010-09-10 17:04:57 +08:00
/* FX2 - dry/wet */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 16 ) , buf , 7 ) ;
2010-09-10 17:04:57 +08:00
break ;
case 5 :
/* FX2 - 1 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 17 ) , buf , 1 ) ;
2010-09-10 17:04:57 +08:00
/* FX2 - 2 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 18 ) , buf , 2 ) ;
2010-09-10 17:04:57 +08:00
/* FX2 - 3 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 19 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* Channel B EQ - Filter */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 20 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* Channel B EQ - Low */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 21 ) , buf , 5 ) ;
2010-09-10 17:04:57 +08:00
/* Channel B EQ - Mid */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 22 ) , buf , 6 ) ;
2010-09-10 17:04:57 +08:00
/* Channel B EQ - Hi */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 23 ) , buf , 7 ) ;
2010-09-10 17:04:57 +08:00
break ;
case 6 :
/* Channel A EQ - Filter */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 24 ) , buf , 1 ) ;
2010-09-10 17:04:57 +08:00
/* Channel A EQ - Low */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 25 ) , buf , 2 ) ;
2010-09-10 17:04:57 +08:00
/* Channel A EQ - Mid */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 26 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* Channel A EQ - Hi */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 27 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* Channel C EQ - Filter */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 28 ) , buf , 5 ) ;
2010-09-10 17:04:57 +08:00
/* Channel C EQ - Low */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 29 ) , buf , 6 ) ;
2010-09-10 17:04:57 +08:00
/* Channel C EQ - Mid */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 30 ) , buf , 7 ) ;
2010-09-10 17:04:57 +08:00
break ;
case 7 :
/* Channel C EQ - Hi */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 31 ) , buf , 1 ) ;
2010-09-10 17:04:57 +08:00
/* FX1 - wet/dry */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 32 ) , buf , 2 ) ;
2010-09-10 17:04:57 +08:00
/* FX1 - 1 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 33 ) , buf , 3 ) ;
2010-09-10 17:04:57 +08:00
/* FX1 - 2 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 34 ) , buf , 4 ) ;
2010-09-10 17:04:57 +08:00
/* FX1 - 3 */
2013-03-03 20:46:21 +01:00
snd_caiaq_input_report_abs ( cdev , KONTROLS4_ABS ( 35 ) , buf , 5 ) ;
2010-09-10 17:04:57 +08:00
break ;
default :
2013-03-03 20:46:22 +01:00
dev_dbg ( dev , " %s(): bogus block (id %d) \n " ,
2010-09-10 17:04:57 +08:00
__func__ , block_id ) ;
return ;
}
len - = TKS4_MSGBLOCK_SIZE ;
buf + = TKS4_MSGBLOCK_SIZE ;
}
2013-03-03 20:46:21 +01:00
input_sync ( cdev - > input_dev ) ;
2010-09-10 17:04:57 +08:00
}
2011-10-10 15:54:23 +00:00
# define MASCHINE_MSGBLOCK_SIZE 2
2013-03-03 20:46:21 +01:00
static void snd_usb_caiaq_maschine_dispatch ( struct snd_usb_caiaqdev * cdev ,
2011-10-10 15:54:23 +00:00
const unsigned char * buf ,
unsigned int len )
{
unsigned int i , pad_id ;
2013-04-29 21:15:46 +02:00
__le16 * pressure = ( __le16 * ) buf ;
2011-10-10 15:54:23 +00:00
for ( i = 0 ; i < MASCHINE_PADS ; i + + ) {
2013-04-29 21:15:46 +02:00
pad_id = le16_to_cpu ( * pressure ) > > 12 ;
input_report_abs ( cdev - > input_dev , MASCHINE_PAD ( pad_id ) ,
le16_to_cpu ( * pressure ) & 0xfff ) ;
pressure + + ;
2011-10-10 15:54:23 +00:00
}
2013-03-03 20:46:21 +01:00
input_sync ( cdev - > input_dev ) ;
2011-10-10 15:54:23 +00:00
}
2010-03-22 13:13:37 +01:00
static void snd_usb_caiaq_ep4_reply_dispatch ( struct urb * urb )
{
2013-03-03 20:46:21 +01:00
struct snd_usb_caiaqdev * cdev = urb - > context ;
2010-03-22 13:13:37 +01:00
unsigned char * buf = urb - > transfer_buffer ;
2013-03-04 12:50:05 +01:00
struct device * dev = & urb - > dev - > dev ;
2010-03-22 13:13:37 +01:00
int ret ;
2013-03-03 20:46:21 +01:00
if ( urb - > status | | ! cdev | | urb ! = cdev - > ep4_in_urb )
2010-03-22 13:13:37 +01:00
return ;
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2010-03-22 13:13:37 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
2010-09-10 17:04:57 +08:00
if ( urb - > actual_length < 24 )
goto requeue ;
2010-03-22 13:13:37 +01:00
if ( buf [ 0 ] & 0x3 )
2013-03-03 20:46:21 +01:00
snd_caiaq_input_read_io ( cdev , buf + 1 , 7 ) ;
2010-03-22 13:13:37 +01:00
if ( buf [ 0 ] & 0x4 )
2013-03-03 20:46:21 +01:00
snd_caiaq_input_read_analog ( cdev , buf + 8 , 16 ) ;
2010-03-22 13:13:37 +01:00
break ;
2010-09-10 17:04:57 +08:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLS4 ) :
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_tks4_dispatch ( cdev , buf , urb - > actual_length ) ;
2010-09-10 17:04:57 +08:00
break ;
2011-10-10 15:54:23 +00:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_MASCHINECONTROLLER ) :
if ( urb - > actual_length < ( MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE ) )
goto requeue ;
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_maschine_dispatch ( cdev , buf , urb - > actual_length ) ;
2011-10-10 15:54:23 +00:00
break ;
2010-03-22 13:13:37 +01:00
}
requeue :
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_urb - > actual_length = 0 ;
ret = usb_submit_urb ( cdev - > ep4_in_urb , GFP_ATOMIC ) ;
2010-03-22 13:13:37 +01:00
if ( ret < 0 )
2013-03-03 20:46:22 +01:00
dev_err ( dev , " unable to submit urb. OOM!? \n " ) ;
2010-03-22 13:13:37 +01:00
}
static int snd_usb_caiaq_input_open ( struct input_dev * idev )
{
2013-03-03 20:46:21 +01:00
struct snd_usb_caiaqdev * cdev = input_get_drvdata ( idev ) ;
2010-03-22 13:13:37 +01:00
2013-03-03 20:46:21 +01:00
if ( ! cdev )
2010-03-22 13:13:37 +01:00
return - EINVAL ;
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2010-03-22 13:13:37 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
2010-09-10 17:04:57 +08:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLS4 ) :
2011-10-10 15:54:23 +00:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_MASCHINECONTROLLER ) :
2013-03-03 20:46:21 +01:00
if ( usb_submit_urb ( cdev - > ep4_in_urb , GFP_KERNEL ) ! = 0 )
2010-03-22 13:13:37 +01:00
return - EIO ;
break ;
}
return 0 ;
}
static void snd_usb_caiaq_input_close ( struct input_dev * idev )
{
2013-03-03 20:46:21 +01:00
struct snd_usb_caiaqdev * cdev = input_get_drvdata ( idev ) ;
2010-03-22 13:13:37 +01:00
2013-03-03 20:46:21 +01:00
if ( ! cdev )
2010-03-22 13:13:37 +01:00
return ;
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2010-03-22 13:13:37 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
2010-09-10 17:04:57 +08:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLS4 ) :
2011-10-10 15:54:23 +00:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_MASCHINECONTROLLER ) :
2013-03-03 20:46:21 +01:00
usb_kill_urb ( cdev - > ep4_in_urb ) ;
2010-03-22 13:13:37 +01:00
break ;
}
}
2013-03-03 20:46:21 +01:00
void snd_usb_caiaq_input_dispatch ( struct snd_usb_caiaqdev * cdev ,
2007-11-21 16:45:23 +01:00
char * buf ,
2007-03-26 19:11:24 +02:00
unsigned int len )
{
2013-03-03 20:46:21 +01:00
if ( ! cdev - > input_dev | | len < 1 )
2007-03-26 19:11:24 +02:00
return ;
switch ( buf [ 0 ] ) {
case EP1_CMD_READ_ANALOG :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_read_analog ( cdev , buf + 1 , len - 1 ) ;
2007-03-26 19:11:24 +02:00
break ;
case EP1_CMD_READ_ERP :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_read_erp ( cdev , buf + 1 , len - 1 ) ;
2007-03-26 19:11:24 +02:00
break ;
case EP1_CMD_READ_IO :
2013-03-03 20:46:21 +01:00
snd_caiaq_input_read_io ( cdev , buf + 1 , len - 1 ) ;
2007-03-26 19:11:24 +02:00
break ;
}
}
2013-03-03 20:46:21 +01:00
int snd_usb_caiaq_input_init ( struct snd_usb_caiaqdev * cdev )
2007-03-26 19:11:24 +02:00
{
2013-03-03 20:46:21 +01:00
struct usb_device * usb_dev = cdev - > chip . dev ;
2007-03-26 19:11:24 +02:00
struct input_dev * input ;
2010-03-22 13:13:37 +01:00
int i , ret = 0 ;
2007-03-26 19:11:24 +02:00
input = input_allocate_device ( ) ;
if ( ! input )
return - ENOMEM ;
2013-03-03 20:46:21 +01:00
usb_make_path ( usb_dev , cdev - > phys , sizeof ( cdev - > phys ) ) ;
strlcat ( cdev - > phys , " /input0 " , sizeof ( cdev - > phys ) ) ;
2007-11-21 16:45:23 +01:00
2013-03-03 20:46:21 +01:00
input - > name = cdev - > product_name ;
input - > phys = cdev - > phys ;
2007-11-21 16:45:23 +01:00
usb_to_input_id ( usb_dev , & input - > id ) ;
input - > dev . parent = & usb_dev - > dev ;
2007-03-26 19:11:24 +02:00
2013-03-03 20:46:21 +01:00
input_set_drvdata ( input , cdev ) ;
2010-03-22 13:13:37 +01:00
2013-03-03 20:46:21 +01:00
switch ( cdev - > chip . usb_id ) {
2007-03-26 19:11:24 +02:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_RIGKONTROL2 ) :
2007-10-18 23:40:32 -07:00
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_X ) | BIT_MASK ( ABS_Y ) |
BIT_MASK ( ABS_Z ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < sizeof ( keycode_rk2 ) ) ;
memcpy ( cdev - > keycode , keycode_rk2 , sizeof ( keycode_rk2 ) ) ;
2007-03-26 19:11:24 +02:00
input - > keycodemax = ARRAY_SIZE ( keycode_rk2 ) ;
input_set_abs_params ( input , ABS_X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Y , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Z , 0 , 4096 , 0 , 10 ) ;
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 0 ) ;
2007-03-26 19:11:24 +02:00
break ;
2007-09-17 14:45:14 +02:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_RIGKONTROL3 ) :
2007-11-22 11:40:04 +01:00
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_X ) | BIT_MASK ( ABS_Y ) |
BIT_MASK ( ABS_Z ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < sizeof ( keycode_rk3 ) ) ;
memcpy ( cdev - > keycode , keycode_rk3 , sizeof ( keycode_rk3 ) ) ;
2007-09-17 14:45:14 +02:00
input - > keycodemax = ARRAY_SIZE ( keycode_rk3 ) ;
input_set_abs_params ( input , ABS_X , 0 , 1024 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Y , 0 , 1024 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Z , 0 , 1024 , 0 , 10 ) ;
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 0 ) ;
2007-09-17 14:45:14 +02:00
break ;
2007-03-26 19:11:24 +02:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_AK1 ) :
2007-10-18 23:40:32 -07:00
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_X ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < sizeof ( keycode_ak1 ) ) ;
memcpy ( cdev - > keycode , keycode_ak1 , sizeof ( keycode_ak1 ) ) ;
2007-03-26 19:11:24 +02:00
input - > keycodemax = ARRAY_SIZE ( keycode_ak1 ) ;
input_set_abs_params ( input , ABS_X , 0 , 999 , 0 , 10 ) ;
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 0 , 5 ) ;
2007-03-26 19:11:24 +02:00
break ;
2007-11-22 11:40:04 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER ) :
2007-11-26 09:00:56 +01:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_KORECONTROLLER2 ) :
2007-11-22 11:40:04 +01:00
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_HAT0X ) | BIT_MASK ( ABS_HAT0Y ) |
BIT_MASK ( ABS_HAT1X ) | BIT_MASK ( ABS_HAT1Y ) |
BIT_MASK ( ABS_HAT2X ) | BIT_MASK ( ABS_HAT2Y ) |
BIT_MASK ( ABS_HAT3X ) | BIT_MASK ( ABS_HAT3Y ) |
BIT_MASK ( ABS_X ) | BIT_MASK ( ABS_Y ) |
BIT_MASK ( ABS_Z ) ;
input - > absbit [ BIT_WORD ( ABS_MISC ) ] | = BIT_MASK ( ABS_MISC ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < sizeof ( keycode_kore ) ) ;
memcpy ( cdev - > keycode , keycode_kore , sizeof ( keycode_kore ) ) ;
2007-11-22 11:40:04 +01:00
input - > keycodemax = ARRAY_SIZE ( keycode_kore ) ;
input_set_abs_params ( input , ABS_HAT0X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT0Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Y , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_Z , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_MISC , 0 , 255 , 0 , 1 ) ;
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 5 ) ;
2010-03-22 13:13:37 +01:00
break ;
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLX1 ) :
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_HAT0X ) | BIT_MASK ( ABS_HAT0Y ) |
BIT_MASK ( ABS_HAT1X ) | BIT_MASK ( ABS_HAT1Y ) |
BIT_MASK ( ABS_HAT2X ) | BIT_MASK ( ABS_HAT2Y ) |
BIT_MASK ( ABS_HAT3X ) | BIT_MASK ( ABS_HAT3Y ) |
BIT_MASK ( ABS_X ) | BIT_MASK ( ABS_Y ) |
BIT_MASK ( ABS_Z ) ;
input - > absbit [ BIT_WORD ( ABS_MISC ) ] | = BIT_MASK ( ABS_MISC ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < KONTROLX1_INPUTS ) ;
2010-03-22 13:13:37 +01:00
for ( i = 0 ; i < KONTROLX1_INPUTS ; i + + )
2013-03-03 20:46:21 +01:00
cdev - > keycode [ i ] = BTN_MISC + i ;
2010-03-22 13:13:37 +01:00
input - > keycodemax = KONTROLX1_INPUTS ;
/* analog potentiometers */
input_set_abs_params ( input , ABS_HAT0X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT0Y , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1Y , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2Y , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3X , 0 , 4096 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3Y , 0 , 4096 , 0 , 10 ) ;
/* rotary encoders */
input_set_abs_params ( input , ABS_X , 0 , 0xf , 0 , 1 ) ;
input_set_abs_params ( input , ABS_Y , 0 , 0xf , 0 , 1 ) ;
input_set_abs_params ( input , ABS_Z , 0 , 0xf , 0 , 1 ) ;
input_set_abs_params ( input , ABS_MISC , 0 , 0xf , 0 , 1 ) ;
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! cdev - > ep4_in_urb ) {
2010-03-22 13:13:37 +01:00
ret = - ENOMEM ;
goto exit_free_idev ;
}
2013-03-03 20:46:21 +01:00
usb_fill_bulk_urb ( cdev - > ep4_in_urb , usb_dev ,
2010-03-22 13:13:37 +01:00
usb_rcvbulkpipe ( usb_dev , 0x4 ) ,
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_buf , EP4_BUFSIZE ,
snd_usb_caiaq_ep4_reply_dispatch , cdev ) ;
2017-10-10 12:30:41 +02:00
ret = usb_urb_ep_type_check ( cdev - > ep4_in_urb ) ;
if ( ret < 0 )
goto exit_free_idev ;
2010-03-22 13:13:37 +01:00
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 5 ) ;
2010-03-22 13:13:37 +01:00
2007-11-22 11:40:04 +01:00
break ;
2010-09-10 17:04:57 +08:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_TRAKTORKONTROLS4 ) :
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < KONTROLS4_BUTTONS ) ;
2010-09-10 17:04:57 +08:00
for ( i = 0 ; i < KONTROLS4_BUTTONS ; i + + )
2013-03-03 20:46:21 +01:00
cdev - > keycode [ i ] = KONTROLS4_BUTTON ( i ) ;
2010-09-10 17:04:57 +08:00
input - > keycodemax = KONTROLS4_BUTTONS ;
for ( i = 0 ; i < KONTROLS4_AXIS ; i + + ) {
int axis = KONTROLS4_ABS ( i ) ;
input - > absbit [ BIT_WORD ( axis ) ] | = BIT_MASK ( axis ) ;
}
/* 36 analog potentiometers and faders */
for ( i = 0 ; i < 36 ; i + + )
input_set_abs_params ( input , KONTROLS4_ABS ( i ) , 0 , 0xfff , 0 , 10 ) ;
/* 2 encoder wheels */
input_set_abs_params ( input , KONTROLS4_ABS ( 36 ) , 0 , 0x3ff , 0 , 1 ) ;
input_set_abs_params ( input , KONTROLS4_ABS ( 37 ) , 0 , 0x3ff , 0 , 1 ) ;
/* 9 rotary encoders */
for ( i = 0 ; i < 9 ; i + + )
input_set_abs_params ( input , KONTROLS4_ABS ( 38 + i ) , 0 , 0xf , 0 , 1 ) ;
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! cdev - > ep4_in_urb ) {
2010-09-10 17:04:57 +08:00
ret = - ENOMEM ;
goto exit_free_idev ;
}
2013-03-03 20:46:21 +01:00
usb_fill_bulk_urb ( cdev - > ep4_in_urb , usb_dev ,
2010-09-10 17:04:57 +08:00
usb_rcvbulkpipe ( usb_dev , 0x4 ) ,
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_buf , EP4_BUFSIZE ,
snd_usb_caiaq_ep4_reply_dispatch , cdev ) ;
2017-10-10 12:30:41 +02:00
ret = usb_urb_ep_type_check ( cdev - > ep4_in_urb ) ;
if ( ret < 0 )
goto exit_free_idev ;
2010-09-10 17:04:57 +08:00
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 5 ) ;
2010-09-10 17:04:57 +08:00
break ;
2011-10-10 15:54:23 +00:00
case USB_ID ( USB_VID_NATIVEINSTRUMENTS , USB_PID_MASCHINECONTROLLER ) :
input - > evbit [ 0 ] = BIT_MASK ( EV_KEY ) | BIT_MASK ( EV_ABS ) ;
input - > absbit [ 0 ] = BIT_MASK ( ABS_HAT0X ) | BIT_MASK ( ABS_HAT0Y ) |
BIT_MASK ( ABS_HAT1X ) | BIT_MASK ( ABS_HAT1Y ) |
BIT_MASK ( ABS_HAT2X ) | BIT_MASK ( ABS_HAT2Y ) |
BIT_MASK ( ABS_HAT3X ) | BIT_MASK ( ABS_HAT3Y ) |
BIT_MASK ( ABS_RX ) | BIT_MASK ( ABS_RY ) |
BIT_MASK ( ABS_RZ ) ;
2013-03-03 20:46:21 +01:00
BUILD_BUG_ON ( sizeof ( cdev - > keycode ) < sizeof ( keycode_maschine ) ) ;
memcpy ( cdev - > keycode , keycode_maschine , sizeof ( keycode_maschine ) ) ;
2011-10-10 15:54:23 +00:00
input - > keycodemax = ARRAY_SIZE ( keycode_maschine ) ;
for ( i = 0 ; i < MASCHINE_PADS ; i + + ) {
input - > absbit [ 0 ] | = MASCHINE_PAD ( i ) ;
input_set_abs_params ( input , MASCHINE_PAD ( i ) , 0 , 0xfff , 5 , 10 ) ;
}
input_set_abs_params ( input , ABS_HAT0X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT0Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT1Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT2Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3X , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_HAT3Y , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_RX , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_RY , 0 , 999 , 0 , 10 ) ;
input_set_abs_params ( input , ABS_RZ , 0 , 999 , 0 , 10 ) ;
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! cdev - > ep4_in_urb ) {
2011-10-10 15:54:23 +00:00
ret = - ENOMEM ;
goto exit_free_idev ;
}
2013-03-03 20:46:21 +01:00
usb_fill_bulk_urb ( cdev - > ep4_in_urb , usb_dev ,
2011-10-10 15:54:23 +00:00
usb_rcvbulkpipe ( usb_dev , 0x4 ) ,
2013-03-03 20:46:21 +01:00
cdev - > ep4_in_buf , EP4_BUFSIZE ,
snd_usb_caiaq_ep4_reply_dispatch , cdev ) ;
2017-10-10 12:30:41 +02:00
ret = usb_urb_ep_type_check ( cdev - > ep4_in_urb ) ;
if ( ret < 0 )
goto exit_free_idev ;
2011-10-10 15:54:23 +00:00
2013-03-03 20:46:21 +01:00
snd_usb_caiaq_set_auto_msg ( cdev , 1 , 10 , 5 ) ;
2011-10-10 15:54:23 +00:00
break ;
2007-03-26 19:11:24 +02:00
default :
/* no input methods supported on this device */
2010-03-22 13:13:37 +01:00
goto exit_free_idev ;
2007-03-26 19:11:24 +02:00
}
2010-03-22 13:13:37 +01:00
input - > open = snd_usb_caiaq_input_open ;
input - > close = snd_usb_caiaq_input_close ;
2013-03-03 20:46:21 +01:00
input - > keycode = cdev - > keycode ;
2007-11-21 16:45:23 +01:00
input - > keycodesize = sizeof ( unsigned short ) ;
for ( i = 0 ; i < input - > keycodemax ; i + + )
2013-03-03 20:46:21 +01:00
__set_bit ( cdev - > keycode [ i ] , input - > keybit ) ;
2007-11-21 16:45:23 +01:00
2013-03-03 20:46:21 +01:00
cdev - > input_dev = input ;
2011-10-10 15:54:22 +00:00
2007-03-26 19:11:24 +02:00
ret = input_register_device ( input ) ;
2010-03-22 13:13:37 +01:00
if ( ret < 0 )
goto exit_free_idev ;
2007-03-26 19:11:24 +02:00
return 0 ;
2010-03-22 13:13:37 +01:00
exit_free_idev :
input_free_device ( input ) ;
2013-03-03 20:46:21 +01:00
cdev - > input_dev = NULL ;
2010-03-22 13:13:37 +01:00
return ret ;
2007-03-26 19:11:24 +02:00
}
2013-03-03 20:46:21 +01:00
void snd_usb_caiaq_input_free ( struct snd_usb_caiaqdev * cdev )
2007-03-26 19:11:24 +02:00
{
2013-03-03 20:46:21 +01:00
if ( ! cdev | | ! cdev - > input_dev )
2007-03-26 19:11:24 +02:00
return ;
2013-03-03 20:46:21 +01:00
usb_kill_urb ( cdev - > ep4_in_urb ) ;
usb_free_urb ( cdev - > ep4_in_urb ) ;
cdev - > ep4_in_urb = NULL ;
2010-03-22 13:13:37 +01:00
2013-03-03 20:46:21 +01:00
input_unregister_device ( cdev - > input_dev ) ;
cdev - > input_dev = NULL ;
2007-03-26 19:11:24 +02:00
}