| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 1 | /* | 
 | 2 |  *   Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz | 
 | 3 |  * | 
 | 4 |  *   This program is free software; you can redistribute it and/or modify | 
 | 5 |  *   it under the terms of the GNU General Public License as published by | 
 | 6 |  *   the Free Software Foundation; either version 2 of the License, or | 
 | 7 |  *   (at your option) any later version. | 
 | 8 |  * | 
 | 9 |  *   This program is distributed in the hope that it will be useful, | 
 | 10 |  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 11 |  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 12 |  *   GNU General Public License for more details. | 
 | 13 |  * | 
 | 14 |  *   You should have received a copy of the GNU General Public License | 
 | 15 |  *   along with this program; if not, write to the Free Software | 
 | 16 |  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA | 
 | 17 | */ | 
 | 18 |  | 
 | 19 | #include <linux/init.h> | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 20 | #include <linux/usb.h> | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 21 | #include <linux/usb/input.h> | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 22 | #include <sound/pcm.h> | 
| Daniel Mack | 936e7d0 | 2009-04-01 19:05:39 +0200 | [diff] [blame] | 23 |  | 
 | 24 | #include "device.h" | 
 | 25 | #include "input.h" | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 26 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 27 | static unsigned short keycode_ak1[] =  { KEY_C, KEY_B, KEY_A }; | 
 | 28 | static unsigned short keycode_rk2[] =  { KEY_1, KEY_2, KEY_3, KEY_4, | 
 | 29 | 					 KEY_5, KEY_6, KEY_7 }; | 
 | 30 | static unsigned short keycode_rk3[] =  { KEY_1, KEY_2, KEY_3, KEY_4, | 
 | 31 | 					 KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 32 |  | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 33 | static unsigned short keycode_kore[] = { | 
 | 34 | 	KEY_FN_F1,      /* "menu"               */ | 
 | 35 | 	KEY_FN_F7,      /* "lcd backlight       */ | 
 | 36 | 	KEY_FN_F2,      /* "control"            */ | 
 | 37 | 	KEY_FN_F3,      /* "enter"              */ | 
 | 38 | 	KEY_FN_F4,      /* "view"               */ | 
 | 39 | 	KEY_FN_F5,      /* "esc"                */ | 
 | 40 | 	KEY_FN_F6,      /* "sound"              */ | 
 | 41 | 	KEY_FN_F8,      /* array spacer, never triggered. */ | 
 | 42 | 	KEY_RIGHT, | 
 | 43 | 	KEY_DOWN, | 
 | 44 | 	KEY_UP, | 
 | 45 | 	KEY_LEFT, | 
 | 46 | 	KEY_SOUND,      /* "listen"             */ | 
 | 47 | 	KEY_RECORD, | 
 | 48 | 	KEY_PLAYPAUSE, | 
 | 49 | 	KEY_STOP, | 
 | 50 | 	BTN_4,          /* 8 softkeys */ | 
 | 51 | 	BTN_3, | 
 | 52 | 	BTN_2, | 
 | 53 | 	BTN_1, | 
 | 54 | 	BTN_8, | 
 | 55 | 	BTN_7, | 
 | 56 | 	BTN_6, | 
 | 57 | 	BTN_5, | 
 | 58 | 	KEY_BRL_DOT4,   /* touch sensitive knobs */ | 
 | 59 | 	KEY_BRL_DOT3, | 
 | 60 | 	KEY_BRL_DOT2, | 
 | 61 | 	KEY_BRL_DOT1, | 
 | 62 | 	KEY_BRL_DOT8, | 
 | 63 | 	KEY_BRL_DOT7, | 
 | 64 | 	KEY_BRL_DOT6, | 
 | 65 | 	KEY_BRL_DOT5 | 
 | 66 | }; | 
 | 67 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 68 | #define DEG90		(range / 2) | 
 | 69 | #define DEG180		(range) | 
 | 70 | #define DEG270		(DEG90 + DEG180) | 
 | 71 | #define DEG360		(DEG180 * 2) | 
 | 72 | #define HIGH_PEAK	(268) | 
 | 73 | #define LOW_PEAK	(-7) | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 74 |  | 
 | 75 | /* some of these devices have endless rotation potentiometers | 
 | 76 |  * built in which use two tapers, 90 degrees phase shifted. | 
 | 77 |  * this algorithm decodes them to one single value, ranging | 
 | 78 |  * from 0 to 999 */ | 
 | 79 | static unsigned int decode_erp(unsigned char a, unsigned char b) | 
 | 80 | { | 
 | 81 | 	int weight_a, weight_b; | 
 | 82 | 	int pos_a, pos_b; | 
 | 83 | 	int ret; | 
 | 84 | 	int range = HIGH_PEAK - LOW_PEAK; | 
 | 85 | 	int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; | 
 | 86 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 87 | 	weight_b = abs(mid_value - a) - (range / 2 - 100) / 2; | 
 | 88 |  | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 89 | 	if (weight_b < 0) | 
 | 90 | 		weight_b = 0; | 
 | 91 |  | 
 | 92 | 	if (weight_b > 100) | 
 | 93 | 		weight_b = 100; | 
 | 94 |  | 
 | 95 | 	weight_a = 100 - weight_b; | 
 | 96 |  | 
 | 97 | 	if (a < mid_value) { | 
 | 98 | 		/* 0..90 and 270..360 degrees */ | 
 | 99 | 		pos_b = b - LOW_PEAK + DEG270; | 
 | 100 | 		if (pos_b >= DEG360) | 
 | 101 | 			pos_b -= DEG360; | 
 | 102 | 	} else | 
 | 103 | 		/* 90..270 degrees */ | 
 | 104 | 		pos_b = HIGH_PEAK - b + DEG90; | 
 | 105 |  | 
 | 106 |  | 
 | 107 | 	if (b > mid_value) | 
 | 108 | 		/* 0..180 degrees */ | 
 | 109 | 		pos_a = a - LOW_PEAK; | 
 | 110 | 	else | 
 | 111 | 		/* 180..360 degrees */ | 
 | 112 | 		pos_a = HIGH_PEAK - a + DEG180; | 
 | 113 |  | 
 | 114 | 	/* interpolate both slider values, depending on weight factors */ | 
 | 115 | 	/* 0..99 x DEG360 */ | 
 | 116 | 	ret = pos_a * weight_a + pos_b * weight_b; | 
 | 117 |  | 
 | 118 | 	/* normalize to 0..999 */ | 
 | 119 | 	ret *= 10; | 
 | 120 | 	ret /= DEG360; | 
 | 121 |  | 
 | 122 | 	if (ret < 0) | 
 | 123 | 		ret += 1000; | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 124 |  | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 125 | 	if (ret >= 1000) | 
 | 126 | 		ret -= 1000; | 
 | 127 |  | 
 | 128 | 	return ret; | 
 | 129 | } | 
 | 130 |  | 
 | 131 | #undef DEG90 | 
 | 132 | #undef DEG180 | 
 | 133 | #undef DEG270 | 
 | 134 | #undef DEG360 | 
 | 135 | #undef HIGH_PEAK | 
 | 136 | #undef LOW_PEAK | 
 | 137 |  | 
 | 138 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 139 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | 
| Daniel Mack | ad1e34b | 2007-09-17 14:45:14 +0200 | [diff] [blame] | 140 | 					const unsigned char *buf, | 
 | 141 | 					unsigned int len) | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 142 | { | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 143 | 	struct input_dev *input_dev = dev->input_dev; | 
 | 144 |  | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 145 | 	switch (dev->chip.usb_id) { | 
 | 146 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 147 | 		input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); | 
 | 148 | 		input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); | 
 | 149 | 		input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); | 
 | 150 | 		input_sync(input_dev); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 151 | 		break; | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 152 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 
 | 153 | 		input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); | 
 | 154 | 		input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); | 
 | 155 | 		input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); | 
 | 156 | 		input_sync(input_dev); | 
 | 157 | 		break; | 
 | 158 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 
| Daniel Mack | 7829d0e | 2007-11-26 09:00:56 +0100 | [diff] [blame] | 159 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 160 | 		input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); | 
 | 161 | 		input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); | 
 | 162 | 		input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); | 
 | 163 | 		input_sync(input_dev); | 
| Daniel Mack | ad1e34b | 2007-09-17 14:45:14 +0200 | [diff] [blame] | 164 | 		break; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 165 | 	} | 
 | 166 | } | 
 | 167 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 168 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 169 | 				     const char *buf, unsigned int len) | 
 | 170 | { | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 171 | 	struct input_dev *input_dev = dev->input_dev; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 172 | 	int i; | 
 | 173 |  | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 174 | 	switch (dev->chip.usb_id) { | 
 | 175 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 176 | 		i = decode_erp(buf[0], buf[1]); | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 177 | 		input_report_abs(input_dev, ABS_X, i); | 
 | 178 | 		input_sync(input_dev); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 179 | 		break; | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 180 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 
| Daniel Mack | 7829d0e | 2007-11-26 09:00:56 +0100 | [diff] [blame] | 181 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 182 | 		i = decode_erp(buf[7], buf[5]); | 
 | 183 | 		input_report_abs(input_dev, ABS_HAT0X, i); | 
 | 184 | 		i = decode_erp(buf[12], buf[14]); | 
 | 185 | 		input_report_abs(input_dev, ABS_HAT0Y, i); | 
 | 186 | 		i = decode_erp(buf[15], buf[13]); | 
 | 187 | 		input_report_abs(input_dev, ABS_HAT1X, i); | 
 | 188 | 		i = decode_erp(buf[0], buf[2]); | 
 | 189 | 		input_report_abs(input_dev, ABS_HAT1Y, i); | 
 | 190 | 		i = decode_erp(buf[3], buf[1]); | 
 | 191 | 		input_report_abs(input_dev, ABS_HAT2X, i); | 
 | 192 | 		i = decode_erp(buf[8], buf[10]); | 
 | 193 | 		input_report_abs(input_dev, ABS_HAT2Y, i); | 
 | 194 | 		i = decode_erp(buf[11], buf[9]); | 
 | 195 | 		input_report_abs(input_dev, ABS_HAT3X, i); | 
 | 196 | 		i = decode_erp(buf[4], buf[6]); | 
 | 197 | 		input_report_abs(input_dev, ABS_HAT3Y, i); | 
 | 198 | 		input_sync(input_dev); | 
 | 199 | 		break; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 200 | 	} | 
 | 201 | } | 
 | 202 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 203 | static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 204 | 				    char *buf, unsigned int len) | 
 | 205 | { | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 206 | 	struct input_dev *input_dev = dev->input_dev; | 
 | 207 | 	unsigned short *keycode = input_dev->keycode; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 208 | 	int i; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 209 |  | 
 | 210 | 	if (!keycode) | 
 | 211 | 		return; | 
 | 212 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 213 | 	if (input_dev->id.product == USB_PID_RIGKONTROL2) | 
 | 214 | 		for (i = 0; i < len; i++) | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 215 | 			buf[i] = ~buf[i]; | 
 | 216 |  | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 217 | 	for (i = 0; i < input_dev->keycodemax && i < len * 8; i++) | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 218 | 		input_report_key(input_dev, keycode[i], | 
 | 219 | 				 buf[i / 8] & (1 << (i % 8))); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 220 |  | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 221 | 	if (dev->chip.usb_id == | 
| Daniel Mack | 7829d0e | 2007-11-26 09:00:56 +0100 | [diff] [blame] | 222 | 		USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || | 
 | 223 | 	    dev->chip.usb_id == | 
 | 224 | 		USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2)) | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 225 | 		input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); | 
 | 226 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 227 | 	input_sync(input_dev); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 228 | } | 
 | 229 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 230 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, | 
 | 231 | 				  char *buf, | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 232 | 				  unsigned int len) | 
 | 233 | { | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 234 | 	if (!dev->input_dev || len < 1) | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 235 | 		return; | 
 | 236 |  | 
 | 237 | 	switch (buf[0]) { | 
 | 238 | 	case EP1_CMD_READ_ANALOG: | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 239 | 		snd_caiaq_input_read_analog(dev, buf + 1, len - 1); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 240 | 		break; | 
 | 241 | 	case EP1_CMD_READ_ERP: | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 242 | 		snd_caiaq_input_read_erp(dev, buf + 1, len - 1); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 243 | 		break; | 
 | 244 | 	case EP1_CMD_READ_IO: | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 245 | 		snd_caiaq_input_read_io(dev, buf + 1, len - 1); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 246 | 		break; | 
 | 247 | 	} | 
 | 248 | } | 
 | 249 |  | 
 | 250 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | 
 | 251 | { | 
 | 252 | 	struct usb_device *usb_dev = dev->chip.dev; | 
 | 253 | 	struct input_dev *input; | 
 | 254 | 	int i, ret; | 
 | 255 |  | 
 | 256 | 	input = input_allocate_device(); | 
 | 257 | 	if (!input) | 
 | 258 | 		return -ENOMEM; | 
 | 259 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 260 | 	usb_make_path(usb_dev, dev->phys, sizeof(dev->phys)); | 
 | 261 | 	strlcat(dev->phys, "/input0", sizeof(dev->phys)); | 
 | 262 |  | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 263 | 	input->name = dev->product_name; | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 264 | 	input->phys = dev->phys; | 
 | 265 | 	usb_to_input_id(usb_dev, &input->id); | 
 | 266 | 	input->dev.parent = &usb_dev->dev; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 267 |  | 
 | 268 |         switch (dev->chip.usb_id) { | 
 | 269 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 
| Jiri Slaby | 7b19ada | 2007-10-18 23:40:32 -0700 | [diff] [blame] | 270 | 		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 
 | 271 | 		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 
 | 272 | 			BIT_MASK(ABS_Z); | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 273 | 		BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk2)); | 
 | 274 | 		memcpy(dev->keycode, keycode_rk2, sizeof(keycode_rk2)); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 275 | 		input->keycodemax = ARRAY_SIZE(keycode_rk2); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 276 | 		input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); | 
 | 277 | 		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); | 
 | 278 | 		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); | 
 | 279 | 		snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); | 
 | 280 | 		break; | 
| Daniel Mack | ad1e34b | 2007-09-17 14:45:14 +0200 | [diff] [blame] | 281 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 282 | 		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 
 | 283 | 		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 
 | 284 | 			BIT_MASK(ABS_Z); | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 285 | 		BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3)); | 
 | 286 | 		memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3)); | 
| Daniel Mack | ad1e34b | 2007-09-17 14:45:14 +0200 | [diff] [blame] | 287 | 		input->keycodemax = ARRAY_SIZE(keycode_rk3); | 
| Daniel Mack | ad1e34b | 2007-09-17 14:45:14 +0200 | [diff] [blame] | 288 | 		input_set_abs_params(input, ABS_X, 0, 1024, 0, 10); | 
 | 289 | 		input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10); | 
 | 290 | 		input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10); | 
 | 291 | 		snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); | 
 | 292 | 		break; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 293 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 
| Jiri Slaby | 7b19ada | 2007-10-18 23:40:32 -0700 | [diff] [blame] | 294 | 		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 
 | 295 | 		input->absbit[0] = BIT_MASK(ABS_X); | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 296 | 		BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1)); | 
 | 297 | 		memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1)); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 298 | 		input->keycodemax = ARRAY_SIZE(keycode_ak1); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 299 | 		input_set_abs_params(input, ABS_X, 0, 999, 0, 10); | 
 | 300 | 		snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); | 
 | 301 | 		break; | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 302 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 
| Daniel Mack | 7829d0e | 2007-11-26 09:00:56 +0100 | [diff] [blame] | 303 | 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 
| Daniel Mack | 8e3cd08 | 2007-11-22 11:40:04 +0100 | [diff] [blame] | 304 | 		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 
 | 305 | 		input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | | 
 | 306 | 				   BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | | 
 | 307 | 				   BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | | 
 | 308 | 				   BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | | 
 | 309 | 				   BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 
 | 310 | 				   BIT_MASK(ABS_Z); | 
 | 311 | 		input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 
 | 312 | 		BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore)); | 
 | 313 | 		memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore)); | 
 | 314 | 		input->keycodemax = ARRAY_SIZE(keycode_kore); | 
 | 315 | 		input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); | 
 | 316 | 		input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); | 
 | 317 | 		input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); | 
 | 318 | 		input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); | 
 | 319 | 		input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); | 
 | 320 | 		input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); | 
 | 321 | 		input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); | 
 | 322 | 		input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); | 
 | 323 | 		input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); | 
 | 324 | 		input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); | 
 | 325 | 		input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); | 
 | 326 | 		input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); | 
 | 327 | 		snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 
 | 328 | 		break; | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 329 | 	default: | 
 | 330 | 		/* no input methods supported on this device */ | 
 | 331 | 		input_free_device(input); | 
 | 332 | 		return 0; | 
 | 333 | 	} | 
 | 334 |  | 
| Dmitry Torokhov | b18b493 | 2007-11-21 16:45:23 +0100 | [diff] [blame] | 335 | 	input->keycode = dev->keycode; | 
 | 336 | 	input->keycodesize = sizeof(unsigned short); | 
 | 337 | 	for (i = 0; i < input->keycodemax; i++) | 
 | 338 | 		__set_bit(dev->keycode[i], input->keybit); | 
 | 339 |  | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 340 | 	ret = input_register_device(input); | 
 | 341 | 	if (ret < 0) { | 
 | 342 | 		input_free_device(input); | 
 | 343 | 		return ret; | 
 | 344 | 	} | 
 | 345 |  | 
 | 346 | 	dev->input_dev = input; | 
 | 347 | 	return 0; | 
 | 348 | } | 
 | 349 |  | 
 | 350 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | 
 | 351 | { | 
 | 352 | 	if (!dev || !dev->input_dev) | 
 | 353 | 		return; | 
 | 354 |  | 
 | 355 | 	input_unregister_device(dev->input_dev); | 
| Daniel Mack | 523f1dc | 2007-03-26 19:11:24 +0200 | [diff] [blame] | 356 | 	dev->input_dev = NULL; | 
 | 357 | } | 
 | 358 |  |