0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 #include <linux/init.h>
0120 #include <linux/module.h>
0121 #include <linux/moduleparam.h>
0122 #include <linux/slab.h>
0123 #include <linux/interrupt.h>
0124 #include <linux/usb.h>
0125 #include <sound/core.h>
0126 #include <sound/initval.h>
0127 #include <sound/pcm.h>
0128
0129 #include <sound/rawmidi.h>
0130 #include "usx2y.h"
0131 #include "usbusx2y.h"
0132 #include "usX2Yhwdep.h"
0133
0134 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
0135 MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
0136 MODULE_LICENSE("GPL");
0137
0138 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0139 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0140 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
0141
0142 module_param_array(index, int, NULL, 0444);
0143 MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
0144 module_param_array(id, charp, NULL, 0444);
0145 MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
0146 module_param_array(enable, bool, NULL, 0444);
0147 MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
0148
0149 static int snd_usx2y_card_used[SNDRV_CARDS];
0150
0151 static void snd_usx2y_card_private_free(struct snd_card *card);
0152 static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s);
0153
0154
0155
0156
0157 static void i_usx2y_out04_int(struct urb *urb)
0158 {
0159 #ifdef CONFIG_SND_DEBUG
0160 if (urb->status) {
0161 int i;
0162 struct usx2ydev *usx2y = urb->context;
0163
0164 for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++)
0165 ;
0166 snd_printdd("%s urb %i status=%i\n", __func__, i, urb->status);
0167 }
0168 #endif
0169 }
0170
0171 static void i_usx2y_in04_int(struct urb *urb)
0172 {
0173 int err = 0;
0174 struct usx2ydev *usx2y = urb->context;
0175 struct us428ctls_sharedmem *us428ctls = usx2y->us428ctls_sharedmem;
0176 struct us428_p4out *p4out;
0177 int i, j, n, diff, send;
0178
0179 usx2y->in04_int_calls++;
0180
0181 if (urb->status) {
0182 snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status);
0183 return;
0184 }
0185
0186
0187 if (us428ctls) {
0188 diff = -1;
0189 if (us428ctls->ctl_snapshot_last == -2) {
0190 diff = 0;
0191 memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
0192 us428ctls->ctl_snapshot_last = -1;
0193 } else {
0194 for (i = 0; i < 21; i++) {
0195 if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {
0196 if (diff < 0)
0197 diff = i;
0198 usx2y->in04_last[i] = ((char *)usx2y->in04_buf)[i];
0199 }
0200 }
0201 }
0202 if (diff >= 0) {
0203 n = us428ctls->ctl_snapshot_last + 1;
0204 if (n >= N_US428_CTL_BUFS || n < 0)
0205 n = 0;
0206 memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0]));
0207 us428ctls->ctl_snapshot_differs_at[n] = diff;
0208 us428ctls->ctl_snapshot_last = n;
0209 wake_up(&usx2y->us428ctls_wait_queue_head);
0210 }
0211 }
0212
0213 if (usx2y->us04) {
0214 if (!usx2y->us04->submitted) {
0215 do {
0216 err = usb_submit_urb(usx2y->us04->urb[usx2y->us04->submitted++], GFP_ATOMIC);
0217 } while (!err && usx2y->us04->submitted < usx2y->us04->len);
0218 }
0219 } else {
0220 if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) {
0221 if (us428ctls->p4out_last != us428ctls->p4out_sent) {
0222 send = us428ctls->p4out_sent + 1;
0223 if (send >= N_US428_P4OUT_BUFS)
0224 send = 0;
0225 for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) {
0226 if (!usx2y->as04.urb[j]->status) {
0227 p4out = us428ctls->p4out + send;
0228 usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev,
0229 usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol,
0230 p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5,
0231 i_usx2y_out04_int, usx2y);
0232 err = usb_submit_urb(usx2y->as04.urb[j], GFP_ATOMIC);
0233 us428ctls->p4out_sent = send;
0234 break;
0235 }
0236 }
0237 }
0238 }
0239 }
0240
0241 if (err)
0242 snd_printk(KERN_ERR "in04_int() usb_submit_urb err=%i\n", err);
0243
0244 urb->dev = usx2y->dev;
0245 usb_submit_urb(urb, GFP_ATOMIC);
0246 }
0247
0248
0249
0250
0251 int usx2y_async_seq04_init(struct usx2ydev *usx2y)
0252 {
0253 int err = 0, i;
0254
0255 if (WARN_ON(usx2y->as04.buffer))
0256 return -EBUSY;
0257
0258 usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ,
0259 URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL);
0260 if (!usx2y->as04.buffer) {
0261 err = -ENOMEM;
0262 } else {
0263 for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
0264 usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL);
0265 if (!usx2y->as04.urb[i]) {
0266 err = -ENOMEM;
0267 break;
0268 }
0269 usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev,
0270 usb_sndbulkpipe(usx2y->dev, 0x04),
0271 usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ * i, 0,
0272 i_usx2y_out04_int, usx2y);
0273 err = usb_urb_ep_type_check(usx2y->as04.urb[i]);
0274 if (err < 0)
0275 break;
0276 }
0277 }
0278 if (err)
0279 usx2y_unlinkseq(&usx2y->as04);
0280 return err;
0281 }
0282
0283 int usx2y_in04_init(struct usx2ydev *usx2y)
0284 {
0285 int err;
0286
0287 if (WARN_ON(usx2y->in04_urb))
0288 return -EBUSY;
0289
0290 usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL);
0291 if (!usx2y->in04_urb) {
0292 err = -ENOMEM;
0293 goto error;
0294 }
0295
0296 usx2y->in04_buf = kmalloc(21, GFP_KERNEL);
0297 if (!usx2y->in04_buf) {
0298 err = -ENOMEM;
0299 goto error;
0300 }
0301
0302 init_waitqueue_head(&usx2y->in04_wait_queue);
0303 usb_fill_int_urb(usx2y->in04_urb, usx2y->dev, usb_rcvintpipe(usx2y->dev, 0x4),
0304 usx2y->in04_buf, 21,
0305 i_usx2y_in04_int, usx2y,
0306 10);
0307 if (usb_urb_ep_type_check(usx2y->in04_urb)) {
0308 err = -EINVAL;
0309 goto error;
0310 }
0311 return usb_submit_urb(usx2y->in04_urb, GFP_KERNEL);
0312
0313 error:
0314 kfree(usx2y->in04_buf);
0315 usb_free_urb(usx2y->in04_urb);
0316 usx2y->in04_buf = NULL;
0317 usx2y->in04_urb = NULL;
0318 return err;
0319 }
0320
0321 static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s)
0322 {
0323 int i;
0324
0325 for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
0326 if (!s->urb[i])
0327 continue;
0328 usb_kill_urb(s->urb[i]);
0329 usb_free_urb(s->urb[i]);
0330 s->urb[i] = NULL;
0331 }
0332 kfree(s->buffer);
0333 s->buffer = NULL;
0334 }
0335
0336 static const struct usb_device_id snd_usx2y_usb_id_table[] = {
0337 {
0338 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
0339 .idVendor = 0x1604,
0340 .idProduct = USB_ID_US428
0341 },
0342 {
0343 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
0344 .idVendor = 0x1604,
0345 .idProduct = USB_ID_US122
0346 },
0347 {
0348 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
0349 .idVendor = 0x1604,
0350 .idProduct = USB_ID_US224
0351 },
0352 { }
0353 };
0354 MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table);
0355
0356 static int usx2y_create_card(struct usb_device *device,
0357 struct usb_interface *intf,
0358 struct snd_card **cardp)
0359 {
0360 int dev;
0361 struct snd_card *card;
0362 int err;
0363
0364 for (dev = 0; dev < SNDRV_CARDS; ++dev)
0365 if (enable[dev] && !snd_usx2y_card_used[dev])
0366 break;
0367 if (dev >= SNDRV_CARDS)
0368 return -ENODEV;
0369 err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
0370 sizeof(struct usx2ydev), &card);
0371 if (err < 0)
0372 return err;
0373 snd_usx2y_card_used[usx2y(card)->card_index = dev] = 1;
0374 card->private_free = snd_usx2y_card_private_free;
0375 usx2y(card)->dev = device;
0376 init_waitqueue_head(&usx2y(card)->prepare_wait_queue);
0377 init_waitqueue_head(&usx2y(card)->us428ctls_wait_queue_head);
0378 mutex_init(&usx2y(card)->pcm_mutex);
0379 INIT_LIST_HEAD(&usx2y(card)->midi_list);
0380 strcpy(card->driver, "USB "NAME_ALLCAPS"");
0381 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
0382 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
0383 card->shortname,
0384 le16_to_cpu(device->descriptor.idVendor),
0385 le16_to_cpu(device->descriptor.idProduct),
0386 0,
0387 usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum);
0388 *cardp = card;
0389 return 0;
0390 }
0391
0392 static void snd_usx2y_card_private_free(struct snd_card *card)
0393 {
0394 struct usx2ydev *usx2y = usx2y(card);
0395
0396 kfree(usx2y->in04_buf);
0397 usb_free_urb(usx2y->in04_urb);
0398 if (usx2y->us428ctls_sharedmem)
0399 free_pages_exact(usx2y->us428ctls_sharedmem,
0400 US428_SHAREDMEM_PAGES);
0401 if (usx2y->card_index >= 0 && usx2y->card_index < SNDRV_CARDS)
0402 snd_usx2y_card_used[usx2y->card_index] = 0;
0403 }
0404
0405 static void snd_usx2y_disconnect(struct usb_interface *intf)
0406 {
0407 struct snd_card *card;
0408 struct usx2ydev *usx2y;
0409 struct list_head *p;
0410
0411 card = usb_get_intfdata(intf);
0412 if (!card)
0413 return;
0414 usx2y = usx2y(card);
0415 usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
0416 usx2y_unlinkseq(&usx2y->as04);
0417 usb_kill_urb(usx2y->in04_urb);
0418 snd_card_disconnect(card);
0419
0420
0421 list_for_each(p, &usx2y->midi_list) {
0422 snd_usbmidi_disconnect(p);
0423 }
0424 if (usx2y->us428ctls_sharedmem)
0425 wake_up(&usx2y->us428ctls_wait_queue_head);
0426 snd_card_free(card);
0427 }
0428
0429 static int snd_usx2y_probe(struct usb_interface *intf,
0430 const struct usb_device_id *id)
0431 {
0432 struct usb_device *device = interface_to_usbdev(intf);
0433 struct snd_card *card;
0434 int err;
0435
0436 if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
0437 (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
0438 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
0439 le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
0440 return -EINVAL;
0441
0442 err = usx2y_create_card(device, intf, &card);
0443 if (err < 0)
0444 return err;
0445 err = usx2y_hwdep_new(card, device);
0446 if (err < 0)
0447 goto error;
0448 err = snd_card_register(card);
0449 if (err < 0)
0450 goto error;
0451
0452 dev_set_drvdata(&intf->dev, card);
0453 return 0;
0454
0455 error:
0456 snd_card_free(card);
0457 return err;
0458 }
0459
0460 static struct usb_driver snd_usx2y_usb_driver = {
0461 .name = "snd-usb-usx2y",
0462 .probe = snd_usx2y_probe,
0463 .disconnect = snd_usx2y_disconnect,
0464 .id_table = snd_usx2y_usb_id_table,
0465 };
0466 module_usb_driver(snd_usx2y_usb_driver);