1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * usbduxsigma.c 4 * Copyright (C) 2011-2015 Bernd Porr, mail@berndporr.me.uk 5 */ 6 7/* 8 * Driver: usbduxsigma 9 * Description: University of Stirling USB DAQ & INCITE Technology Limited 10 * Devices: [ITL] USB-DUX-SIGMA (usbduxsigma) 11 * Author: Bernd Porr <mail@berndporr.me.uk> 12 * Updated: 20 July 2015 13 * Status: stable 14 */ 15 16/* 17 * I must give credit here to Chris Baugher who 18 * wrote the driver for AT-MIO-16d. I used some parts of this 19 * driver. I also must give credits to David Brownell 20 * who supported me with the USB development. 21 * 22 * Note: the raw data from the A/D converter is 24 bit big endian 23 * anything else is little endian to/from the dux board 24 * 25 * 26 * Revision history: 27 * 0.1: initial version 28 * 0.2: all basic functions implemented, digital I/O only for one port 29 * 0.3: proper vendor ID and driver name 30 * 0.4: fixed D/A voltage range 31 * 0.5: various bug fixes, health check at startup 32 * 0.6: corrected wrong input range 33 * 0.7: rewrite code that urb->interval is always 1 34 */ 35 36#include <linux/kernel.h> 37#include <linux/module.h> 38#include <linux/slab.h> 39#include <linux/input.h> 40#include <linux/fcntl.h> 41#include <linux/compiler.h> 42#include <asm/unaligned.h> 43#include <linux/comedi/comedi_usb.h> 44 45/* timeout for the USB-transfer in ms*/ 46#define BULK_TIMEOUT 1000 47 48/* constants for "firmware" upload and download */ 49#define FIRMWARE "usbduxsigma_firmware.bin" 50#define FIRMWARE_MAX_LEN 0x4000 51#define USBDUXSUB_FIRMWARE 0xa0 52#define VENDOR_DIR_IN 0xc0 53#define VENDOR_DIR_OUT 0x40 54 55/* internal addresses of the 8051 processor */ 56#define USBDUXSUB_CPUCS 0xE600 57 58/* 300Hz max frequ under PWM */ 59#define MIN_PWM_PERIOD ((long)(1E9 / 300)) 60 61/* Default PWM frequency */ 62#define PWM_DEFAULT_PERIOD ((long)(1E9 / 100)) 63 64/* Number of channels (16 AD and offset)*/ 65#define NUMCHANNELS 16 66 67/* Size of one A/D value */ 68#define SIZEADIN ((sizeof(u32))) 69 70/* 71 * Size of the async input-buffer IN BYTES, the DIO state is transmitted 72 * as the first byte. 73 */ 74#define SIZEINBUF (((NUMCHANNELS + 1) * SIZEADIN)) 75 76/* 16 bytes. */ 77#define SIZEINSNBUF 16 78 79/* Number of DA channels */ 80#define NUMOUTCHANNELS 8 81 82/* size of one value for the D/A converter: channel and value */ 83#define SIZEDAOUT ((sizeof(u8) + sizeof(uint16_t))) 84 85/* 86 * Size of the output-buffer in bytes 87 * Actually only the first 4 triplets are used but for the 88 * high speed mode we need to pad it to 8 (microframes). 89 */ 90#define SIZEOUTBUF ((8 * SIZEDAOUT)) 91 92/* 93 * Size of the buffer for the dux commands: just now max size is determined 94 * by the analogue out + command byte + panic bytes... 95 */ 96#define SIZEOFDUXBUFFER ((8 * SIZEDAOUT + 2)) 97 98/* Number of in-URBs which receive the data: min=2 */ 99#define NUMOFINBUFFERSFULL 5 100 101/* Number of out-URBs which send the data: min=2 */ 102#define NUMOFOUTBUFFERSFULL 5 103 104/* Number of in-URBs which receive the data: min=5 */ 105/* must have more buffers due to buggy USB ctr */ 106#define NUMOFINBUFFERSHIGH 10 107 108/* Number of out-URBs which send the data: min=5 */ 109/* must have more buffers due to buggy USB ctr */ 110#define NUMOFOUTBUFFERSHIGH 10 111 112/* number of retries to get the right dux command */ 113#define RETRIES 10 114 115/* bulk transfer commands to usbduxsigma */ 116#define USBBUXSIGMA_AD_CMD 9 117#define USBDUXSIGMA_DA_CMD 1 118#define USBDUXSIGMA_DIO_CFG_CMD 2 119#define USBDUXSIGMA_DIO_BITS_CMD 3 120#define USBDUXSIGMA_SINGLE_AD_CMD 4 121#define USBDUXSIGMA_PWM_ON_CMD 7 122#define USBDUXSIGMA_PWM_OFF_CMD 8 123 124static const struct comedi_lrange usbduxsigma_ai_range = { 125 1, { 126 BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0) 127 } 128}; 129 130struct usbduxsigma_private { 131 /* actual number of in-buffers */ 132 int n_ai_urbs; 133 /* actual number of out-buffers */ 134 int n_ao_urbs; 135 /* ISO-transfer handling: buffers */ 136 struct urb **ai_urbs; 137 struct urb **ao_urbs; 138 /* pwm-transfer handling */ 139 struct urb *pwm_urb; 140 /* PWM period */ 141 unsigned int pwm_period; 142 /* PWM internal delay for the GPIF in the FX2 */ 143 u8 pwm_delay; 144 /* size of the PWM buffer which holds the bit pattern */ 145 int pwm_buf_sz; 146 /* input buffer for the ISO-transfer */ 147 __be32 *in_buf; 148 /* input buffer for single insn */ 149 u8 *insn_buf; 150 151 unsigned high_speed:1; 152 unsigned ai_cmd_running:1; 153 unsigned ao_cmd_running:1; 154 unsigned pwm_cmd_running:1; 155 156 /* time between samples in units of the timer */ 157 unsigned int ai_timer; 158 unsigned int ao_timer; 159 /* counter between acquisitions */ 160 unsigned int ai_counter; 161 unsigned int ao_counter; 162 /* interval in frames/uframes */ 163 unsigned int ai_interval; 164 /* commands */ 165 u8 *dux_commands; 166 struct mutex mut; 167}; 168 169static void usbduxsigma_unlink_urbs(struct urb **urbs, int num_urbs) 170{ 171 int i; 172 173 for (i = 0; i < num_urbs; i++) 174 usb_kill_urb(urbs[i]); 175} 176 177static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink) 178{ 179 struct usbduxsigma_private *devpriv = dev->private; 180 181 if (do_unlink && devpriv->ai_urbs) 182 usbduxsigma_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs); 183 184 devpriv->ai_cmd_running = 0; 185} 186 187static int usbduxsigma_ai_cancel(struct comedi_device *dev, 188 struct comedi_subdevice *s) 189{ 190 struct usbduxsigma_private *devpriv = dev->private; 191 192 mutex_lock(&devpriv->mut); 193 /* unlink only if it is really running */ 194 usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running); 195 mutex_unlock(&devpriv->mut); 196 197 return 0; 198} 199 200static void usbduxsigma_ai_handle_urb(struct comedi_device *dev, 201 struct comedi_subdevice *s, 202 struct urb *urb) 203{ 204 struct usbduxsigma_private *devpriv = dev->private; 205 struct comedi_async *async = s->async; 206 struct comedi_cmd *cmd = &async->cmd; 207 u32 val; 208 int ret; 209 int i; 210 211 if ((urb->actual_length > 0) && (urb->status != -EXDEV)) { 212 devpriv->ai_counter--; 213 if (devpriv->ai_counter == 0) { 214 devpriv->ai_counter = devpriv->ai_timer; 215 216 /* 217 * Get the data from the USB bus and hand it over 218 * to comedi. Note, first byte is the DIO state. 219 */ 220 for (i = 0; i < cmd->chanlist_len; i++) { 221 val = be32_to_cpu(devpriv->in_buf[i + 1]); 222 val &= 0x00ffffff; /* strip status byte */ 223 val = comedi_offset_munge(s, val); 224 if (!comedi_buf_write_samples(s, &val, 1)) 225 return; 226 } 227 228 if (cmd->stop_src == TRIG_COUNT && 229 async->scans_done >= cmd->stop_arg) 230 async->events |= COMEDI_CB_EOA; 231 } 232 } 233 234 /* if command is still running, resubmit urb */ 235 if (!(async->events & COMEDI_CB_CANCEL_MASK)) { 236 urb->dev = comedi_to_usb_dev(dev); 237 ret = usb_submit_urb(urb, GFP_ATOMIC); 238 if (ret < 0) { 239 dev_err(dev->class_dev, "urb resubmit failed (%d)\n", 240 ret); 241 if (ret == -EL2NSYNC) 242 dev_err(dev->class_dev, 243 "buggy USB host controller or bug in IRQ handler\n"); 244 async->events |= COMEDI_CB_ERROR; 245 } 246 } 247} 248 249static void usbduxsigma_ai_urb_complete(struct urb *urb) 250{ 251 struct comedi_device *dev = urb->context; 252 struct usbduxsigma_private *devpriv = dev->private; 253 struct comedi_subdevice *s = dev->read_subdev; 254 struct comedi_async *async = s->async; 255 256 /* exit if not running a command, do not resubmit urb */ 257 if (!devpriv->ai_cmd_running) 258 return; 259 260 switch (urb->status) { 261 case 0: 262 /* copy the result in the transfer buffer */ 263 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF); 264 usbduxsigma_ai_handle_urb(dev, s, urb); 265 break; 266 267 case -EILSEQ: 268 /* 269 * error in the ISOchronous data 270 * we don't copy the data into the transfer buffer 271 * and recycle the last data byte 272 */ 273 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n"); 274 usbduxsigma_ai_handle_urb(dev, s, urb); 275 break; 276 277 case -ECONNRESET: 278 case -ENOENT: 279 case -ESHUTDOWN: 280 case -ECONNABORTED: 281 /* happens after an unlink command */ 282 async->events |= COMEDI_CB_ERROR; 283 break; 284 285 default: 286 /* a real error */ 287 dev_err(dev->class_dev, "non-zero urb status (%d)\n", 288 urb->status); 289 async->events |= COMEDI_CB_ERROR; 290 break; 291 } 292 293 /* 294 * comedi_handle_events() cannot be used in this driver. The (*cancel) 295 * operation would unlink the urb. 296 */ 297 if (async->events & COMEDI_CB_CANCEL_MASK) 298 usbduxsigma_ai_stop(dev, 0); 299 300 comedi_event(dev, s); 301} 302 303static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink) 304{ 305 struct usbduxsigma_private *devpriv = dev->private; 306 307 if (do_unlink && devpriv->ao_urbs) 308 usbduxsigma_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs); 309 310 devpriv->ao_cmd_running = 0; 311} 312 313static int usbduxsigma_ao_cancel(struct comedi_device *dev, 314 struct comedi_subdevice *s) 315{ 316 struct usbduxsigma_private *devpriv = dev->private; 317 318 mutex_lock(&devpriv->mut); 319 /* unlink only if it is really running */ 320 usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running); 321 mutex_unlock(&devpriv->mut); 322 323 return 0; 324} 325 326static void usbduxsigma_ao_handle_urb(struct comedi_device *dev, 327 struct comedi_subdevice *s, 328 struct urb *urb) 329{ 330 struct usbduxsigma_private *devpriv = dev->private; 331 struct comedi_async *async = s->async; 332 struct comedi_cmd *cmd = &async->cmd; 333 u8 *datap; 334 int ret; 335 int i; 336 337 devpriv->ao_counter--; 338 if (devpriv->ao_counter == 0) { 339 devpriv->ao_counter = devpriv->ao_timer; 340 341 if (cmd->stop_src == TRIG_COUNT && 342 async->scans_done >= cmd->stop_arg) { 343 async->events |= COMEDI_CB_EOA; 344 return; 345 } 346 347 /* transmit data to the USB bus */ 348 datap = urb->transfer_buffer; 349 *datap++ = cmd->chanlist_len; 350 for (i = 0; i < cmd->chanlist_len; i++) { 351 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 352 unsigned short val; 353 354 if (!comedi_buf_read_samples(s, &val, 1)) { 355 dev_err(dev->class_dev, "buffer underflow\n"); 356 async->events |= COMEDI_CB_OVERFLOW; 357 return; 358 } 359 360 *datap++ = val; 361 *datap++ = chan; 362 s->readback[chan] = val; 363 } 364 } 365 366 /* if command is still running, resubmit urb */ 367 if (!(async->events & COMEDI_CB_CANCEL_MASK)) { 368 urb->transfer_buffer_length = SIZEOUTBUF; 369 urb->dev = comedi_to_usb_dev(dev); 370 urb->status = 0; 371 urb->interval = 1; /* (u)frames */ 372 urb->number_of_packets = 1; 373 urb->iso_frame_desc[0].offset = 0; 374 urb->iso_frame_desc[0].length = SIZEOUTBUF; 375 urb->iso_frame_desc[0].status = 0; 376 ret = usb_submit_urb(urb, GFP_ATOMIC); 377 if (ret < 0) { 378 dev_err(dev->class_dev, "urb resubmit failed (%d)\n", 379 ret); 380 if (ret == -EL2NSYNC) 381 dev_err(dev->class_dev, 382 "buggy USB host controller or bug in IRQ handler\n"); 383 async->events |= COMEDI_CB_ERROR; 384 } 385 } 386} 387 388static void usbduxsigma_ao_urb_complete(struct urb *urb) 389{ 390 struct comedi_device *dev = urb->context; 391 struct usbduxsigma_private *devpriv = dev->private; 392 struct comedi_subdevice *s = dev->write_subdev; 393 struct comedi_async *async = s->async; 394 395 /* exit if not running a command, do not resubmit urb */ 396 if (!devpriv->ao_cmd_running) 397 return; 398 399 switch (urb->status) { 400 case 0: 401 usbduxsigma_ao_handle_urb(dev, s, urb); 402 break; 403 404 case -ECONNRESET: 405 case -ENOENT: 406 case -ESHUTDOWN: 407 case -ECONNABORTED: 408 /* happens after an unlink command */ 409 async->events |= COMEDI_CB_ERROR; 410 break; 411 412 default: 413 /* a real error */ 414 dev_err(dev->class_dev, "non-zero urb status (%d)\n", 415 urb->status); 416 async->events |= COMEDI_CB_ERROR; 417 break; 418 } 419 420 /* 421 * comedi_handle_events() cannot be used in this driver. The (*cancel) 422 * operation would unlink the urb. 423 */ 424 if (async->events & COMEDI_CB_CANCEL_MASK) 425 usbduxsigma_ao_stop(dev, 0); 426 427 comedi_event(dev, s); 428} 429 430static int usbduxsigma_submit_urbs(struct comedi_device *dev, 431 struct urb **urbs, int num_urbs, 432 int input_urb) 433{ 434 struct usb_device *usb = comedi_to_usb_dev(dev); 435 struct urb *urb; 436 int ret; 437 int i; 438 439 /* Submit all URBs and start the transfer on the bus */ 440 for (i = 0; i < num_urbs; i++) { 441 urb = urbs[i]; 442 443 /* in case of a resubmission after an unlink... */ 444 if (input_urb) 445 urb->interval = 1; 446 urb->context = dev; 447 urb->dev = usb; 448 urb->status = 0; 449 urb->transfer_flags = URB_ISO_ASAP; 450 451 ret = usb_submit_urb(urb, GFP_ATOMIC); 452 if (ret) 453 return ret; 454 } 455 return 0; 456} 457 458static int usbduxsigma_chans_to_interval(int num_chan) 459{ 460 if (num_chan <= 2) 461 return 2; /* 4kHz */ 462 if (num_chan <= 8) 463 return 4; /* 2kHz */ 464 return 8; /* 1kHz */ 465} 466 467static int usbduxsigma_ai_cmdtest(struct comedi_device *dev, 468 struct comedi_subdevice *s, 469 struct comedi_cmd *cmd) 470{ 471 struct usbduxsigma_private *devpriv = dev->private; 472 int high_speed = devpriv->high_speed; 473 int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len); 474 unsigned int tmp; 475 int err = 0; 476 477 /* Step 1 : check if triggers are trivially valid */ 478 479 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); 480 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); 481 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); 482 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 483 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 484 485 if (err) 486 return 1; 487 488 /* Step 2a : make sure trigger sources are unique */ 489 490 err |= comedi_check_trigger_is_unique(cmd->start_src); 491 err |= comedi_check_trigger_is_unique(cmd->stop_src); 492 493 /* Step 2b : and mutually compatible */ 494 495 if (err) 496 return 2; 497 498 /* Step 3: check if arguments are trivially valid */ 499 500 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 501 502 if (high_speed) { 503 /* 504 * In high speed mode microframes are possible. 505 * However, during one microframe we can roughly 506 * sample two channels. Thus, the more channels 507 * are in the channel list the more time we need. 508 */ 509 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 510 (125000 * interval)); 511 } else { 512 /* full speed */ 513 /* 1kHz scans every USB frame */ 514 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 515 1000000); 516 } 517 518 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 519 cmd->chanlist_len); 520 521 if (cmd->stop_src == TRIG_COUNT) 522 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 523 else /* TRIG_NONE */ 524 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 525 526 if (err) 527 return 3; 528 529 /* Step 4: fix up any arguments */ 530 531 tmp = rounddown(cmd->scan_begin_arg, high_speed ? 125000 : 1000000); 532 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp); 533 534 if (err) 535 return 4; 536 537 return 0; 538} 539 540/* 541 * creates the ADC command for the MAX1271 542 * range is the range value from comedi 543 */ 544static void create_adc_command(unsigned int chan, 545 u8 *muxsg0, u8 *muxsg1) 546{ 547 if (chan < 8) 548 (*muxsg0) = (*muxsg0) | (1 << chan); 549 else if (chan < 16) 550 (*muxsg1) = (*muxsg1) | (1 << (chan - 8)); 551} 552 553static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type) 554{ 555 struct usb_device *usb = comedi_to_usb_dev(dev); 556 struct usbduxsigma_private *devpriv = dev->private; 557 int nsent; 558 559 devpriv->dux_commands[0] = cmd_type; 560 561 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1), 562 devpriv->dux_commands, SIZEOFDUXBUFFER, 563 &nsent, BULK_TIMEOUT); 564} 565 566static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command) 567{ 568 struct usb_device *usb = comedi_to_usb_dev(dev); 569 struct usbduxsigma_private *devpriv = dev->private; 570 int nrec; 571 int ret; 572 int i; 573 574 for (i = 0; i < RETRIES; i++) { 575 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8), 576 devpriv->insn_buf, SIZEINSNBUF, 577 &nrec, BULK_TIMEOUT); 578 if (ret < 0) 579 return ret; 580 581 if (devpriv->insn_buf[0] == command) 582 return 0; 583 } 584 /* 585 * This is only reached if the data has been requested a 586 * couple of times and the command was not received. 587 */ 588 return -EFAULT; 589} 590 591static int usbduxsigma_ai_inttrig(struct comedi_device *dev, 592 struct comedi_subdevice *s, 593 unsigned int trig_num) 594{ 595 struct usbduxsigma_private *devpriv = dev->private; 596 struct comedi_cmd *cmd = &s->async->cmd; 597 int ret; 598 599 if (trig_num != cmd->start_arg) 600 return -EINVAL; 601 602 mutex_lock(&devpriv->mut); 603 if (!devpriv->ai_cmd_running) { 604 devpriv->ai_cmd_running = 1; 605 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs, 606 devpriv->n_ai_urbs, 1); 607 if (ret < 0) { 608 devpriv->ai_cmd_running = 0; 609 mutex_unlock(&devpriv->mut); 610 return ret; 611 } 612 s->async->inttrig = NULL; 613 } 614 mutex_unlock(&devpriv->mut); 615 616 return 1; 617} 618 619static int usbduxsigma_ai_cmd(struct comedi_device *dev, 620 struct comedi_subdevice *s) 621{ 622 struct usbduxsigma_private *devpriv = dev->private; 623 struct comedi_cmd *cmd = &s->async->cmd; 624 unsigned int len = cmd->chanlist_len; 625 u8 muxsg0 = 0; 626 u8 muxsg1 = 0; 627 u8 sysred = 0; 628 int ret; 629 int i; 630 631 mutex_lock(&devpriv->mut); 632 633 if (devpriv->high_speed) { 634 /* 635 * every 2 channels get a time window of 125us. Thus, if we 636 * sample all 16 channels we need 1ms. If we sample only one 637 * channel we need only 125us 638 */ 639 unsigned int interval = usbduxsigma_chans_to_interval(len); 640 641 devpriv->ai_interval = interval; 642 devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval); 643 } else { 644 /* interval always 1ms */ 645 devpriv->ai_interval = 1; 646 devpriv->ai_timer = cmd->scan_begin_arg / 1000000; 647 } 648 649 for (i = 0; i < len; i++) { 650 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 651 652 create_adc_command(chan, &muxsg0, &muxsg1); 653 } 654 655 devpriv->dux_commands[1] = devpriv->ai_interval; 656 devpriv->dux_commands[2] = len; /* num channels per time step */ 657 devpriv->dux_commands[3] = 0x12; /* CONFIG0 */ 658 devpriv->dux_commands[4] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */ 659 devpriv->dux_commands[5] = 0x00; /* CONFIG3: diff. channels off */ 660 devpriv->dux_commands[6] = muxsg0; 661 devpriv->dux_commands[7] = muxsg1; 662 devpriv->dux_commands[8] = sysred; 663 664 ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD); 665 if (ret < 0) { 666 mutex_unlock(&devpriv->mut); 667 return ret; 668 } 669 670 devpriv->ai_counter = devpriv->ai_timer; 671 672 if (cmd->start_src == TRIG_NOW) { 673 /* enable this acquisition operation */ 674 devpriv->ai_cmd_running = 1; 675 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs, 676 devpriv->n_ai_urbs, 1); 677 if (ret < 0) { 678 devpriv->ai_cmd_running = 0; 679 mutex_unlock(&devpriv->mut); 680 return ret; 681 } 682 s->async->inttrig = NULL; 683 } else { /* TRIG_INT */ 684 s->async->inttrig = usbduxsigma_ai_inttrig; 685 } 686 687 mutex_unlock(&devpriv->mut); 688 689 return 0; 690} 691 692static int usbduxsigma_ai_insn_read(struct comedi_device *dev, 693 struct comedi_subdevice *s, 694 struct comedi_insn *insn, 695 unsigned int *data) 696{ 697 struct usbduxsigma_private *devpriv = dev->private; 698 unsigned int chan = CR_CHAN(insn->chanspec); 699 u8 muxsg0 = 0; 700 u8 muxsg1 = 0; 701 u8 sysred = 0; 702 int ret; 703 int i; 704 705 mutex_lock(&devpriv->mut); 706 if (devpriv->ai_cmd_running) { 707 mutex_unlock(&devpriv->mut); 708 return -EBUSY; 709 } 710 711 create_adc_command(chan, &muxsg0, &muxsg1); 712 713 /* Mode 0 is used to get a single conversion on demand */ 714 devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */ 715 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */ 716 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */ 717 devpriv->dux_commands[4] = muxsg0; 718 devpriv->dux_commands[5] = muxsg1; 719 devpriv->dux_commands[6] = sysred; 720 721 /* adc commands */ 722 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD); 723 if (ret < 0) { 724 mutex_unlock(&devpriv->mut); 725 return ret; 726 } 727 728 for (i = 0; i < insn->n; i++) { 729 u32 val; 730 731 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD); 732 if (ret < 0) { 733 mutex_unlock(&devpriv->mut); 734 return ret; 735 } 736 737 /* 32 bits big endian from the A/D converter */ 738 val = be32_to_cpu(get_unaligned((__be32 739 *)(devpriv->insn_buf + 1))); 740 val &= 0x00ffffff; /* strip status byte */ 741 data[i] = comedi_offset_munge(s, val); 742 } 743 mutex_unlock(&devpriv->mut); 744 745 return insn->n; 746} 747 748static int usbduxsigma_ao_insn_read(struct comedi_device *dev, 749 struct comedi_subdevice *s, 750 struct comedi_insn *insn, 751 unsigned int *data) 752{ 753 struct usbduxsigma_private *devpriv = dev->private; 754 int ret; 755 756 mutex_lock(&devpriv->mut); 757 ret = comedi_readback_insn_read(dev, s, insn, data); 758 mutex_unlock(&devpriv->mut); 759 760 return ret; 761} 762 763static int usbduxsigma_ao_insn_write(struct comedi_device *dev, 764 struct comedi_subdevice *s, 765 struct comedi_insn *insn, 766 unsigned int *data) 767{ 768 struct usbduxsigma_private *devpriv = dev->private; 769 unsigned int chan = CR_CHAN(insn->chanspec); 770 int ret; 771 int i; 772 773 mutex_lock(&devpriv->mut); 774 if (devpriv->ao_cmd_running) { 775 mutex_unlock(&devpriv->mut); 776 return -EBUSY; 777 } 778 779 for (i = 0; i < insn->n; i++) { 780 devpriv->dux_commands[1] = 1; /* num channels */ 781 devpriv->dux_commands[2] = data[i]; /* value */ 782 devpriv->dux_commands[3] = chan; /* channel number */ 783 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD); 784 if (ret < 0) { 785 mutex_unlock(&devpriv->mut); 786 return ret; 787 } 788 s->readback[chan] = data[i]; 789 } 790 mutex_unlock(&devpriv->mut); 791 792 return insn->n; 793} 794 795static int usbduxsigma_ao_inttrig(struct comedi_device *dev, 796 struct comedi_subdevice *s, 797 unsigned int trig_num) 798{ 799 struct usbduxsigma_private *devpriv = dev->private; 800 struct comedi_cmd *cmd = &s->async->cmd; 801 int ret; 802 803 if (trig_num != cmd->start_arg) 804 return -EINVAL; 805 806 mutex_lock(&devpriv->mut); 807 if (!devpriv->ao_cmd_running) { 808 devpriv->ao_cmd_running = 1; 809 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs, 810 devpriv->n_ao_urbs, 0); 811 if (ret < 0) { 812 devpriv->ao_cmd_running = 0; 813 mutex_unlock(&devpriv->mut); 814 return ret; 815 } 816 s->async->inttrig = NULL; 817 } 818 mutex_unlock(&devpriv->mut); 819 820 return 1; 821} 822 823static int usbduxsigma_ao_cmdtest(struct comedi_device *dev, 824 struct comedi_subdevice *s, 825 struct comedi_cmd *cmd) 826{ 827 struct usbduxsigma_private *devpriv = dev->private; 828 unsigned int tmp; 829 int err = 0; 830 831 /* Step 1 : check if triggers are trivially valid */ 832 833 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); 834 835 /* 836 * For now, always use "scan" timing with all channels updated at once 837 * (cmd->scan_begin_src == TRIG_TIMER, cmd->convert_src == TRIG_NOW). 838 * 839 * In a future version, "convert" timing with channels updated 840 * indivually may be supported in high speed mode 841 * (cmd->scan_begin_src == TRIG_FOLLOW, cmd->convert_src == TRIG_TIMER). 842 */ 843 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER); 844 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); 845 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 846 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 847 848 if (err) { 849 mutex_unlock(&devpriv->mut); 850 return 1; 851 } 852 853 /* Step 2a : make sure trigger sources are unique */ 854 855 err |= comedi_check_trigger_is_unique(cmd->start_src); 856 err |= comedi_check_trigger_is_unique(cmd->stop_src); 857 858 /* Step 2b : and mutually compatible */ 859 860 if (err) 861 return 2; 862 863 /* Step 3: check if arguments are trivially valid */ 864 865 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 866 867 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000); 868 869 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 870 cmd->chanlist_len); 871 872 if (cmd->stop_src == TRIG_COUNT) 873 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 874 else /* TRIG_NONE */ 875 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 876 877 if (err) 878 return 3; 879 880 /* Step 4: fix up any arguments */ 881 882 tmp = rounddown(cmd->scan_begin_arg, 1000000); 883 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp); 884 885 if (err) 886 return 4; 887 888 return 0; 889} 890 891static int usbduxsigma_ao_cmd(struct comedi_device *dev, 892 struct comedi_subdevice *s) 893{ 894 struct usbduxsigma_private *devpriv = dev->private; 895 struct comedi_cmd *cmd = &s->async->cmd; 896 int ret; 897 898 mutex_lock(&devpriv->mut); 899 900 /* 901 * For now, only "scan" timing is supported. A future version may 902 * support "convert" timing in high speed mode. 903 * 904 * Timing of the scan: every 1ms all channels updated at once. 905 */ 906 devpriv->ao_timer = cmd->scan_begin_arg / 1000000; 907 908 devpriv->ao_counter = devpriv->ao_timer; 909 910 if (cmd->start_src == TRIG_NOW) { 911 /* enable this acquisition operation */ 912 devpriv->ao_cmd_running = 1; 913 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs, 914 devpriv->n_ao_urbs, 0); 915 if (ret < 0) { 916 devpriv->ao_cmd_running = 0; 917 mutex_unlock(&devpriv->mut); 918 return ret; 919 } 920 s->async->inttrig = NULL; 921 } else { /* TRIG_INT */ 922 s->async->inttrig = usbduxsigma_ao_inttrig; 923 } 924 925 mutex_unlock(&devpriv->mut); 926 927 return 0; 928} 929 930static int usbduxsigma_dio_insn_config(struct comedi_device *dev, 931 struct comedi_subdevice *s, 932 struct comedi_insn *insn, 933 unsigned int *data) 934{ 935 int ret; 936 937 ret = comedi_dio_insn_config(dev, s, insn, data, 0); 938 if (ret) 939 return ret; 940 941 /* 942 * We don't tell the firmware here as it would take 8 frames 943 * to submit the information. We do it in the (*insn_bits). 944 */ 945 return insn->n; 946} 947 948static int usbduxsigma_dio_insn_bits(struct comedi_device *dev, 949 struct comedi_subdevice *s, 950 struct comedi_insn *insn, 951 unsigned int *data) 952{ 953 struct usbduxsigma_private *devpriv = dev->private; 954 int ret; 955 956 mutex_lock(&devpriv->mut); 957 958 comedi_dio_update_state(s, data); 959 960 /* Always update the hardware. See the (*insn_config). */ 961 devpriv->dux_commands[1] = s->io_bits & 0xff; 962 devpriv->dux_commands[4] = s->state & 0xff; 963 devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff; 964 devpriv->dux_commands[5] = (s->state >> 8) & 0xff; 965 devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff; 966 devpriv->dux_commands[6] = (s->state >> 16) & 0xff; 967 968 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD); 969 if (ret < 0) 970 goto done; 971 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD); 972 if (ret < 0) 973 goto done; 974 975 s->state = devpriv->insn_buf[1] | 976 (devpriv->insn_buf[2] << 8) | 977 (devpriv->insn_buf[3] << 16); 978 979 data[1] = s->state; 980 ret = insn->n; 981 982done: 983 mutex_unlock(&devpriv->mut); 984 985 return ret; 986} 987 988static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink) 989{ 990 struct usbduxsigma_private *devpriv = dev->private; 991 992 if (do_unlink) { 993 if (devpriv->pwm_urb) 994 usb_kill_urb(devpriv->pwm_urb); 995 } 996 997 devpriv->pwm_cmd_running = 0; 998} 999 1000static int usbduxsigma_pwm_cancel(struct comedi_device *dev, 1001 struct comedi_subdevice *s) 1002{ 1003 struct usbduxsigma_private *devpriv = dev->private; 1004 1005 /* unlink only if it is really running */ 1006 usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running); 1007 1008 return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD); 1009} 1010 1011static void usbduxsigma_pwm_urb_complete(struct urb *urb) 1012{ 1013 struct comedi_device *dev = urb->context; 1014 struct usbduxsigma_private *devpriv = dev->private; 1015 int ret; 1016 1017 switch (urb->status) { 1018 case 0: 1019 /* success */ 1020 break; 1021 1022 case -ECONNRESET: 1023 case -ENOENT: 1024 case -ESHUTDOWN: 1025 case -ECONNABORTED: 1026 /* happens after an unlink command */ 1027 if (devpriv->pwm_cmd_running) 1028 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */ 1029 return; 1030 1031 default: 1032 /* a real error */ 1033 if (devpriv->pwm_cmd_running) { 1034 dev_err(dev->class_dev, "non-zero urb status (%d)\n", 1035 urb->status); 1036 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */ 1037 } 1038 return; 1039 } 1040 1041 if (!devpriv->pwm_cmd_running) 1042 return; 1043 1044 urb->transfer_buffer_length = devpriv->pwm_buf_sz; 1045 urb->dev = comedi_to_usb_dev(dev); 1046 urb->status = 0; 1047 ret = usb_submit_urb(urb, GFP_ATOMIC); 1048 if (ret < 0) { 1049 dev_err(dev->class_dev, "urb resubmit failed (%d)\n", ret); 1050 if (ret == -EL2NSYNC) 1051 dev_err(dev->class_dev, 1052 "buggy USB host controller or bug in IRQ handler\n"); 1053 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */ 1054 } 1055} 1056 1057static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev) 1058{ 1059 struct usb_device *usb = comedi_to_usb_dev(dev); 1060 struct usbduxsigma_private *devpriv = dev->private; 1061 struct urb *urb = devpriv->pwm_urb; 1062 1063 /* in case of a resubmission after an unlink... */ 1064 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4), 1065 urb->transfer_buffer, devpriv->pwm_buf_sz, 1066 usbduxsigma_pwm_urb_complete, dev); 1067 1068 return usb_submit_urb(urb, GFP_ATOMIC); 1069} 1070 1071static int usbduxsigma_pwm_period(struct comedi_device *dev, 1072 struct comedi_subdevice *s, 1073 unsigned int period) 1074{ 1075 struct usbduxsigma_private *devpriv = dev->private; 1076 int fx2delay; 1077 1078 if (period < MIN_PWM_PERIOD) 1079 return -EAGAIN; 1080 1081 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6; 1082 if (fx2delay > 255) 1083 return -EAGAIN; 1084 1085 devpriv->pwm_delay = fx2delay; 1086 devpriv->pwm_period = period; 1087 return 0; 1088} 1089 1090static int usbduxsigma_pwm_start(struct comedi_device *dev, 1091 struct comedi_subdevice *s) 1092{ 1093 struct usbduxsigma_private *devpriv = dev->private; 1094 int ret; 1095 1096 if (devpriv->pwm_cmd_running) 1097 return 0; 1098 1099 devpriv->dux_commands[1] = devpriv->pwm_delay; 1100 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD); 1101 if (ret < 0) 1102 return ret; 1103 1104 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz); 1105 1106 devpriv->pwm_cmd_running = 1; 1107 ret = usbduxsigma_submit_pwm_urb(dev); 1108 if (ret < 0) { 1109 devpriv->pwm_cmd_running = 0; 1110 return ret; 1111 } 1112 1113 return 0; 1114} 1115 1116static void usbduxsigma_pwm_pattern(struct comedi_device *dev, 1117 struct comedi_subdevice *s, 1118 unsigned int chan, 1119 unsigned int value, 1120 unsigned int sign) 1121{ 1122 struct usbduxsigma_private *devpriv = dev->private; 1123 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */ 1124 char sgn_mask = (16 << chan); /* DIO bit for the sign */ 1125 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer); 1126 int szbuf = devpriv->pwm_buf_sz; 1127 int i; 1128 1129 for (i = 0; i < szbuf; i++) { 1130 char c = *buf; 1131 1132 c &= ~pwm_mask; 1133 if (i < value) 1134 c |= pwm_mask; 1135 if (!sign) 1136 c &= ~sgn_mask; 1137 else 1138 c |= sgn_mask; 1139 *buf++ = c; 1140 } 1141} 1142 1143static int usbduxsigma_pwm_write(struct comedi_device *dev, 1144 struct comedi_subdevice *s, 1145 struct comedi_insn *insn, 1146 unsigned int *data) 1147{ 1148 unsigned int chan = CR_CHAN(insn->chanspec); 1149 1150 /* 1151 * It doesn't make sense to support more than one value here 1152 * because it would just overwrite the PWM buffer. 1153 */ 1154 if (insn->n != 1) 1155 return -EINVAL; 1156 1157 /* 1158 * The sign is set via a special INSN only, this gives us 8 bits 1159 * for normal operation, sign is 0 by default. 1160 */ 1161 usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0); 1162 1163 return insn->n; 1164} 1165 1166static int usbduxsigma_pwm_config(struct comedi_device *dev, 1167 struct comedi_subdevice *s, 1168 struct comedi_insn *insn, 1169 unsigned int *data) 1170{ 1171 struct usbduxsigma_private *devpriv = dev->private; 1172 unsigned int chan = CR_CHAN(insn->chanspec); 1173 1174 switch (data[0]) { 1175 case INSN_CONFIG_ARM: 1176 /* 1177 * if not zero the PWM is limited to a certain time which is 1178 * not supported here 1179 */ 1180 if (data[1] != 0) 1181 return -EINVAL; 1182 return usbduxsigma_pwm_start(dev, s); 1183 case INSN_CONFIG_DISARM: 1184 return usbduxsigma_pwm_cancel(dev, s); 1185 case INSN_CONFIG_GET_PWM_STATUS: 1186 data[1] = devpriv->pwm_cmd_running; 1187 return 0; 1188 case INSN_CONFIG_PWM_SET_PERIOD: 1189 return usbduxsigma_pwm_period(dev, s, data[1]); 1190 case INSN_CONFIG_PWM_GET_PERIOD: 1191 data[1] = devpriv->pwm_period; 1192 return 0; 1193 case INSN_CONFIG_PWM_SET_H_BRIDGE: 1194 /* 1195 * data[1] = value 1196 * data[2] = sign (for a relay) 1197 */ 1198 usbduxsigma_pwm_pattern(dev, s, chan, data[1], (data[2] != 0)); 1199 return 0; 1200 case INSN_CONFIG_PWM_GET_H_BRIDGE: 1201 /* values are not kept in this driver, nothing to return */ 1202 return -EINVAL; 1203 } 1204 return -EINVAL; 1205} 1206 1207static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan) 1208{ 1209 struct comedi_subdevice *s = dev->read_subdev; 1210 struct usbduxsigma_private *devpriv = dev->private; 1211 u8 sysred; 1212 u32 val; 1213 int ret; 1214 1215 switch (chan) { 1216 default: 1217 case 0: 1218 sysred = 0; /* ADC zero */ 1219 break; 1220 case 1: 1221 sysred = 1; /* ADC offset */ 1222 break; 1223 case 2: 1224 sysred = 4; /* VCC */ 1225 break; 1226 case 3: 1227 sysred = 8; /* temperature */ 1228 break; 1229 case 4: 1230 sysred = 16; /* gain */ 1231 break; 1232 case 5: 1233 sysred = 32; /* ref */ 1234 break; 1235 } 1236 1237 devpriv->dux_commands[1] = 0x12; /* CONFIG0 */ 1238 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */ 1239 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */ 1240 devpriv->dux_commands[4] = 0; 1241 devpriv->dux_commands[5] = 0; 1242 devpriv->dux_commands[6] = sysred; 1243 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD); 1244 if (ret < 0) 1245 return ret; 1246 1247 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD); 1248 if (ret < 0) 1249 return ret; 1250 1251 /* 32 bits big endian from the A/D converter */ 1252 val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1))); 1253 val &= 0x00ffffff; /* strip status byte */ 1254 1255 return (int)comedi_offset_munge(s, val); 1256} 1257 1258static int usbduxsigma_firmware_upload(struct comedi_device *dev, 1259 const u8 *data, size_t size, 1260 unsigned long context) 1261{ 1262 struct usb_device *usb = comedi_to_usb_dev(dev); 1263 u8 *buf; 1264 u8 *tmp; 1265 int ret; 1266 1267 if (!data) 1268 return 0; 1269 1270 if (size > FIRMWARE_MAX_LEN) { 1271 dev_err(dev->class_dev, "firmware binary too large for FX2\n"); 1272 return -ENOMEM; 1273 } 1274 1275 /* we generate a local buffer for the firmware */ 1276 buf = kmemdup(data, size, GFP_KERNEL); 1277 if (!buf) 1278 return -ENOMEM; 1279 1280 /* we need a malloc'ed buffer for usb_control_msg() */ 1281 tmp = kmalloc(1, GFP_KERNEL); 1282 if (!tmp) { 1283 kfree(buf); 1284 return -ENOMEM; 1285 } 1286 1287 /* stop the current firmware on the device */ 1288 *tmp = 1; /* 7f92 to one */ 1289 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1290 USBDUXSUB_FIRMWARE, 1291 VENDOR_DIR_OUT, 1292 USBDUXSUB_CPUCS, 0x0000, 1293 tmp, 1, 1294 BULK_TIMEOUT); 1295 if (ret < 0) { 1296 dev_err(dev->class_dev, "can not stop firmware\n"); 1297 goto done; 1298 } 1299 1300 /* upload the new firmware to the device */ 1301 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1302 USBDUXSUB_FIRMWARE, 1303 VENDOR_DIR_OUT, 1304 0, 0x0000, 1305 buf, size, 1306 BULK_TIMEOUT); 1307 if (ret < 0) { 1308 dev_err(dev->class_dev, "firmware upload failed\n"); 1309 goto done; 1310 } 1311 1312 /* start the new firmware on the device */ 1313 *tmp = 0; /* 7f92 to zero */ 1314 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0), 1315 USBDUXSUB_FIRMWARE, 1316 VENDOR_DIR_OUT, 1317 USBDUXSUB_CPUCS, 0x0000, 1318 tmp, 1, 1319 BULK_TIMEOUT); 1320 if (ret < 0) 1321 dev_err(dev->class_dev, "can not start firmware\n"); 1322 1323done: 1324 kfree(tmp); 1325 kfree(buf); 1326 return ret; 1327} 1328 1329static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev) 1330{ 1331 struct usb_device *usb = comedi_to_usb_dev(dev); 1332 struct usbduxsigma_private *devpriv = dev->private; 1333 struct urb *urb; 1334 int i; 1335 1336 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); 1337 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL); 1338 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL); 1339 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL); 1340 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL); 1341 if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf || 1342 !devpriv->ai_urbs || !devpriv->ao_urbs) 1343 return -ENOMEM; 1344 1345 for (i = 0; i < devpriv->n_ai_urbs; i++) { 1346 /* one frame: 1ms */ 1347 urb = usb_alloc_urb(1, GFP_KERNEL); 1348 if (!urb) 1349 return -ENOMEM; 1350 devpriv->ai_urbs[i] = urb; 1351 urb->dev = usb; 1352 /* will be filled later with a pointer to the comedi-device */ 1353 /* and ONLY then the urb should be submitted */ 1354 urb->context = NULL; 1355 urb->pipe = usb_rcvisocpipe(usb, 6); 1356 urb->transfer_flags = URB_ISO_ASAP; 1357 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL); 1358 if (!urb->transfer_buffer) 1359 return -ENOMEM; 1360 urb->complete = usbduxsigma_ai_urb_complete; 1361 urb->number_of_packets = 1; 1362 urb->transfer_buffer_length = SIZEINBUF; 1363 urb->iso_frame_desc[0].offset = 0; 1364 urb->iso_frame_desc[0].length = SIZEINBUF; 1365 } 1366 1367 for (i = 0; i < devpriv->n_ao_urbs; i++) { 1368 /* one frame: 1ms */ 1369 urb = usb_alloc_urb(1, GFP_KERNEL); 1370 if (!urb) 1371 return -ENOMEM; 1372 devpriv->ao_urbs[i] = urb; 1373 urb->dev = usb; 1374 /* will be filled later with a pointer to the comedi-device */ 1375 /* and ONLY then the urb should be submitted */ 1376 urb->context = NULL; 1377 urb->pipe = usb_sndisocpipe(usb, 2); 1378 urb->transfer_flags = URB_ISO_ASAP; 1379 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); 1380 if (!urb->transfer_buffer) 1381 return -ENOMEM; 1382 urb->complete = usbduxsigma_ao_urb_complete; 1383 urb->number_of_packets = 1; 1384 urb->transfer_buffer_length = SIZEOUTBUF; 1385 urb->iso_frame_desc[0].offset = 0; 1386 urb->iso_frame_desc[0].length = SIZEOUTBUF; 1387 urb->interval = 1; /* (u)frames */ 1388 } 1389 1390 if (devpriv->pwm_buf_sz) { 1391 urb = usb_alloc_urb(0, GFP_KERNEL); 1392 if (!urb) 1393 return -ENOMEM; 1394 devpriv->pwm_urb = urb; 1395 1396 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, 1397 GFP_KERNEL); 1398 if (!urb->transfer_buffer) 1399 return -ENOMEM; 1400 } 1401 1402 return 0; 1403} 1404 1405static void usbduxsigma_free_usb_buffers(struct comedi_device *dev) 1406{ 1407 struct usbduxsigma_private *devpriv = dev->private; 1408 struct urb *urb; 1409 int i; 1410 1411 urb = devpriv->pwm_urb; 1412 if (urb) { 1413 kfree(urb->transfer_buffer); 1414 usb_free_urb(urb); 1415 } 1416 if (devpriv->ao_urbs) { 1417 for (i = 0; i < devpriv->n_ao_urbs; i++) { 1418 urb = devpriv->ao_urbs[i]; 1419 if (urb) { 1420 kfree(urb->transfer_buffer); 1421 usb_free_urb(urb); 1422 } 1423 } 1424 kfree(devpriv->ao_urbs); 1425 } 1426 if (devpriv->ai_urbs) { 1427 for (i = 0; i < devpriv->n_ai_urbs; i++) { 1428 urb = devpriv->ai_urbs[i]; 1429 if (urb) { 1430 kfree(urb->transfer_buffer); 1431 usb_free_urb(urb); 1432 } 1433 } 1434 kfree(devpriv->ai_urbs); 1435 } 1436 kfree(devpriv->insn_buf); 1437 kfree(devpriv->in_buf); 1438 kfree(devpriv->dux_commands); 1439} 1440 1441static int usbduxsigma_auto_attach(struct comedi_device *dev, 1442 unsigned long context_unused) 1443{ 1444 struct usb_interface *intf = comedi_to_usb_interface(dev); 1445 struct usb_device *usb = comedi_to_usb_dev(dev); 1446 struct usbduxsigma_private *devpriv; 1447 struct comedi_subdevice *s; 1448 int offset; 1449 int ret; 1450 1451 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1452 if (!devpriv) 1453 return -ENOMEM; 1454 1455 mutex_init(&devpriv->mut); 1456 1457 usb_set_intfdata(intf, devpriv); 1458 1459 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH); 1460 if (devpriv->high_speed) { 1461 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH; 1462 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH; 1463 devpriv->pwm_buf_sz = 512; 1464 } else { 1465 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL; 1466 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL; 1467 } 1468 1469 ret = usbduxsigma_alloc_usb_buffers(dev); 1470 if (ret) 1471 return ret; 1472 1473 /* setting to alternate setting 3: enabling iso ep and bulk ep. */ 1474 ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber, 1475 3); 1476 if (ret < 0) { 1477 dev_err(dev->class_dev, 1478 "could not set alternate setting 3 in high speed\n"); 1479 return ret; 1480 } 1481 1482 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE, 1483 usbduxsigma_firmware_upload, 0); 1484 if (ret) 1485 return ret; 1486 1487 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 4 : 3); 1488 if (ret) 1489 return ret; 1490 1491 /* Analog Input subdevice */ 1492 s = &dev->subdevices[0]; 1493 dev->read_subdev = s; 1494 s->type = COMEDI_SUBD_AI; 1495 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL; 1496 s->n_chan = NUMCHANNELS; 1497 s->len_chanlist = NUMCHANNELS; 1498 s->maxdata = 0x00ffffff; 1499 s->range_table = &usbduxsigma_ai_range; 1500 s->insn_read = usbduxsigma_ai_insn_read; 1501 s->do_cmdtest = usbduxsigma_ai_cmdtest; 1502 s->do_cmd = usbduxsigma_ai_cmd; 1503 s->cancel = usbduxsigma_ai_cancel; 1504 1505 /* Analog Output subdevice */ 1506 s = &dev->subdevices[1]; 1507 dev->write_subdev = s; 1508 s->type = COMEDI_SUBD_AO; 1509 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; 1510 s->n_chan = 4; 1511 s->len_chanlist = s->n_chan; 1512 s->maxdata = 0x00ff; 1513 s->range_table = &range_unipolar2_5; 1514 s->insn_write = usbduxsigma_ao_insn_write; 1515 s->insn_read = usbduxsigma_ao_insn_read; 1516 s->do_cmdtest = usbduxsigma_ao_cmdtest; 1517 s->do_cmd = usbduxsigma_ao_cmd; 1518 s->cancel = usbduxsigma_ao_cancel; 1519 1520 ret = comedi_alloc_subdev_readback(s); 1521 if (ret) 1522 return ret; 1523 1524 /* Digital I/O subdevice */ 1525 s = &dev->subdevices[2]; 1526 s->type = COMEDI_SUBD_DIO; 1527 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1528 s->n_chan = 24; 1529 s->maxdata = 1; 1530 s->range_table = &range_digital; 1531 s->insn_bits = usbduxsigma_dio_insn_bits; 1532 s->insn_config = usbduxsigma_dio_insn_config; 1533 1534 if (devpriv->high_speed) { 1535 /* Timer / pwm subdevice */ 1536 s = &dev->subdevices[3]; 1537 s->type = COMEDI_SUBD_PWM; 1538 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; 1539 s->n_chan = 8; 1540 s->maxdata = devpriv->pwm_buf_sz; 1541 s->insn_write = usbduxsigma_pwm_write; 1542 s->insn_config = usbduxsigma_pwm_config; 1543 1544 usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD); 1545 } 1546 1547 offset = usbduxsigma_getstatusinfo(dev, 0); 1548 if (offset < 0) { 1549 dev_err(dev->class_dev, 1550 "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n"); 1551 return offset; 1552 } 1553 1554 dev_info(dev->class_dev, "ADC_zero = %x\n", offset); 1555 1556 return 0; 1557} 1558 1559static void usbduxsigma_detach(struct comedi_device *dev) 1560{ 1561 struct usb_interface *intf = comedi_to_usb_interface(dev); 1562 struct usbduxsigma_private *devpriv = dev->private; 1563 1564 usb_set_intfdata(intf, NULL); 1565 1566 if (!devpriv) 1567 return; 1568 1569 mutex_lock(&devpriv->mut); 1570 1571 /* force unlink all urbs */ 1572 usbduxsigma_ai_stop(dev, 1); 1573 usbduxsigma_ao_stop(dev, 1); 1574 usbduxsigma_pwm_stop(dev, 1); 1575 1576 usbduxsigma_free_usb_buffers(dev); 1577 1578 mutex_unlock(&devpriv->mut); 1579 1580 mutex_destroy(&devpriv->mut); 1581} 1582 1583static struct comedi_driver usbduxsigma_driver = { 1584 .driver_name = "usbduxsigma", 1585 .module = THIS_MODULE, 1586 .auto_attach = usbduxsigma_auto_attach, 1587 .detach = usbduxsigma_detach, 1588}; 1589 1590static int usbduxsigma_usb_probe(struct usb_interface *intf, 1591 const struct usb_device_id *id) 1592{ 1593 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0); 1594} 1595 1596static const struct usb_device_id usbduxsigma_usb_table[] = { 1597 { USB_DEVICE(0x13d8, 0x0020) }, 1598 { USB_DEVICE(0x13d8, 0x0021) }, 1599 { USB_DEVICE(0x13d8, 0x0022) }, 1600 { } 1601}; 1602MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table); 1603 1604static struct usb_driver usbduxsigma_usb_driver = { 1605 .name = "usbduxsigma", 1606 .probe = usbduxsigma_usb_probe, 1607 .disconnect = comedi_usb_auto_unconfig, 1608 .id_table = usbduxsigma_usb_table, 1609}; 1610module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); 1611 1612MODULE_AUTHOR("Bernd Porr, mail@berndporr.me.uk"); 1613MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- mail@berndporr.me.uk"); 1614MODULE_LICENSE("GPL"); 1615MODULE_FIRMWARE(FIRMWARE); 1616