Version:  2.0.40 2.2.26 2.4.37 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7

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

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

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