aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/caiaq/input.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-03-22 08:13:37 -0400
committerTakashi Iwai <tiwai@suse.de>2010-03-22 11:10:41 -0400
commit6da7a2aa899f75116e1a62cef78c358ada9878b7 (patch)
tree64099b4ea88f717623ec720293727e5048a9bd37 /sound/usb/caiaq/input.c
parentfc8aa7b16a5fcfe9c6d0be9bb587f1fcedd9145f (diff)
ALSA: usb/caiaq: Add support for Traktor Kontrol X1
This device does not have audio controllers and backlit buttons only. Input data is handled over a dedicated USB endpoint. All functions are supported by the driver now. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/caiaq/input.c')
-rw-r--r--sound/usb/caiaq/input.c162
1 files changed, 149 insertions, 13 deletions
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index a48d309bd94c..27ed0bc651ae 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -19,6 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/usb.h> 20#include <linux/usb.h>
21#include <linux/usb/input.h> 21#include <linux/usb/input.h>
22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23 24
24#include "device.h" 25#include "device.h"
@@ -65,6 +66,8 @@ static unsigned short keycode_kore[] = {
65 KEY_BRL_DOT5 66 KEY_BRL_DOT5
66}; 67};
67 68
69#define KONTROLX1_INPUTS 40
70
68#define DEG90 (range / 2) 71#define DEG90 (range / 2)
69#define DEG180 (range) 72#define DEG180 (range)
70#define DEG270 (DEG90 + DEG180) 73#define DEG270 (DEG90 + DEG180)
@@ -162,6 +165,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
162 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 165 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
163 input_sync(input_dev); 166 input_sync(input_dev);
164 break; 167 break;
168 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
169 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]);
170 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]);
171 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]);
172 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]);
173 input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]);
174 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]);
175 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]);
176 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]);
177 input_sync(input_dev);
178 break;
165 } 179 }
166} 180}
167 181
@@ -201,7 +215,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
201} 215}
202 216
203static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, 217static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
204 char *buf, unsigned int len) 218 unsigned char *buf, unsigned int len)
205{ 219{
206 struct input_dev *input_dev = dev->input_dev; 220 struct input_dev *input_dev = dev->input_dev;
207 unsigned short *keycode = input_dev->keycode; 221 unsigned short *keycode = input_dev->keycode;
@@ -218,15 +232,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
218 input_report_key(input_dev, keycode[i], 232 input_report_key(input_dev, keycode[i],
219 buf[i / 8] & (1 << (i % 8))); 233 buf[i / 8] & (1 << (i % 8)));
220 234
221 if (dev->chip.usb_id == 235 switch (dev->chip.usb_id) {
222 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || 236 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
223 dev->chip.usb_id == 237 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
224 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2))
225 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); 238 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
239 break;
240 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
241 /* rotary encoders */
242 input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
243 input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
244 input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
245 input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
246 break;
247 }
226 248
227 input_sync(input_dev); 249 input_sync(input_dev);
228} 250}
229 251
252static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
253{
254 struct snd_usb_caiaqdev *dev = urb->context;
255 unsigned char *buf = urb->transfer_buffer;
256 int ret;
257
258 if (urb->status || !dev || urb != dev->ep4_in_urb)
259 return;
260
261 if (urb->actual_length < 24)
262 goto requeue;
263
264 switch (dev->chip.usb_id) {
265 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
266 if (buf[0] & 0x3)
267 snd_caiaq_input_read_io(dev, buf + 1, 7);
268
269 if (buf[0] & 0x4)
270 snd_caiaq_input_read_analog(dev, buf + 8, 16);
271
272 break;
273 }
274
275requeue:
276 dev->ep4_in_urb->actual_length = 0;
277 ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
278 if (ret < 0)
279 log("unable to submit urb. OOM!?\n");
280}
281
282static int snd_usb_caiaq_input_open(struct input_dev *idev)
283{
284 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
285
286 if (!dev)
287 return -EINVAL;
288
289 switch (dev->chip.usb_id) {
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
291 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
292 return -EIO;
293 break;
294 }
295
296 return 0;
297}
298
299static void snd_usb_caiaq_input_close(struct input_dev *idev)
300{
301 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
302
303 if (!dev)
304 return;
305
306 switch (dev->chip.usb_id) {
307 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
308 usb_kill_urb(dev->ep4_in_urb);
309 break;
310 }
311}
312
230void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, 313void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
231 char *buf, 314 char *buf,
232 unsigned int len) 315 unsigned int len)
@@ -251,7 +334,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
251{ 334{
252 struct usb_device *usb_dev = dev->chip.dev; 335 struct usb_device *usb_dev = dev->chip.dev;
253 struct input_dev *input; 336 struct input_dev *input;
254 int i, ret; 337 int i, ret = 0;
255 338
256 input = input_allocate_device(); 339 input = input_allocate_device();
257 if (!input) 340 if (!input)
@@ -265,7 +348,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
265 usb_to_input_id(usb_dev, &input->id); 348 usb_to_input_id(usb_dev, &input->id);
266 input->dev.parent = &usb_dev->dev; 349 input->dev.parent = &usb_dev->dev;
267 350
268 switch (dev->chip.usb_id) { 351 input_set_drvdata(input, dev);
352
353 switch (dev->chip.usb_id) {
269 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 354 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
270 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 355 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
271 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 356 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
@@ -326,25 +411,72 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
326 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); 411 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
327 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 412 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
328 break; 413 break;
414 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
415 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
416 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
417 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
418 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
419 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
420 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
421 BIT_MASK(ABS_Z);
422 input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
423 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
424 for (i = 0; i < KONTROLX1_INPUTS; i++)
425 dev->keycode[i] = BTN_MISC + i;
426 input->keycodemax = KONTROLX1_INPUTS;
427
428 /* analog potentiometers */
429 input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
430 input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
431 input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
432 input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
433 input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
434 input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
435 input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
436 input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
437
438 /* rotary encoders */
439 input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
440 input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
441 input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
442 input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
443
444 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
445 if (!dev->ep4_in_urb) {
446 ret = -ENOMEM;
447 goto exit_free_idev;
448 }
449
450 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
451 usb_rcvbulkpipe(usb_dev, 0x4),
452 dev->ep4_in_buf, EP4_BUFSIZE,
453 snd_usb_caiaq_ep4_reply_dispatch, dev);
454
455 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
456
457 break;
329 default: 458 default:
330 /* no input methods supported on this device */ 459 /* no input methods supported on this device */
331 input_free_device(input); 460 goto exit_free_idev;
332 return 0;
333 } 461 }
334 462
463 input->open = snd_usb_caiaq_input_open;
464 input->close = snd_usb_caiaq_input_close;
335 input->keycode = dev->keycode; 465 input->keycode = dev->keycode;
336 input->keycodesize = sizeof(unsigned short); 466 input->keycodesize = sizeof(unsigned short);
337 for (i = 0; i < input->keycodemax; i++) 467 for (i = 0; i < input->keycodemax; i++)
338 __set_bit(dev->keycode[i], input->keybit); 468 __set_bit(dev->keycode[i], input->keybit);
339 469
340 ret = input_register_device(input); 470 ret = input_register_device(input);
341 if (ret < 0) { 471 if (ret < 0)
342 input_free_device(input); 472 goto exit_free_idev;
343 return ret;
344 }
345 473
346 dev->input_dev = input; 474 dev->input_dev = input;
347 return 0; 475 return 0;
476
477exit_free_idev:
478 input_free_device(input);
479 return ret;
348} 480}
349 481
350void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) 482void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
@@ -352,6 +484,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
352 if (!dev || !dev->input_dev) 484 if (!dev || !dev->input_dev)
353 return; 485 return;
354 486
487 usb_kill_urb(dev->ep4_in_urb);
488 usb_free_urb(dev->ep4_in_urb);
489 dev->ep4_in_urb = NULL;
490
355 input_unregister_device(dev->input_dev); 491 input_unregister_device(dev->input_dev);
356 dev->input_dev = NULL; 492 dev->input_dev = NULL;
357} 493}