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