Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/staging/comedi/drivers/usbduxsigma.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us