1/* 2 comedi/drivers/usbdux.c 3 Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 */ 15/* 16Driver: usbdux 17Description: University of Stirling USB DAQ & INCITE Technology Limited 18Devices: [ITL] USB-DUX (usbdux.o) 19Author: Bernd Porr <BerndPorr@f2s.com> 20Updated: 8 Dec 2008 21Status: Stable 22Configuration options: 23 You have to upload firmware with the -i option. The 24 firmware is usually installed under /usr/share/usb or 25 /usr/local/share/usb or /lib/firmware. 26 27Connection scheme for the counter at the digital port: 28 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1. 29 The sampling rate of the counter is approximately 500Hz. 30 31Please note that under USB2.0 the length of the channel list determines 32the max sampling rate. If you sample only one channel you get 8kHz 33sampling rate. If you sample two channels you get 4kHz and so on. 34*/ 35/* 36 * I must give credit here to Chris Baugher who 37 * wrote the driver for AT-MIO-16d. I used some parts of this 38 * driver. I also must give credits to David Brownell 39 * who supported me with the USB development. 40 * 41 * Bernd Porr 42 * 43 * 44 * Revision history: 45 * 0.94: D/A output should work now with any channel list combinations 46 * 0.95: .owner commented out for kernel vers below 2.4.19 47 * sanity checks in ai/ao_cmd 48 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's 49 * attach final USB IDs 50 * moved memory allocation completely to the corresponding comedi 51 * functions firmware upload is by fxload and no longer by comedi (due to 52 * enumeration) 53 * 0.97: USB IDs received, adjusted table 54 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc 55 * to the usb subsystem and moved all comedi related memory 56 * alloc to comedi. 57 * | kernel | registration | usbdux-usb | usbdux-comedi | comedi | 58 * 0.99: USB 2.0: changed protocol to isochronous transfer 59 * IRQ transfer is too buggy and too risky in 2.0 60 * for the high speed ISO transfer is now a working version 61 * available 62 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA 63 * chipsets miss out IRQs. Deeper buffering is needed. 64 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling 65 * rate. 66 * Firmware vers 1.00 is needed for this. 67 * Two 16 bit up/down/reset counter with a sampling rate of 1kHz 68 * And loads of cleaning up, in particular streamlining the 69 * bulk transfers. 70 * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4 71 * 1.2: added PWM support via EP4 72 * 2.0: PWM seems to be stable and is not interfering with the other functions 73 * 2.1: changed PWM API 74 * 2.2: added firmware kernel request to fix an udev problem 75 * 2.3: corrected a bug in bulk timeouts which were far too short 76 * 2.4: fixed a bug which causes the driver to hang when it ran out of data. 77 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it. 78 * 79 */ 80 81#include <linux/kernel.h> 82#include <linux/module.h> 83#include <linux/slab.h> 84#include <linux/input.h> 85#include <linux/usb.h> 86#include <linux/fcntl.h> 87#include <linux/compiler.h> 88 89#include "../comedidev.h" 90 91#include "comedi_fc.h" 92 93/* constants for firmware upload and download */ 94#define USBDUX_FIRMWARE "usbdux_firmware.bin" 95#define USBDUX_FIRMWARE_MAX_LEN 0x2000 96#define USBDUX_FIRMWARE_CMD 0xa0 97#define VENDOR_DIR_IN 0xc0 98#define VENDOR_DIR_OUT 0x40 99#define USBDUX_CPU_CS 0xe600 100 101/* usbdux bulk transfer commands */ 102#define USBDUX_CMD_MULT_AI 0 103#define USBDUX_CMD_AO 1 104#define USBDUX_CMD_DIO_CFG 2 105#define USBDUX_CMD_DIO_BITS 3 106#define USBDUX_CMD_SINGLE_AI 4 107#define USBDUX_CMD_TIMER_RD 5 108#define USBDUX_CMD_TIMER_WR 6 109#define USBDUX_CMD_PWM_ON 7 110#define USBDUX_CMD_PWM_OFF 8 111 112/* timeout for the USB-transfer in ms */ 113#define BULK_TIMEOUT 1000 114 115/* 300Hz max frequ under PWM */ 116#define MIN_PWM_PERIOD ((long)(1E9/300)) 117 118/* Default PWM frequency */ 119#define PWM_DEFAULT_PERIOD ((long)(1E9/100)) 120 121/* Size of one A/D value */ 122#define SIZEADIN ((sizeof(uint16_t))) 123 124/* 125 * Size of the input-buffer IN BYTES 126 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode 127 */ 128#define SIZEINBUF ((8*SIZEADIN)) 129 130/* 16 bytes. */ 131#define SIZEINSNBUF 16 132 133/* size of one value for the D/A converter: channel and value */ 134#define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t))) 135 136/* 137 * Size of the output-buffer in bytes 138 * Actually only the first 4 triplets are used but for the 139 * high speed mode we need to pad it to 8 (microframes). 140 */ 141#define SIZEOUTBUF ((8*SIZEDAOUT)) 142 143/* 144 * Size of the buffer for the dux commands: just now max size is determined 145 * by the analogue out + command byte + panic bytes... 146 */ 147#define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2)) 148 149/* Number of in-URBs which receive the data: min=2 */ 150#define NUMOFINBUFFERSFULL 5 151 152/* Number of out-URBs which send the data: min=2 */ 153#define NUMOFOUTBUFFERSFULL 5 154 155/* Number of in-URBs which receive the data: min=5 */ 156/* must have more buffers due to buggy USB ctr */ 157#define NUMOFINBUFFERSHIGH 10 158 159/* Number of out-URBs which send the data: min=5 */ 160/* must have more buffers due to buggy USB ctr */ 161#define NUMOFOUTBUFFERSHIGH 10 162 163/* number of retries to get the right dux command */ 164#define RETRIES 10 165 166static const struct comedi_lrange range_usbdux_ai_range = { 167 4, { 168 BIP_RANGE(4.096), 169 BIP_RANGE(4.096 / 2), 170 UNI_RANGE(4.096), 171 UNI_RANGE(4.096 / 2) 172 } 173}; 174 175static const struct comedi_lrange range_usbdux_ao_range = { 176 2, { 177 BIP_RANGE(4.096), 178 UNI_RANGE(4.096) 179 } 180}; 181 182struct usbdux_private { 183 /* actual number of in-buffers */ 184 int n_ai_urbs; 185 /* actual number of out-buffers */ 186 int n_ao_urbs; 187 /* ISO-transfer handling: buffers */ 188 struct urb **ai_urbs; 189 struct urb **ao_urbs; 190 /* pwm-transfer handling */ 191 struct urb *pwm_urb; 192 /* PWM period */ 193 unsigned int pwm_period; 194 /* PWM internal delay for the GPIF in the FX2 */ 195 uint8_t pwm_delay; 196 /* size of the PWM buffer which holds the bit pattern */ 197 int pwm_buf_sz; 198 /* input buffer for the ISO-transfer */ 199 __le16 *in_buf; 200 /* input buffer for single insn */ 201 __le16 *insn_buf; 202 203 unsigned int high_speed:1; 204 unsigned int ai_cmd_running:1; 205 unsigned int ao_cmd_running:1; 206 unsigned int pwm_cmd_running:1; 207 208 /* number of samples to acquire */ 209 int ai_sample_count; 210 int ao_sample_count; 211 /* time between samples in units of the timer */ 212 unsigned int ai_timer; 213 unsigned int ao_timer; 214 /* counter between aquisitions */ 215 unsigned int ai_counter; 216 unsigned int ao_counter; 217 /* interval in frames/uframes */ 218 unsigned int ai_interval; 219 /* commands */ 220 uint8_t *dux_commands; 221 struct semaphore sem; 222}; 223 224static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs) 225{ 226 int i; 227 228 for (i = 0; i < num_urbs; i++) 229 usb_kill_urb(urbs[i]); 230} 231 232static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink) 233{ 234 struct usbdux_private *devpriv = dev->private; 235 236 if (do_unlink && devpriv->ai_urbs) 237 usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs); 238 239 devpriv->ai_cmd_running = 0; 240} 241 242static int usbdux_ai_cancel(struct comedi_device *dev, 243 struct comedi_subdevice *s) 244{ 245 struct usbdux_private *devpriv = dev->private; 246 247 /* prevent other CPUs from submitting new commands just now */ 248 down(&devpriv->sem); 249 /* unlink only if the urb really has been submitted */ 250 usbdux_ai_stop(dev, devpriv->ai_cmd_running); 251 up(&devpriv->sem); 252 253 return 0; 254} 255 256/* analogue IN - interrupt service routine */ 257static void usbduxsub_ai_isoc_irq(struct urb *urb) 258{ 259 struct comedi_device *dev = urb->context; 260 struct comedi_subdevice *s = dev->read_subdev; 261 struct usbdux_private *devpriv = dev->private; 262 struct comedi_cmd *cmd = &s->async->cmd; 263 int i, err; 264 265 /* first we test if something unusual has just happened */ 266 switch (urb->status) { 267 case 0: 268 /* copy the result in the transfer buffer */ 269 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); 270 break; 271 case -EILSEQ: 272 /* error in the ISOchronous data */ 273 /* we don't copy the data into the transfer buffer */ 274 /* and recycle the last data byte */ 275 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); 276 break; 277 278 case -ECONNRESET: 279 case -ENOENT: 280 case -ESHUTDOWN: 281 case -ECONNABORTED: 282 /* happens after an unlink command */ 283 if (devpriv->ai_cmd_running) { 284 s->async->events |= COMEDI_CB_EOA; 285 s->async->events |= COMEDI_CB_ERROR; 286 comedi_event(dev, s); 287 /* stop the transfer w/o unlink */ 288 usbdux_ai_stop(dev, 0); 289 } 290 return; 291 292 default: 293 /* a real error on the bus */ 294 /* pass error to comedi if we are really running a command */ 295 if (devpriv->ai_cmd_running) { 296 dev_err(dev->class_dev, 297 "Non-zero urb status received in ai intr context: %d\n", 298 urb->status); 299 s->async->events |= COMEDI_CB_EOA; 300 s->async->events |= COMEDI_CB_ERROR; 301 comedi_event(dev, s); 302 /* don't do an unlink here */ 303 usbdux_ai_stop(dev, 0); 304 } 305 return; 306 } 307 308 /* 309 * at this point we are reasonably sure that nothing dodgy has happened 310 * are we running a command? 311 */ 312 if (unlikely(!devpriv->ai_cmd_running)) { 313 /* 314 * not running a command, do not continue execution if no 315 * asynchronous command is running in particular not resubmit 316 */ 317 return; 318 } 319 320 urb->dev = comedi_to_usb_dev(dev); 321 322 /* resubmit the urb */ 323 err = usb_submit_urb(urb, GFP_ATOMIC); 324 if (unlikely(err < 0)) { 325 dev_err(dev->class_dev, 326 "urb resubmit failed in int-context! err=%d\n", err); 327 if (err == -EL2NSYNC) 328 dev_err(dev->class_dev, 329 "buggy USB host controller or bug in IRQ handler!\n"); 330 s->async->events |= COMEDI_CB_EOA; 331 s->async->events |= COMEDI_CB_ERROR; 332 comedi_event(dev, s); 333 /* don't do an unlink here */ 334 usbdux_ai_stop(dev, 0); 335 return; 336 } 337 338 devpriv->ai_counter--; 339 if (likely(devpriv->ai_counter > 0)) 340 return; 341 342 /* timer zero, transfer measurements to comedi */ 343 devpriv->ai_counter = devpriv->ai_timer; 344 345 /* test, if we transmit only a fixed number of samples */ 346 if (cmd->stop_src == TRIG_COUNT) { 347 /* not continuous, fixed number of samples */ 348 devpriv->ai_sample_count--; 349 /* all samples received? */ 350 if (devpriv->ai_sample_count < 0) { 351 /* prevent a resubmit next time */ 352 usbdux_ai_stop(dev, 0); 353 /* say comedi that the acquistion is over */ 354 s->async->events |= COMEDI_CB_EOA; 355 comedi_event(dev, s); 356 return; 357 } 358 } 359 /* get the data from the USB bus and hand it over to comedi */ 360 for (i = 0; i < cmd->chanlist_len; i++) { 361 unsigned int range = CR_RANGE(cmd->chanlist[i]); 362 uint16_t val = le16_to_cpu(devpriv->in_buf[i]); 363 364 /* bipolar data is two's-complement */ 365 if (comedi_range_is_bipolar(s, range)) 366 val ^= ((s->maxdata + 1) >> 1); 367 368 /* transfer data */ 369 err = comedi_buf_put(s, val); 370 if (unlikely(err == 0)) { 371 /* buffer overflow */ 372 usbdux_ai_stop(dev, 0); 373 return; 374 } 375 } 376 /* tell comedi that data is there */ 377 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 378 comedi_event(dev, s); 379} 380 381static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink) 382{ 383 struct usbdux_private *devpriv = dev->private; 384 385 if (do_unlink && devpriv->ao_urbs) 386 usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs); 387 388 devpriv->ao_cmd_running = 0; 389} 390 391static int usbdux_ao_cancel(struct comedi_device *dev, 392 struct comedi_subdevice *s) 393{ 394 struct usbdux_private *devpriv = dev->private; 395 396 /* prevent other CPUs from submitting a command just now */ 397 down(&devpriv->sem); 398 /* unlink only if it is really running */ 399 usbdux_ao_stop(dev, devpriv->ao_cmd_running); 400 up(&devpriv->sem); 401 402 return 0; 403} 404 405static void usbduxsub_ao_isoc_irq(struct urb *urb) 406{ 407 struct comedi_device *dev = urb->context; 408 struct comedi_subdevice *s = dev->write_subdev; 409 struct usbdux_private *devpriv = dev->private; 410 struct comedi_cmd *cmd = &s->async->cmd; 411 uint8_t *datap; 412 int ret; 413 int i; 414 415 switch (urb->status) { 416 case 0: 417 /* success */ 418 break; 419 420 case -ECONNRESET: 421 case -ENOENT: 422 case -ESHUTDOWN: 423 case -ECONNABORTED: 424 /* after an unlink command, unplug, ... etc */ 425 /* no unlink needed here. Already shutting down. */ 426 if (devpriv->ao_cmd_running) { 427 s->async->events |= COMEDI_CB_EOA; 428 comedi_event(dev, s); 429 usbdux_ao_stop(dev, 0); 430 } 431 return; 432 433 default: 434 /* a real error */ 435 if (devpriv->ao_cmd_running) { 436 dev_err(dev->class_dev, 437 "Non-zero urb status received in ao intr context: %d\n", 438 urb->status); 439 s->async->events |= COMEDI_CB_ERROR; 440 s->async->events |= COMEDI_CB_EOA; 441 comedi_event(dev, s); 442 /* we do an unlink if we are in the high speed mode */ 443 usbdux_ao_stop(dev, 0); 444 } 445 return; 446 } 447 448 /* are we actually running? */ 449 if (!devpriv->ao_cmd_running) 450 return; 451 452 /* normal operation: executing a command in this subdevice */ 453 devpriv->ao_counter--; 454 if ((int)devpriv->ao_counter <= 0) { 455 /* timer zero */ 456 devpriv->ao_counter = devpriv->ao_timer; 457 458 /* handle non continous acquisition */ 459 if (cmd->stop_src == TRIG_COUNT) { 460 /* fixed number of samples */ 461 devpriv->ao_sample_count--; 462 if (devpriv->ao_sample_count < 0) { 463 /* all samples transmitted */ 464 usbdux_ao_stop(dev, 0); 465 s->async->events |= COMEDI_CB_EOA; 466 comedi_event(dev, s); 467 /* no resubmit of the urb */ 468 return; 469 } 470 } 471 472 /* transmit data to the USB bus */ 473 datap = urb->transfer_buffer; 474 *datap++ = cmd->chanlist_len; 475 for (i = 0; i < cmd->chanlist_len; i++) { 476 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 477 unsigned short val; 478 479 ret = comedi_buf_get(s, &val); 480 if (ret < 0) { 481 dev_err(dev->class_dev, "buffer underflow\n"); 482 s->async->events |= (COMEDI_CB_EOA | 483 COMEDI_CB_OVERFLOW); 484 } 485 /* pointer to the DA */ 486 *datap++ = val & 0xff; 487 *datap++ = (val >> 8) & 0xff; 488 *datap++ = chan << 6; 489 s->readback[chan] = val; 490 491 s->async->events |= COMEDI_CB_BLOCK; 492 comedi_event(dev, s); 493 } 494 } 495 urb->transfer_buffer_length = SIZEOUTBUF; 496 urb->dev = comedi_to_usb_dev(dev); 497 urb->status = 0; 498 if (devpriv->ao_cmd_running) { 499 if (devpriv->high_speed) 500 urb->interval = 8; /* uframes */ 501 else 502 urb->interval = 1; /* frames */ 503 urb->number_of_packets = 1; 504 urb->iso_frame_desc[0].offset = 0; 505 urb->iso_frame_desc[0].length = SIZEOUTBUF; 506 urb->iso_frame_desc[0].status = 0; 507 ret = usb_submit_urb(urb, GFP_ATOMIC); 508 if (ret < 0) { 509 dev_err(dev->class_dev, 510 "ao urb resubm failed in int-cont. ret=%d", 511 ret); 512 if (ret == -EL2NSYNC) 513 dev_err(dev->class_dev, 514 "buggy USB host controller or bug in IRQ handling!\n"); 515 516 s->async->events |= COMEDI_CB_EOA; 517 s->async->events |= COMEDI_CB_ERROR; 518 comedi_event(dev, s); 519 /* don't do an unlink here */ 520 usbdux_ao_stop(dev, 0); 521 } 522 } 523} 524 525static int usbdux_submit_urbs(struct comedi_device *dev, 526 struct urb **urbs, int num_urbs, 527 int input_urb) 528{ 529 struct usb_device *usb = comedi_to_usb_dev(dev); 530 struct usbdux_private *devpriv = dev->private; 531 struct urb *urb; 532 int ret; 533 int i; 534 535 /* Submit all URBs and start the transfer on the bus */ 536 for (i = 0; i < num_urbs; i++) { 537 urb = urbs[i]; 538 539 /* in case of a resubmission after an unlink... */ 540 if (input_urb) 541 urb->interval = devpriv->ai_interval; 542 urb->context = dev; 543 urb->dev = usb; 544 urb->status = 0; 545 urb->transfer_flags = URB_ISO_ASAP; 546 547 ret = usb_submit_urb(urb, GFP_ATOMIC); 548 if (ret) 549 return ret; 550 } 551 return 0; 552} 553 554static int usbdux_ai_cmdtest(struct comedi_device *dev, 555 struct comedi_subdevice *s, struct comedi_cmd *cmd) 556{ 557 struct usbdux_private *this_usbduxsub = dev->private; 558 int err = 0, i; 559 unsigned int tmp_timer; 560 561 /* Step 1 : check if triggers are trivially valid */ 562 563 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); 564 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); 565 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); 566 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 567 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 568 569 if (err) 570 return 1; 571 572 /* Step 2a : make sure trigger sources are unique */ 573 574 err |= cfc_check_trigger_is_unique(cmd->start_src); 575 err |= cfc_check_trigger_is_unique(cmd->stop_src); 576 577 /* Step 2b : and mutually compatible */ 578 579 if (err) 580 return 2; 581 582 /* Step 3: check if arguments are trivially valid */ 583 584 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 585 586 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ 587 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 588 589 if (cmd->scan_begin_src == TRIG_TIMER) { 590 if (this_usbduxsub->high_speed) { 591 /* 592 * In high speed mode microframes are possible. 593 * However, during one microframe we can roughly 594 * sample one channel. Thus, the more channels 595 * are in the channel list the more time we need. 596 */ 597 i = 1; 598 /* find a power of 2 for the number of channels */ 599 while (i < (cmd->chanlist_len)) 600 i = i * 2; 601 602 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 603 1000000 / 8 * i); 604 /* now calc the real sampling rate with all the 605 * rounding errors */ 606 tmp_timer = 607 ((unsigned int)(cmd->scan_begin_arg / 125000)) * 608 125000; 609 } else { 610 /* full speed */ 611 /* 1kHz scans every USB frame */ 612 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 613 1000000); 614 /* 615 * calc the real sampling rate with the rounding errors 616 */ 617 tmp_timer = ((unsigned int)(cmd->scan_begin_arg / 618 1000000)) * 1000000; 619 } 620 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 621 tmp_timer); 622 } 623 624 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 625 626 if (cmd->stop_src == TRIG_COUNT) 627 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 628 else /* TRIG_NONE */ 629 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 630 631 if (err) 632 return 3; 633 634 return 0; 635} 636 637/* 638 * creates the ADC command for the MAX1271 639 * range is the range value from comedi 640 */ 641static uint8_t create_adc_command(unsigned int chan, unsigned int range) 642{ 643 uint8_t p = (range <= 1); 644 uint8_t r = ((range % 2) == 0); 645 646 return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3); 647} 648 649static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type) 650{ 651 struct usb_device *usb = comedi_to_usb_dev(dev); 652 struct usbdux_private *devpriv = dev->private; 653 int nsent; 654 655 devpriv->dux_commands[0] = cmd_type; 656 657 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1), 658 devpriv->dux_commands, SIZEOFDUXBUFFER, 659 &nsent, BULK_TIMEOUT); 660} 661 662static int receive_dux_commands(struct comedi_device *dev, unsigned int command) 663{ 664 struct usb_device *usb = comedi_to_usb_dev(dev); 665 struct usbdux_private *devpriv = dev->private; 666 int ret; 667 int nrec; 668 int i; 669 670 for (i = 0; i < RETRIES; i++) { 671 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8), 672 devpriv->insn_buf, SIZEINSNBUF, 673 &nrec, BULK_TIMEOUT); 674 if (ret < 0) 675 return ret; 676 if (le16_to_cpu(devpriv->insn_buf[0]) == command) 677 return ret; 678 } 679 /* command not received */ 680 return -EFAULT; 681} 682 683static int usbdux_ai_inttrig(struct comedi_device *dev, 684 struct comedi_subdevice *s, 685 unsigned int trig_num) 686{ 687 struct usbdux_private *devpriv = dev->private; 688 struct comedi_cmd *cmd = &s->async->cmd; 689 int ret; 690 691 if (trig_num != cmd->start_arg) 692 return -EINVAL; 693 694 down(&devpriv->sem); 695 696 if (!devpriv->ai_cmd_running) { 697 devpriv->ai_cmd_running = 1; 698 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs, 699 devpriv->n_ai_urbs, 1); 700 if (ret < 0) { 701 devpriv->ai_cmd_running = 0; 702 goto ai_trig_exit; 703 } 704 s->async->inttrig = NULL; 705 } else { 706 ret = -EBUSY; 707 } 708 709ai_trig_exit: 710 up(&devpriv->sem); 711 return ret; 712} 713 714static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 715{ 716 struct usbdux_private *devpriv = dev->private; 717 struct comedi_cmd *cmd = &s->async->cmd; 718 int len = cmd->chanlist_len; 719 int ret = -EBUSY; 720 int i; 721 722 /* block other CPUs from starting an ai_cmd */ 723 down(&devpriv->sem); 724 725 if (devpriv->ai_cmd_running) 726 goto ai_cmd_exit; 727 728 /* set current channel of the running acquisition to zero */ 729 s->async->cur_chan = 0; 730 731 devpriv->dux_commands[1] = len; 732 for (i = 0; i < len; ++i) { 733 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 734 unsigned int range = CR_RANGE(cmd->chanlist[i]); 735 736 devpriv->dux_commands[i + 2] = create_adc_command(chan, range); 737 } 738 739 ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI); 740 if (ret < 0) 741 goto ai_cmd_exit; 742 743 if (devpriv->high_speed) { 744 /* 745 * every channel gets a time window of 125us. Thus, if we 746 * sample all 8 channels we need 1ms. If we sample only one 747 * channel we need only 125us 748 */ 749 devpriv->ai_interval = 1; 750 /* find a power of 2 for the interval */ 751 while (devpriv->ai_interval < len) 752 devpriv->ai_interval *= 2; 753 754 devpriv->ai_timer = cmd->scan_begin_arg / 755 (125000 * devpriv->ai_interval); 756 } else { 757 /* interval always 1ms */ 758 devpriv->ai_interval = 1; 759 devpriv->ai_timer = cmd->scan_begin_arg / 1000000; 760 } 761 if (devpriv->ai_timer < 1) { 762 ret = -EINVAL; 763 goto ai_cmd_exit; 764 } 765 766 devpriv->ai_counter = devpriv->ai_timer; 767 768 if (cmd->stop_src == TRIG_COUNT) { 769 /* data arrives as one packet */ 770 devpriv->ai_sample_count = cmd->stop_arg; 771 } else { 772 /* continous acquisition */ 773 devpriv->ai_sample_count = 0; 774 } 775 776 if (cmd->start_src == TRIG_NOW) { 777 /* enable this acquisition operation */ 778 devpriv->ai_cmd_running = 1; 779 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs, 780 devpriv->n_ai_urbs, 1); 781 if (ret < 0) { 782 devpriv->ai_cmd_running = 0; 783 /* fixme: unlink here?? */ 784 goto ai_cmd_exit; 785 } 786 s->async->inttrig = NULL; 787 } else { 788 /* TRIG_INT */ 789 /* don't enable the acquision operation */ 790 /* wait for an internal signal */ 791 s->async->inttrig = usbdux_ai_inttrig; 792 } 793 794ai_cmd_exit: 795 up(&devpriv->sem); 796 797 return ret; 798} 799 800/* Mode 0 is used to get a single conversion on demand */ 801static int usbdux_ai_insn_read(struct comedi_device *dev, 802 struct comedi_subdevice *s, 803 struct comedi_insn *insn, 804 unsigned int *data) 805{ 806 struct usbdux_private *devpriv = dev->private; 807 unsigned int chan = CR_CHAN(insn->chanspec); 808 unsigned int range = CR_RANGE(insn->chanspec); 809 unsigned int val; 810 int ret = -EBUSY; 811 int i; 812 813 down(&devpriv->sem); 814 815 if (devpriv->ai_cmd_running) 816 goto ai_read_exit; 817 818 /* set command for the first channel */ 819 devpriv->dux_commands[1] = create_adc_command(chan, range); 820 821 /* adc commands */ 822 ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI); 823 if (ret < 0) 824 goto ai_read_exit; 825 826 for (i = 0; i < insn->n; i++) { 827 ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI); 828 if (ret < 0) 829 goto ai_read_exit; 830 831 val = le16_to_cpu(devpriv->insn_buf[1]); 832 833 /* bipolar data is two's-complement */ 834 if (comedi_range_is_bipolar(s, range)) 835 val ^= ((s->maxdata + 1) >> 1); 836 837 data[i] = val; 838 } 839 840ai_read_exit: 841 up(&devpriv->sem); 842 843 return ret ? ret : insn->n; 844} 845 846static int usbdux_ao_insn_read(struct comedi_device *dev, 847 struct comedi_subdevice *s, 848 struct comedi_insn *insn, 849 unsigned int *data) 850{ 851 struct usbdux_private *devpriv = dev->private; 852 int ret; 853 854 down(&devpriv->sem); 855 ret = comedi_readback_insn_read(dev, s, insn, data); 856 up(&devpriv->sem); 857 858 return ret; 859} 860 861static int usbdux_ao_insn_write(struct comedi_device *dev, 862 struct comedi_subdevice *s, 863 struct comedi_insn *insn, 864 unsigned int *data) 865{ 866 struct usbdux_private *devpriv = dev->private; 867 unsigned int chan = CR_CHAN(insn->chanspec); 868 unsigned int val = s->readback[chan]; 869 __le16 *p = (__le16 *)&devpriv->dux_commands[2]; 870 int ret = -EBUSY; 871 int i; 872 873 down(&devpriv->sem); 874 875 if (devpriv->ao_cmd_running) 876 goto ao_write_exit; 877 878 /* number of channels: 1 */ 879 devpriv->dux_commands[1] = 1; 880 /* channel number */ 881 devpriv->dux_commands[4] = chan << 6; 882 883 for (i = 0; i < insn->n; i++) { 884 val = data[i]; 885 886 /* one 16 bit value */ 887 *p = cpu_to_le16(val); 888 889 ret = send_dux_commands(dev, USBDUX_CMD_AO); 890 if (ret < 0) 891 goto ao_write_exit; 892 893 s->readback[chan] = val; 894 } 895 896ao_write_exit: 897 up(&devpriv->sem); 898 899 return ret ? ret : insn->n; 900} 901 902static int usbdux_ao_inttrig(struct comedi_device *dev, 903 struct comedi_subdevice *s, 904 unsigned int trig_num) 905{ 906 struct usbdux_private *devpriv = dev->private; 907 struct comedi_cmd *cmd = &s->async->cmd; 908 int ret; 909 910 if (trig_num != cmd->start_arg) 911 return -EINVAL; 912 913 down(&devpriv->sem); 914 915 if (!devpriv->ao_cmd_running) { 916 devpriv->ao_cmd_running = 1; 917 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs, 918 devpriv->n_ao_urbs, 0); 919 if (ret < 0) { 920 devpriv->ao_cmd_running = 0; 921 goto ao_trig_exit; 922 } 923 s->async->inttrig = NULL; 924 } else { 925 ret = -EBUSY; 926 } 927 928ao_trig_exit: 929 up(&devpriv->sem); 930 return ret; 931} 932 933static int usbdux_ao_cmdtest(struct comedi_device *dev, 934 struct comedi_subdevice *s, struct comedi_cmd *cmd) 935{ 936 struct usbdux_private *this_usbduxsub = dev->private; 937 int err = 0; 938 unsigned int flags; 939 940 if (!this_usbduxsub) 941 return -EFAULT; 942 943 /* Step 1 : check if triggers are trivially valid */ 944 945 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); 946 947 if (0) { /* (this_usbduxsub->high_speed) */ 948 /* the sampling rate is set by the coversion rate */ 949 flags = TRIG_FOLLOW; 950 } else { 951 /* start a new scan (output at once) with a timer */ 952 flags = TRIG_TIMER; 953 } 954 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags); 955 956 if (0) { /* (this_usbduxsub->high_speed) */ 957 /* 958 * in usb-2.0 only one conversion it transmitted 959 * but with 8kHz/n 960 */ 961 flags = TRIG_TIMER; 962 } else { 963 /* 964 * all conversion events happen simultaneously with 965 * a rate of 1kHz/n 966 */ 967 flags = TRIG_NOW; 968 } 969 err |= cfc_check_trigger_src(&cmd->convert_src, flags); 970 971 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 972 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 973 974 if (err) 975 return 1; 976 977 /* Step 2a : make sure trigger sources are unique */ 978 979 err |= cfc_check_trigger_is_unique(cmd->start_src); 980 err |= cfc_check_trigger_is_unique(cmd->stop_src); 981 982 /* Step 2b : and mutually compatible */ 983 984 if (err) 985 return 2; 986 987 /* Step 3: check if arguments are trivially valid */ 988 989 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 990 991 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ 992 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 993 994 if (cmd->scan_begin_src == TRIG_TIMER) 995 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 996 1000000); 997 998 /* not used now, is for later use */ 999 if (cmd->convert_src == TRIG_TIMER) 1000 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000); 1001 1002 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 1003 1004 if (cmd->stop_src == TRIG_COUNT) 1005 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 1006 else /* TRIG_NONE */ 1007 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 1008 1009 if (err) 1010 return 3; 1011 1012 return 0; 1013} 1014 1015static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 1016{ 1017 struct usbdux_private *devpriv = dev->private; 1018 struct comedi_cmd *cmd = &s->async->cmd; 1019 int ret = -EBUSY; 1020 1021 down(&devpriv->sem); 1022 1023 if (devpriv->ao_cmd_running) 1024 goto ao_cmd_exit; 1025 1026 /* set current channel of the running acquisition to zero */ 1027 s->async->cur_chan = 0; 1028 1029 /* we count in steps of 1ms (125us) */ 1030 /* 125us mode not used yet */ 1031 if (0) { /* (devpriv->high_speed) */ 1032 /* 125us */ 1033 /* timing of the conversion itself: every 125 us */ 1034 devpriv->ao_timer = cmd->convert_arg / 125000; 1035 } else { 1036 /* 1ms */ 1037 /* timing of the scan: we get all channels at once */ 1038 devpriv->ao_timer = cmd->scan_begin_arg / 1000000; 1039 if (devpriv->ao_timer < 1) { 1040 ret = -EINVAL; 1041 goto ao_cmd_exit; 1042 } 1043 } 1044 1045 devpriv->ao_counter = devpriv->ao_timer; 1046 1047 if (cmd->stop_src == TRIG_COUNT) { 1048 /* not continuous */ 1049 /* counter */ 1050 /* high speed also scans everything at once */ 1051 if (0) { /* (devpriv->high_speed) */ 1052 devpriv->ao_sample_count = cmd->stop_arg * 1053 cmd->scan_end_arg; 1054 } else { 1055 /* there's no scan as the scan has been */ 1056 /* perf inside the FX2 */ 1057 /* data arrives as one packet */ 1058 devpriv->ao_sample_count = cmd->stop_arg; 1059 } 1060 } else { 1061 /* continous acquisition */ 1062 devpriv->ao_sample_count = 0; 1063 } 1064 1065 if (cmd->start_src == TRIG_NOW) { 1066 /* enable this acquisition operation */ 1067 devpriv->ao_cmd_running = 1; 1068 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs, 1069 devpriv->n_ao_urbs, 0); 1070 if (ret < 0) { 1071 devpriv->ao_cmd_running = 0; 1072 /* fixme: unlink here?? */ 1073 goto ao_cmd_exit; 1074 } 1075 s->async->inttrig = NULL; 1076 } else { 1077 /* TRIG_INT */ 1078 /* submit the urbs later */ 1079 /* wait for an internal signal */ 1080 s->async->inttrig = usbdux_ao_inttrig; 1081 } 1082 1083ao_cmd_exit: 1084 up(&devpriv->sem); 1085 1086 return ret; 1087} 1088 1089static int usbdux_dio_insn_config(struct comedi_device *dev, 1090 struct comedi_subdevice *s, 1091 struct comedi_insn *insn, 1092 unsigned int *data) 1093{ 1094 int ret; 1095 1096 ret = comedi_dio_insn_config(dev, s, insn, data, 0); 1097 if (ret) 1098 return ret; 1099 1100 /* 1101 * We don't tell the firmware here as it would take 8 frames 1102 * to submit the information. We do it in the insn_bits. 1103 */ 1104 return insn->n; 1105} 1106 1107static int usbdux_dio_insn_bits(struct comedi_device *dev, 1108 struct comedi_subdevice *s, 1109 struct comedi_insn *insn, 1110 unsigned int *data) 1111{ 1112 1113 struct usbdux_private *devpriv = dev->private; 1114 int ret; 1115 1116 down(&devpriv->sem); 1117 1118 comedi_dio_update_state(s, data); 1119 1120 /* Always update the hardware. See the (*insn_config). */ 1121 devpriv->dux_commands[1] = s->io_bits; 1122 devpriv->dux_commands[2] = s->state; 1123 1124 /* 1125 * This command also tells the firmware to return 1126 * the digital input lines. 1127 */ 1128 ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS); 1129 if (ret < 0) 1130 goto dio_exit; 1131 ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS); 1132 if (ret < 0) 1133 goto dio_exit; 1134 1135 data[1] = le16_to_cpu(devpriv->insn_buf[1]); 1136 1137dio_exit: 1138 up(&devpriv->sem); 1139 1140 return ret ? ret : insn->n; 1141} 1142 1143static int usbdux_counter_read(struct comedi_device *dev, 1144 struct comedi_subdevice *s, 1145 struct comedi_insn *insn, 1146 unsigned int *data) 1147{ 1148 struct usbdux_private *devpriv = dev->private; 1149 unsigned int chan = CR_CHAN(insn->chanspec); 1150 int ret = 0; 1151 int i; 1152 1153 down(&devpriv->sem); 1154 1155 for (i = 0; i < insn->n; i++) { 1156 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD); 1157 if (ret < 0) 1158 goto counter_read_exit; 1159 ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD); 1160 if (ret < 0) 1161 goto counter_read_exit; 1162 1163 data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]); 1164 } 1165 1166counter_read_exit: 1167 up(&devpriv->sem); 1168 1169 return ret ? ret : insn->n; 1170} 1171 1172static int usbdux_counter_write(struct comedi_device *dev, 1173 struct comedi_subdevice *s, 1174 struct comedi_insn *insn, 1175 unsigned int *data) 1176{ 1177 struct usbdux_private *devpriv = dev->private; 1178 unsigned int chan = CR_CHAN(insn->chanspec); 1179 __le16 *p = (__le16 *)&devpriv->dux_commands[2]; 1180 int ret = 0; 1181 int i; 1182 1183 down(&devpriv->sem); 1184 1185 devpriv->dux_commands[1] = chan; 1186 1187 for (i = 0; i < insn->n; i++) { 1188 *p = cpu_to_le16(data[i]); 1189 1190 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR); 1191 if (ret < 0) 1192 break; 1193 } 1194 1195 up(&devpriv->sem); 1196 1197 return ret ? ret : insn->n; 1198} 1199 1200static int usbdux_counter_config(struct comedi_device *dev, 1201 struct comedi_subdevice *s, 1202 struct comedi_insn *insn, unsigned int *data) 1203{ 1204 /* nothing to do so far */ 1205 return 2; 1206} 1207 1208static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev) 1209{ 1210 struct usbdux_private *devpriv = dev->private; 1211 1212 usb_kill_urb(devpriv->pwm_urb); 1213} 1214 1215static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink) 1216{ 1217 struct usbdux_private *devpriv = dev->private; 1218 1219 if (do_unlink) 1220 usbduxsub_unlink_pwm_urbs(dev); 1221 1222 devpriv->pwm_cmd_running = 0; 1223} 1224 1225static int usbdux_pwm_cancel(struct comedi_device *dev, 1226 struct comedi_subdevice *s) 1227{ 1228 struct usbdux_private *devpriv = dev->private; 1229 int ret; 1230 1231 down(&devpriv->sem); 1232 /* unlink only if it is really running */ 1233 usbdux_pwm_stop(dev, devpriv->pwm_cmd_running); 1234 ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF); 1235 up(&devpriv->sem); 1236 1237 return ret; 1238} 1239 1240static void usbduxsub_pwm_irq(struct urb *urb) 1241{ 1242 struct comedi_device *dev = urb->context; 1243 struct usbdux_private *devpriv = dev->private; 1244 int ret; 1245 1246 switch (urb->status) { 1247 case 0: 1248 /* success */ 1249 break; 1250 1251 case -ECONNRESET: 1252 case -ENOENT: 1253 case -ESHUTDOWN: 1254 case -ECONNABORTED: 1255 /* 1256 * after an unlink command, unplug, ... etc 1257 * no unlink needed here. Already shutting down. 1258 */ 1259 if (devpriv->pwm_cmd_running) 1260 usbdux_pwm_stop(dev, 0); 1261 1262 return; 1263 1264 default: 1265 /* a real error */ 1266 if (devpriv->pwm_cmd_running) { 1267 dev_err(dev->class_dev, 1268 "Non-zero urb status received in pwm intr context: %d\n", 1269 urb->status); 1270 usbdux_pwm_stop(dev, 0); 1271 } 1272 return; 1273 } 1274 1275 /* are we actually running? */ 1276 if (!devpriv->pwm_cmd_running) 1277 return; 1278 1279 urb->transfer_buffer_length = devpriv->pwm_buf_sz; 1280 urb->dev = comedi_to_usb_dev(dev); 1281 urb->status = 0; 1282 if (devpriv->pwm_cmd_running) { 1283 ret = usb_submit_urb(urb, GFP_ATOMIC); 1284 if (ret < 0) { 1285 dev_err(dev->class_dev, 1286 "pwm urb resubm failed in int-cont. ret=%d", 1287 ret); 1288 if (ret == -EL2NSYNC) 1289 dev_err(dev->class_dev, 1290 "buggy USB host controller or bug in IRQ handling!\n"); 1291 1292 /* don't do an unlink here */ 1293 usbdux_pwm_stop(dev, 0); 1294 } 1295 } 1296} 1297 1298static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev) 1299{ 1300 struct usb_device *usb = comedi_to_usb_dev(dev); 1301 struct usbdux_private *devpriv = dev->private; 1302 struct urb *urb = devpriv->pwm_urb; 1303 1304 /* in case of a resubmission after an unlink... */ 1305 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4), 1306 urb->transfer_buffer, 1307 devpriv->pwm_buf_sz, 1308 usbduxsub_pwm_irq, 1309 dev); 1310 1311 return usb_submit_urb(urb, GFP_ATOMIC); 1312} 1313 1314static int usbdux_pwm_period(struct comedi_device *dev, 1315 struct comedi_subdevice *s, 1316 unsigned int period) 1317{ 1318 struct usbdux_private *devpriv = dev->private; 1319 int fx2delay = 255; 1320 1321 if (period < MIN_PWM_PERIOD) 1322 return -EAGAIN; 1323 1324 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6; 1325 if (fx2delay > 255) 1326 return -EAGAIN; 1327 1328 devpriv->pwm_delay = fx2delay; 1329 devpriv->pwm_period = period; 1330 1331 return 0; 1332} 1333 1334static int usbdux_pwm_start(struct comedi_device *dev, 1335 struct comedi_subdevice *s) 1336{ 1337 struct usbdux_private *devpriv = dev->private; 1338 int ret = 0; 1339 1340 down(&devpriv->sem); 1341 1342 if (devpriv->pwm_cmd_running) 1343 goto pwm_start_exit; 1344 1345 devpriv->dux_commands[1] = devpriv->pwm_delay; 1346 ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON); 1347 if (ret < 0) 1348 goto pwm_start_exit; 1349 1350 /* initialise the buffer */ 1351 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz); 1352 1353 devpriv->pwm_cmd_running = 1; 1354 ret = usbduxsub_submit_pwm_urbs(dev); 1355 if (ret < 0) 1356 devpriv->pwm_cmd_running = 0; 1357 1358pwm_start_exit: 1359 up(&devpriv->sem); 1360 1361 return ret; 1362} 1363 1364static void usbdux_pwm_pattern(struct comedi_device *dev, 1365 struct comedi_subdevice *s, 1366 unsigned int chan, 1367 unsigned int value, 1368 unsigned int sign) 1369{ 1370 struct usbdux_private *devpriv = dev->private; 1371 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */ 1372 char sgn_mask = (16 << chan); /* DIO bit for the sign */ 1373 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer); 1374 int szbuf = devpriv->pwm_buf_sz; 1375 int i; 1376 1377 for (i = 0; i < szbuf; i++) { 1378 char c = *buf; 1379 1380 c &= ~pwm_mask; 1381 if (i < value) 1382 c |= pwm_mask; 1383 if (!sign) 1384 c &= ~sgn_mask; 1385 else 1386 c |= sgn_mask; 1387 *buf++ = c; 1388 } 1389} 1390 1391static int usbdux_pwm_write(struct comedi_device *dev, 1392 struct comedi_subdevice *s, 1393 struct comedi_insn *insn, 1394 unsigned int *data) 1395{ 1396 unsigned int chan = CR_CHAN(insn->chanspec); 1397 1398 /* 1399 * It doesn't make sense to support more than one value here 1400 * because it would just overwrite the PWM buffer. 1401 */ 1402 if (insn->n != 1) 1403 return -EINVAL; 1404 1405 /* 1406 * The sign is set via a special INSN only, this gives us 8 bits 1407 * for normal operation, sign is 0 by default. 1408 */ 1409 usbdux_pwm_pattern(dev, s, chan, data[0], 0); 1410 1411 return insn->n; 1412} 1413 1414static int usbdux_pwm_config(struct comedi_device *dev, 1415 struct comedi_subdevice *s, 1416 struct comedi_insn *insn, 1417 unsigned int *data) 1418{ 1419 struct usbdux_private *devpriv = dev->private; 1420 unsigned int chan = CR_CHAN(insn->chanspec); 1421 1422 switch (data[0]) { 1423 case INSN_CONFIG_ARM: 1424 /* 1425 * if not zero the PWM is limited to a certain time which is 1426 * not supported here 1427 */ 1428 if (data[1] != 0) 1429 return -EINVAL; 1430 return usbdux_pwm_start(dev, s); 1431 case INSN_CONFIG_DISARM: 1432 return usbdux_pwm_cancel(dev, s); 1433 case INSN_CONFIG_GET_PWM_STATUS: 1434 data[1] = devpriv->pwm_cmd_running; 1435 return 0; 1436 case INSN_CONFIG_PWM_SET_PERIOD: 1437 return usbdux_pwm_period(dev, s, data[1]); 1438 case INSN_CONFIG_PWM_GET_PERIOD: 1439 data[1] = devpriv->pwm_period; 1440 return 0; 1441 case INSN_CONFIG_PWM_SET_H_BRIDGE: 1442 /* 1443 * data[1] = value 1444 * data[2] = sign (for a relay) 1445 */ 1446 usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0)); 1447 return 0; 1448 case INSN_CONFIG_PWM_GET_H_BRIDGE: 1449 /* values are not kept in this driver, nothing to return here */ 1450 return -EINVAL; 1451 } 1452 return -EINVAL; 1453} 1454 1455static int usbdux_firmware_upload(struct comedi_device *dev, 1456 const u8 *data, size_t size, 1457 unsigned long context) 1458{ 1459 struct usb_device *usb = comedi_to_usb_dev(dev); 1460 uint8_t *buf; 1461 uint8_t *tmp; 1462 int ret; 1463 1464 if (!data) 1465 return 0; 1466 1467 if (size > USBDUX_FIRMWARE_MAX_LEN) { 1468 dev_err(dev->class_dev, 1469 "usbdux firmware binary it too large for FX2.\n"); 1470 return -ENOMEM; 1471 } 1472 1473 /* we generate a local buffer for the firmware */ 1474 buf = kmemdup(data, size, GFP_KERNEL); 1475 if (!buf) 1476 return -ENOMEM; 1477 1478 /* we need a malloc'ed buffer for usb_control_msg() */ 1479 tmp = kmalloc(1, GFP_KERNEL); 1480 if (!tmp) { 1481 kfree(buf); 1482 return -ENOMEM; 1483 } 1484 1485 /* stop the current firmware on the device */ 1486 *tmp = 1; /* 7f92 to one */ 1487 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1488 USBDUX_FIRMWARE_CMD, 1489 VENDOR_DIR_OUT, 1490 USBDUX_CPU_CS, 0x0000, 1491 tmp, 1, 1492 BULK_TIMEOUT); 1493 if (ret < 0) { 1494 dev_err(dev->class_dev, "can not stop firmware\n"); 1495 goto done; 1496 } 1497 1498 /* upload the new firmware to the device */ 1499 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1500 USBDUX_FIRMWARE_CMD, 1501 VENDOR_DIR_OUT, 1502 0, 0x0000, 1503 buf, size, 1504 BULK_TIMEOUT); 1505 if (ret < 0) { 1506 dev_err(dev->class_dev, "firmware upload failed\n"); 1507 goto done; 1508 } 1509 1510 /* start the new firmware on the device */ 1511 *tmp = 0; /* 7f92 to zero */ 1512 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1513 USBDUX_FIRMWARE_CMD, 1514 VENDOR_DIR_OUT, 1515 USBDUX_CPU_CS, 0x0000, 1516 tmp, 1, 1517 BULK_TIMEOUT); 1518 if (ret < 0) 1519 dev_err(dev->class_dev, "can not start firmware\n"); 1520 1521done: 1522 kfree(tmp); 1523 kfree(buf); 1524 return ret; 1525} 1526 1527static int usbdux_alloc_usb_buffers(struct comedi_device *dev) 1528{ 1529 struct usb_device *usb = comedi_to_usb_dev(dev); 1530 struct usbdux_private *devpriv = dev->private; 1531 struct urb *urb; 1532 int i; 1533 1534 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); 1535 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL); 1536 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL); 1537 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *), 1538 GFP_KERNEL); 1539 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *), 1540 GFP_KERNEL); 1541 if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf || 1542 !devpriv->ai_urbs || !devpriv->ao_urbs) 1543 return -ENOMEM; 1544 1545 for (i = 0; i < devpriv->n_ai_urbs; i++) { 1546 /* one frame: 1ms */ 1547 urb = usb_alloc_urb(1, GFP_KERNEL); 1548 if (!urb) 1549 return -ENOMEM; 1550 devpriv->ai_urbs[i] = urb; 1551 1552 urb->dev = usb; 1553 urb->context = dev; 1554 urb->pipe = usb_rcvisocpipe(usb, 6); 1555 urb->transfer_flags = URB_ISO_ASAP; 1556 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL); 1557 if (!urb->transfer_buffer) 1558 return -ENOMEM; 1559 1560 urb->complete = usbduxsub_ai_isoc_irq; 1561 urb->number_of_packets = 1; 1562 urb->transfer_buffer_length = SIZEINBUF; 1563 urb->iso_frame_desc[0].offset = 0; 1564 urb->iso_frame_desc[0].length = SIZEINBUF; 1565 } 1566 1567 for (i = 0; i < devpriv->n_ao_urbs; i++) { 1568 /* one frame: 1ms */ 1569 urb = usb_alloc_urb(1, GFP_KERNEL); 1570 if (!urb) 1571 return -ENOMEM; 1572 devpriv->ao_urbs[i] = urb; 1573 1574 urb->dev = usb; 1575 urb->context = dev; 1576 urb->pipe = usb_sndisocpipe(usb, 2); 1577 urb->transfer_flags = URB_ISO_ASAP; 1578 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); 1579 if (!urb->transfer_buffer) 1580 return -ENOMEM; 1581 1582 urb->complete = usbduxsub_ao_isoc_irq; 1583 urb->number_of_packets = 1; 1584 urb->transfer_buffer_length = SIZEOUTBUF; 1585 urb->iso_frame_desc[0].offset = 0; 1586 urb->iso_frame_desc[0].length = SIZEOUTBUF; 1587 if (devpriv->high_speed) 1588 urb->interval = 8; /* uframes */ 1589 else 1590 urb->interval = 1; /* frames */ 1591 } 1592 1593 /* pwm */ 1594 if (devpriv->pwm_buf_sz) { 1595 urb = usb_alloc_urb(0, GFP_KERNEL); 1596 if (!urb) 1597 return -ENOMEM; 1598 devpriv->pwm_urb = urb; 1599 1600 /* max bulk ep size in high speed */ 1601 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, 1602 GFP_KERNEL); 1603 if (!urb->transfer_buffer) 1604 return -ENOMEM; 1605 } 1606 1607 return 0; 1608} 1609 1610static void usbdux_free_usb_buffers(struct comedi_device *dev) 1611{ 1612 struct usbdux_private *devpriv = dev->private; 1613 struct urb *urb; 1614 int i; 1615 1616 urb = devpriv->pwm_urb; 1617 if (urb) { 1618 kfree(urb->transfer_buffer); 1619 usb_free_urb(urb); 1620 } 1621 if (devpriv->ao_urbs) { 1622 for (i = 0; i < devpriv->n_ao_urbs; i++) { 1623 urb = devpriv->ao_urbs[i]; 1624 if (urb) { 1625 kfree(urb->transfer_buffer); 1626 usb_free_urb(urb); 1627 } 1628 } 1629 kfree(devpriv->ao_urbs); 1630 } 1631 if (devpriv->ai_urbs) { 1632 for (i = 0; i < devpriv->n_ai_urbs; i++) { 1633 urb = devpriv->ai_urbs[i]; 1634 if (urb) { 1635 kfree(urb->transfer_buffer); 1636 usb_free_urb(urb); 1637 } 1638 } 1639 kfree(devpriv->ai_urbs); 1640 } 1641 kfree(devpriv->insn_buf); 1642 kfree(devpriv->in_buf); 1643 kfree(devpriv->dux_commands); 1644} 1645 1646static int usbdux_auto_attach(struct comedi_device *dev, 1647 unsigned long context_unused) 1648{ 1649 struct usb_interface *intf = comedi_to_usb_interface(dev); 1650 struct usb_device *usb = comedi_to_usb_dev(dev); 1651 struct usbdux_private *devpriv; 1652 struct comedi_subdevice *s; 1653 int ret; 1654 1655 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1656 if (!devpriv) 1657 return -ENOMEM; 1658 1659 sema_init(&devpriv->sem, 1); 1660 1661 usb_set_intfdata(intf, devpriv); 1662 1663 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH); 1664 if (devpriv->high_speed) { 1665 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH; 1666 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH; 1667 devpriv->pwm_buf_sz = 512; 1668 } else { 1669 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL; 1670 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL; 1671 } 1672 1673 ret = usbdux_alloc_usb_buffers(dev); 1674 if (ret) 1675 return ret; 1676 1677 /* setting to alternate setting 3: enabling iso ep and bulk ep. */ 1678 ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber, 1679 3); 1680 if (ret < 0) { 1681 dev_err(dev->class_dev, 1682 "could not set alternate setting 3 in high speed\n"); 1683 return ret; 1684 } 1685 1686 ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE, 1687 usbdux_firmware_upload, 0); 1688 if (ret < 0) 1689 return ret; 1690 1691 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4); 1692 if (ret) 1693 return ret; 1694 1695 /* Analog Input subdevice */ 1696 s = &dev->subdevices[0]; 1697 dev->read_subdev = s; 1698 s->type = COMEDI_SUBD_AI; 1699 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; 1700 s->n_chan = 8; 1701 s->maxdata = 0x0fff; 1702 s->len_chanlist = 8; 1703 s->range_table = &range_usbdux_ai_range; 1704 s->insn_read = usbdux_ai_insn_read; 1705 s->do_cmdtest = usbdux_ai_cmdtest; 1706 s->do_cmd = usbdux_ai_cmd; 1707 s->cancel = usbdux_ai_cancel; 1708 1709 /* Analog Output subdevice */ 1710 s = &dev->subdevices[1]; 1711 dev->write_subdev = s; 1712 s->type = COMEDI_SUBD_AO; 1713 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; 1714 s->n_chan = 4; 1715 s->maxdata = 0x0fff; 1716 s->len_chanlist = s->n_chan; 1717 s->range_table = &range_usbdux_ao_range; 1718 s->do_cmdtest = usbdux_ao_cmdtest; 1719 s->do_cmd = usbdux_ao_cmd; 1720 s->cancel = usbdux_ao_cancel; 1721 s->insn_read = usbdux_ao_insn_read; 1722 s->insn_write = usbdux_ao_insn_write; 1723 1724 ret = comedi_alloc_subdev_readback(s); 1725 if (ret) 1726 return ret; 1727 1728 /* Digital I/O subdevice */ 1729 s = &dev->subdevices[2]; 1730 s->type = COMEDI_SUBD_DIO; 1731 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1732 s->n_chan = 8; 1733 s->maxdata = 1; 1734 s->range_table = &range_digital; 1735 s->insn_bits = usbdux_dio_insn_bits; 1736 s->insn_config = usbdux_dio_insn_config; 1737 1738 /* Counter subdevice */ 1739 s = &dev->subdevices[3]; 1740 s->type = COMEDI_SUBD_COUNTER; 1741 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 1742 s->n_chan = 4; 1743 s->maxdata = 0xffff; 1744 s->insn_read = usbdux_counter_read; 1745 s->insn_write = usbdux_counter_write; 1746 s->insn_config = usbdux_counter_config; 1747 1748 if (devpriv->high_speed) { 1749 /* PWM subdevice */ 1750 s = &dev->subdevices[4]; 1751 s->type = COMEDI_SUBD_PWM; 1752 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; 1753 s->n_chan = 8; 1754 s->maxdata = devpriv->pwm_buf_sz; 1755 s->insn_write = usbdux_pwm_write; 1756 s->insn_config = usbdux_pwm_config; 1757 1758 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); 1759 } 1760 1761 return 0; 1762} 1763 1764static void usbdux_detach(struct comedi_device *dev) 1765{ 1766 struct usb_interface *intf = comedi_to_usb_interface(dev); 1767 struct usbdux_private *devpriv = dev->private; 1768 1769 usb_set_intfdata(intf, NULL); 1770 1771 if (!devpriv) 1772 return; 1773 1774 down(&devpriv->sem); 1775 1776 /* force unlink all urbs */ 1777 usbdux_pwm_stop(dev, 1); 1778 usbdux_ao_stop(dev, 1); 1779 usbdux_ai_stop(dev, 1); 1780 1781 usbdux_free_usb_buffers(dev); 1782 1783 up(&devpriv->sem); 1784} 1785 1786static struct comedi_driver usbdux_driver = { 1787 .driver_name = "usbdux", 1788 .module = THIS_MODULE, 1789 .auto_attach = usbdux_auto_attach, 1790 .detach = usbdux_detach, 1791}; 1792 1793static int usbdux_usb_probe(struct usb_interface *intf, 1794 const struct usb_device_id *id) 1795{ 1796 return comedi_usb_auto_config(intf, &usbdux_driver, 0); 1797} 1798 1799static const struct usb_device_id usbdux_usb_table[] = { 1800 { USB_DEVICE(0x13d8, 0x0001) }, 1801 { USB_DEVICE(0x13d8, 0x0002) }, 1802 { } 1803}; 1804MODULE_DEVICE_TABLE(usb, usbdux_usb_table); 1805 1806static struct usb_driver usbdux_usb_driver = { 1807 .name = "usbdux", 1808 .probe = usbdux_usb_probe, 1809 .disconnect = comedi_usb_auto_unconfig, 1810 .id_table = usbdux_usb_table, 1811}; 1812module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); 1813 1814MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); 1815MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); 1816MODULE_LICENSE("GPL"); 1817MODULE_FIRMWARE(USBDUX_FIRMWARE); 1818