Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/usb/caiaq/device.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* caiaq.c: ALSA driver for caiaq/NativeInstruments devices
4
*
5
* Copyright (c) 2007 Daniel Mack <[email protected]>
6
* Karsten Wiese <[email protected]>
7
*/
8
9
#include <linux/moduleparam.h>
10
#include <linux/device.h>
11
#include <linux/interrupt.h>
12
#include <linux/module.h>
13
#include <linux/init.h>
14
#include <linux/gfp.h>
15
#include <linux/usb.h>
16
#include <sound/initval.h>
17
#include <sound/core.h>
18
#include <sound/pcm.h>
19
20
#include "device.h"
21
#include "audio.h"
22
#include "midi.h"
23
#include "control.h"
24
#include "input.h"
25
26
MODULE_AUTHOR("Daniel Mack <[email protected]>");
27
MODULE_DESCRIPTION("caiaq USB audio");
28
MODULE_LICENSE("GPL");
29
30
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
31
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
32
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
33
34
module_param_array(index, int, NULL, 0444);
35
MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
36
module_param_array(id, charp, NULL, 0444);
37
MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
38
module_param_array(enable, bool, NULL, 0444);
39
MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
40
41
enum {
42
SAMPLERATE_44100 = 0,
43
SAMPLERATE_48000 = 1,
44
SAMPLERATE_96000 = 2,
45
SAMPLERATE_192000 = 3,
46
SAMPLERATE_88200 = 4,
47
SAMPLERATE_INVALID = 0xff
48
};
49
50
enum {
51
DEPTH_NONE = 0,
52
DEPTH_16 = 1,
53
DEPTH_24 = 2,
54
DEPTH_32 = 3
55
};
56
57
static const struct usb_device_id snd_usb_id_table[] = {
58
{
59
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
60
.idVendor = USB_VID_NATIVEINSTRUMENTS,
61
.idProduct = USB_PID_RIGKONTROL2
62
},
63
{
64
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
65
.idVendor = USB_VID_NATIVEINSTRUMENTS,
66
.idProduct = USB_PID_RIGKONTROL3
67
},
68
{
69
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
70
.idVendor = USB_VID_NATIVEINSTRUMENTS,
71
.idProduct = USB_PID_KORECONTROLLER
72
},
73
{
74
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
75
.idVendor = USB_VID_NATIVEINSTRUMENTS,
76
.idProduct = USB_PID_KORECONTROLLER2
77
},
78
{
79
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
80
.idVendor = USB_VID_NATIVEINSTRUMENTS,
81
.idProduct = USB_PID_AK1
82
},
83
{
84
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
85
.idVendor = USB_VID_NATIVEINSTRUMENTS,
86
.idProduct = USB_PID_AUDIO8DJ
87
},
88
{
89
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
90
.idVendor = USB_VID_NATIVEINSTRUMENTS,
91
.idProduct = USB_PID_SESSIONIO
92
},
93
{
94
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
95
.idVendor = USB_VID_NATIVEINSTRUMENTS,
96
.idProduct = USB_PID_GUITARRIGMOBILE
97
},
98
{
99
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
100
.idVendor = USB_VID_NATIVEINSTRUMENTS,
101
.idProduct = USB_PID_AUDIO4DJ
102
},
103
{
104
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
105
.idVendor = USB_VID_NATIVEINSTRUMENTS,
106
.idProduct = USB_PID_AUDIO2DJ
107
},
108
{
109
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
110
.idVendor = USB_VID_NATIVEINSTRUMENTS,
111
.idProduct = USB_PID_TRAKTORKONTROLX1
112
},
113
{
114
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
115
.idVendor = USB_VID_NATIVEINSTRUMENTS,
116
.idProduct = USB_PID_TRAKTORKONTROLS4
117
},
118
{
119
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
120
.idVendor = USB_VID_NATIVEINSTRUMENTS,
121
.idProduct = USB_PID_TRAKTORAUDIO2
122
},
123
{
124
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
125
.idVendor = USB_VID_NATIVEINSTRUMENTS,
126
.idProduct = USB_PID_MASCHINECONTROLLER
127
},
128
{ /* terminator */ }
129
};
130
131
static void usb_ep1_command_reply_dispatch (struct urb* urb)
132
{
133
int ret;
134
struct device *dev = &urb->dev->dev;
135
struct snd_usb_caiaqdev *cdev = urb->context;
136
unsigned char *buf = urb->transfer_buffer;
137
138
if (urb->status || !cdev) {
139
dev_warn(dev, "received EP1 urb->status = %i\n", urb->status);
140
return;
141
}
142
143
switch(buf[0]) {
144
case EP1_CMD_GET_DEVICE_INFO:
145
memcpy(&cdev->spec, buf+1, sizeof(struct caiaq_device_spec));
146
cdev->spec.fw_version = le16_to_cpu(cdev->spec.fw_version);
147
dev_dbg(dev, "device spec (firmware %d): audio: %d in, %d out, "
148
"MIDI: %d in, %d out, data alignment %d\n",
149
cdev->spec.fw_version,
150
cdev->spec.num_analog_audio_in,
151
cdev->spec.num_analog_audio_out,
152
cdev->spec.num_midi_in,
153
cdev->spec.num_midi_out,
154
cdev->spec.data_alignment);
155
156
cdev->spec_received++;
157
wake_up(&cdev->ep1_wait_queue);
158
break;
159
case EP1_CMD_AUDIO_PARAMS:
160
cdev->audio_parm_answer = buf[1];
161
wake_up(&cdev->ep1_wait_queue);
162
break;
163
case EP1_CMD_MIDI_READ:
164
snd_usb_caiaq_midi_handle_input(cdev, buf[1], buf + 3, buf[2]);
165
break;
166
case EP1_CMD_READ_IO:
167
if (cdev->chip.usb_id ==
168
USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) {
169
if (urb->actual_length > sizeof(cdev->control_state))
170
urb->actual_length = sizeof(cdev->control_state);
171
memcpy(cdev->control_state, buf + 1, urb->actual_length);
172
wake_up(&cdev->ep1_wait_queue);
173
break;
174
}
175
#ifdef CONFIG_SND_USB_CAIAQ_INPUT
176
fallthrough;
177
case EP1_CMD_READ_ERP:
178
case EP1_CMD_READ_ANALOG:
179
snd_usb_caiaq_input_dispatch(cdev, buf, urb->actual_length);
180
#endif
181
break;
182
}
183
184
cdev->ep1_in_urb.actual_length = 0;
185
ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC);
186
if (ret < 0)
187
dev_err(dev, "unable to submit urb. OOM!?\n");
188
}
189
190
int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev,
191
unsigned char command,
192
const unsigned char *buffer,
193
int len)
194
{
195
int actual_len;
196
struct usb_device *usb_dev = cdev->chip.dev;
197
198
if (!usb_dev)
199
return -EIO;
200
201
if (len > EP1_BUFSIZE - 1)
202
len = EP1_BUFSIZE - 1;
203
204
if (buffer && len > 0)
205
memcpy(cdev->ep1_out_buf+1, buffer, len);
206
207
cdev->ep1_out_buf[0] = command;
208
return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
209
cdev->ep1_out_buf, len+1, &actual_len, 200);
210
}
211
212
int snd_usb_caiaq_send_command_bank(struct snd_usb_caiaqdev *cdev,
213
unsigned char command,
214
unsigned char bank,
215
const unsigned char *buffer,
216
int len)
217
{
218
int actual_len;
219
struct usb_device *usb_dev = cdev->chip.dev;
220
221
if (!usb_dev)
222
return -EIO;
223
224
if (len > EP1_BUFSIZE - 2)
225
len = EP1_BUFSIZE - 2;
226
227
if (buffer && len > 0)
228
memcpy(cdev->ep1_out_buf+2, buffer, len);
229
230
cdev->ep1_out_buf[0] = command;
231
cdev->ep1_out_buf[1] = bank;
232
233
return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
234
cdev->ep1_out_buf, len+2, &actual_len, 200);
235
}
236
237
int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev,
238
int rate, int depth, int bpp)
239
{
240
int ret;
241
char tmp[5];
242
struct device *dev = caiaqdev_to_dev(cdev);
243
244
switch (rate) {
245
case 44100: tmp[0] = SAMPLERATE_44100; break;
246
case 48000: tmp[0] = SAMPLERATE_48000; break;
247
case 88200: tmp[0] = SAMPLERATE_88200; break;
248
case 96000: tmp[0] = SAMPLERATE_96000; break;
249
case 192000: tmp[0] = SAMPLERATE_192000; break;
250
default: return -EINVAL;
251
}
252
253
switch (depth) {
254
case 16: tmp[1] = DEPTH_16; break;
255
case 24: tmp[1] = DEPTH_24; break;
256
default: return -EINVAL;
257
}
258
259
tmp[2] = bpp & 0xff;
260
tmp[3] = bpp >> 8;
261
tmp[4] = 1; /* packets per microframe */
262
263
dev_dbg(dev, "setting audio params: %d Hz, %d bits, %d bpp\n",
264
rate, depth, bpp);
265
266
cdev->audio_parm_answer = -1;
267
ret = snd_usb_caiaq_send_command(cdev, EP1_CMD_AUDIO_PARAMS,
268
tmp, sizeof(tmp));
269
270
if (ret)
271
return ret;
272
273
if (!wait_event_timeout(cdev->ep1_wait_queue,
274
cdev->audio_parm_answer >= 0, HZ))
275
return -EPIPE;
276
277
if (cdev->audio_parm_answer != 1)
278
dev_dbg(dev, "unable to set the device's audio params\n");
279
else
280
cdev->bpp = bpp;
281
282
return cdev->audio_parm_answer == 1 ? 0 : -EINVAL;
283
}
284
285
int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev,
286
int digital, int analog, int erp)
287
{
288
char tmp[3] = { digital, analog, erp };
289
return snd_usb_caiaq_send_command(cdev, EP1_CMD_AUTO_MSG,
290
tmp, sizeof(tmp));
291
}
292
293
static void setup_card(struct snd_usb_caiaqdev *cdev)
294
{
295
int ret;
296
char val[4];
297
struct device *dev = caiaqdev_to_dev(cdev);
298
299
/* device-specific startup specials */
300
switch (cdev->chip.usb_id) {
301
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
302
/* RigKontrol2 - display centered dash ('-') */
303
val[0] = 0x00;
304
val[1] = 0x00;
305
val[2] = 0x01;
306
snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 3);
307
break;
308
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
309
/* RigKontrol2 - display two centered dashes ('--') */
310
val[0] = 0x00;
311
val[1] = 0x40;
312
val[2] = 0x40;
313
val[3] = 0x00;
314
snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 4);
315
break;
316
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
317
/* Audio Kontrol 1 - make USB-LED stop blinking */
318
val[0] = 0x00;
319
snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 1);
320
break;
321
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
322
/* Audio 8 DJ - trigger read of current settings */
323
cdev->control_state[0] = 0xff;
324
snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 0);
325
snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0);
326
327
if (!wait_event_timeout(cdev->ep1_wait_queue,
328
cdev->control_state[0] != 0xff, HZ))
329
return;
330
331
/* fix up some defaults */
332
if ((cdev->control_state[1] != 2) ||
333
(cdev->control_state[2] != 3) ||
334
(cdev->control_state[4] != 2)) {
335
cdev->control_state[1] = 2;
336
cdev->control_state[2] = 3;
337
cdev->control_state[4] = 2;
338
snd_usb_caiaq_send_command(cdev,
339
EP1_CMD_WRITE_IO, cdev->control_state, 6);
340
}
341
342
break;
343
}
344
345
if (cdev->spec.num_analog_audio_out +
346
cdev->spec.num_analog_audio_in +
347
cdev->spec.num_digital_audio_out +
348
cdev->spec.num_digital_audio_in > 0) {
349
ret = snd_usb_caiaq_audio_init(cdev);
350
if (ret < 0)
351
dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret);
352
}
353
354
if (cdev->spec.num_midi_in +
355
cdev->spec.num_midi_out > 0) {
356
ret = snd_usb_caiaq_midi_init(cdev);
357
if (ret < 0)
358
dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret);
359
}
360
361
#ifdef CONFIG_SND_USB_CAIAQ_INPUT
362
ret = snd_usb_caiaq_input_init(cdev);
363
if (ret < 0)
364
dev_err(dev, "Unable to set up input system (ret=%d)\n", ret);
365
#endif
366
367
/* finally, register the card and all its sub-instances */
368
ret = snd_card_register(cdev->chip.card);
369
if (ret < 0) {
370
dev_err(dev, "snd_card_register() returned %d\n", ret);
371
snd_card_free(cdev->chip.card);
372
}
373
374
ret = snd_usb_caiaq_control_init(cdev);
375
if (ret < 0)
376
dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
377
}
378
379
static void card_free(struct snd_card *card)
380
{
381
struct snd_usb_caiaqdev *cdev = caiaqdev(card);
382
383
#ifdef CONFIG_SND_USB_CAIAQ_INPUT
384
snd_usb_caiaq_input_free(cdev);
385
#endif
386
snd_usb_caiaq_audio_free(cdev);
387
usb_reset_device(cdev->chip.dev);
388
}
389
390
static int create_card(struct usb_device *usb_dev,
391
struct usb_interface *intf,
392
struct snd_card **cardp)
393
{
394
int devnum;
395
int err;
396
struct snd_card *card;
397
struct snd_usb_caiaqdev *cdev;
398
399
for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
400
if (enable[devnum])
401
break;
402
403
if (devnum >= SNDRV_CARDS)
404
return -ENODEV;
405
406
err = snd_card_new(&intf->dev,
407
index[devnum], id[devnum], THIS_MODULE,
408
sizeof(struct snd_usb_caiaqdev), &card);
409
if (err < 0)
410
return err;
411
412
cdev = caiaqdev(card);
413
cdev->chip.dev = usb_dev;
414
cdev->chip.card = card;
415
cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
416
le16_to_cpu(usb_dev->descriptor.idProduct));
417
spin_lock_init(&cdev->spinlock);
418
419
*cardp = card;
420
return 0;
421
}
422
423
static int init_card(struct snd_usb_caiaqdev *cdev)
424
{
425
char *c, usbpath[32];
426
struct usb_device *usb_dev = cdev->chip.dev;
427
struct snd_card *card = cdev->chip.card;
428
struct device *dev = caiaqdev_to_dev(cdev);
429
int err, len;
430
431
if (usb_set_interface(usb_dev, 0, 1) != 0) {
432
dev_err(dev, "can't set alt interface.\n");
433
return -EIO;
434
}
435
436
usb_init_urb(&cdev->ep1_in_urb);
437
usb_init_urb(&cdev->midi_out_urb);
438
439
usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev,
440
usb_rcvbulkpipe(usb_dev, 0x1),
441
cdev->ep1_in_buf, EP1_BUFSIZE,
442
usb_ep1_command_reply_dispatch, cdev);
443
444
usb_fill_bulk_urb(&cdev->midi_out_urb, usb_dev,
445
usb_sndbulkpipe(usb_dev, 0x1),
446
cdev->midi_out_buf, EP1_BUFSIZE,
447
snd_usb_caiaq_midi_output_done, cdev);
448
449
/* sanity checks of EPs before actually submitting */
450
if (usb_urb_ep_type_check(&cdev->ep1_in_urb) ||
451
usb_urb_ep_type_check(&cdev->midi_out_urb)) {
452
dev_err(dev, "invalid EPs\n");
453
return -EINVAL;
454
}
455
456
init_waitqueue_head(&cdev->ep1_wait_queue);
457
init_waitqueue_head(&cdev->prepare_wait_queue);
458
459
if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0)
460
return -EIO;
461
462
err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
463
if (err)
464
goto err_kill_urb;
465
466
if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) {
467
err = -ENODEV;
468
goto err_kill_urb;
469
}
470
471
usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
472
cdev->vendor_name, CAIAQ_USB_STR_LEN);
473
474
usb_string(usb_dev, usb_dev->descriptor.iProduct,
475
cdev->product_name, CAIAQ_USB_STR_LEN);
476
477
strscpy(card->driver, MODNAME, sizeof(card->driver));
478
strscpy(card->shortname, cdev->product_name, sizeof(card->shortname));
479
strscpy(card->mixername, cdev->product_name, sizeof(card->mixername));
480
481
/* if the id was not passed as module option, fill it with a shortened
482
* version of the product string which does not contain any
483
* whitespaces */
484
485
if (*card->id == '\0') {
486
char id[sizeof(card->id)];
487
488
memset(id, 0, sizeof(id));
489
490
for (c = card->shortname, len = 0;
491
*c && len < sizeof(card->id); c++)
492
if (*c != ' ')
493
id[len++] = *c;
494
495
snd_card_set_id(card, id);
496
}
497
498
usb_make_path(usb_dev, usbpath, sizeof(usbpath));
499
scnprintf(card->longname, sizeof(card->longname), "%s %s (%s)",
500
cdev->vendor_name, cdev->product_name, usbpath);
501
502
setup_card(cdev);
503
card->private_free = card_free;
504
return 0;
505
506
err_kill_urb:
507
usb_kill_urb(&cdev->ep1_in_urb);
508
return err;
509
}
510
511
static int snd_probe(struct usb_interface *intf,
512
const struct usb_device_id *id)
513
{
514
int ret;
515
struct snd_card *card = NULL;
516
struct usb_device *usb_dev = interface_to_usbdev(intf);
517
518
ret = create_card(usb_dev, intf, &card);
519
520
if (ret < 0)
521
return ret;
522
523
usb_set_intfdata(intf, card);
524
ret = init_card(caiaqdev(card));
525
if (ret < 0) {
526
dev_err(&usb_dev->dev, "unable to init card! (ret=%d)\n", ret);
527
snd_card_free(card);
528
return ret;
529
}
530
531
return 0;
532
}
533
534
static void snd_disconnect(struct usb_interface *intf)
535
{
536
struct snd_card *card = usb_get_intfdata(intf);
537
struct device *dev = intf->usb_dev;
538
struct snd_usb_caiaqdev *cdev;
539
540
if (!card)
541
return;
542
543
cdev = caiaqdev(card);
544
dev_dbg(dev, "%s(%p)\n", __func__, intf);
545
546
snd_card_disconnect(card);
547
548
#ifdef CONFIG_SND_USB_CAIAQ_INPUT
549
snd_usb_caiaq_input_disconnect(cdev);
550
#endif
551
snd_usb_caiaq_audio_disconnect(cdev);
552
553
usb_kill_urb(&cdev->ep1_in_urb);
554
usb_kill_urb(&cdev->midi_out_urb);
555
556
snd_card_free_when_closed(card);
557
}
558
559
560
MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
561
static struct usb_driver snd_usb_driver = {
562
.name = MODNAME,
563
.probe = snd_probe,
564
.disconnect = snd_disconnect,
565
.id_table = snd_usb_id_table,
566
};
567
568
module_usb_driver(snd_usb_driver);
569
570