Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usbduxfast.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Bernd Porr, [email protected]
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 /*
20  * I must give credit here to Chris Baugher who
21  * wrote the driver for AT-MIO-16d. I used some parts of this
22  * driver. I also must give credits to David Brownell
23  * who supported me with the USB development.
24  *
25  * Bernd Porr
26  *
27  *
28  * Revision history:
29  * 0.9: Dropping the first data packet which seems to be from the last transfer.
30  * Buffer overflows in the FX2 are handed over to comedi.
31  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
32  * Added insn command basically for testing. Sample rate is
33  * 1MHz/16ch=62.5kHz
34  * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
35  * 0.99a: added external trigger.
36  * 1.00: added firmware kernel request to the driver which fixed
37  * udev coldplug problem
38  */
39 
40 #include <linux/kernel.h>
41 #include <linux/firmware.h>
42 #include <linux/module.h>
43 #include <linux/init.h>
44 #include <linux/slab.h>
45 #include <linux/input.h>
46 #include <linux/usb.h>
47 #include <linux/fcntl.h>
48 #include <linux/compiler.h>
49 #include "comedi_fc.h"
50 #include "../comedidev.h"
51 
52 /*
53  * timeout for the USB-transfer
54  */
55 #define EZTIMEOUT 30
56 
57 /*
58  * constants for "firmware" upload and download
59  */
60 #define FIRMWARE "usbduxfast_firmware.bin"
61 #define USBDUXFASTSUB_FIRMWARE 0xA0
62 #define VENDOR_DIR_IN 0xC0
63 #define VENDOR_DIR_OUT 0x40
64 
65 /*
66  * internal addresses of the 8051 processor
67  */
68 #define USBDUXFASTSUB_CPUCS 0xE600
69 
70 /*
71  * max lenghth of the transfer-buffer for software upload
72  */
73 #define TB_LEN 0x2000
74 
75 /*
76  * input endpoint number
77  */
78 #define BULKINEP 6
79 
80 /*
81  * endpoint for the A/D channellist: bulk OUT
82  */
83 #define CHANNELLISTEP 4
84 
85 /*
86  * number of channels
87  */
88 #define NUMCHANNELS 32
89 
90 /*
91  * size of the waveform descriptor
92  */
93 #define WAVESIZE 0x20
94 
95 /*
96  * size of one A/D value
97  */
98 #define SIZEADIN (sizeof(int16_t))
99 
100 /*
101  * size of the input-buffer IN BYTES
102  */
103 #define SIZEINBUF 512
104 
105 /*
106  * 16 bytes
107  */
108 #define SIZEINSNBUF 512
109 
110 /*
111  * size of the buffer for the dux commands in bytes
112  */
113 #define SIZEOFDUXBUFFER 256
114 
115 /*
116  * number of in-URBs which receive the data: min=5
117  */
118 #define NUMOFINBUFFERSHIGH 10
119 
120 /*
121  * total number of usbduxfast devices
122  */
123 #define NUMUSBDUXFAST 16
124 
125 /*
126  * analogue in subdevice
127  */
128 #define SUBDEV_AD 0
129 
130 /*
131  * min delay steps for more than one channel
132  * basically when the mux gives up ;-)
133  *
134  * steps at 30MHz in the FX2
135  */
136 #define MIN_SAMPLING_PERIOD 9
137 
138 /*
139  * max number of 1/30MHz delay steps
140  */
141 #define MAX_SAMPLING_PERIOD 500
142 
143 /*
144  * number of received packets to ignore before we start handing data
145  * over to comedi, it's quad buffering and we have to ignore 4 packets
146  */
147 #define PACKETS_TO_IGNORE 4
148 
149 /*
150  * comedi constants
151  */
152 static const struct comedi_lrange range_usbduxfast_ai_range = {
153  2, {BIP_RANGE(0.75), BIP_RANGE(0.5)}
154 };
155 
156 /*
157  * private structure of one subdevice
158  *
159  * this is the structure which holds all the data of this driver
160  * one sub device just now: A/D
161  */
163  int attached; /* is attached? */
164  int probed; /* is it associated with a subdevice? */
165  struct usb_device *usbdev; /* pointer to the usb-device */
166  struct urb *urbIn; /* BULK-transfer handling: urb */
168  int16_t *insnBuffer; /* input buffer for single insn */
169  int ifnum; /* interface number */
170  struct usb_interface *interface; /* interface structure */
171  /* comedi device for the interrupt context */
173  short int ai_cmd_running; /* asynchronous command is running */
174  short int ai_continous; /* continous acquisition */
175  long int ai_sample_count; /* number of samples to acquire */
176  uint8_t *dux_commands; /* commands */
177  int ignore; /* counter which ignores the first
178  buffers */
179  struct semaphore sem;
180 };
181 
182 /*
183  * The pointer to the private usb-data of the driver
184  * is also the private data for the comedi-device.
185  * This has to be global as the usb subsystem needs
186  * global variables. The other reason is that this
187  * structure must be there _before_ any comedi
188  * command is issued. The usb subsystem must be
189  * initialised before comedi can access it.
190  */
191 static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
192 
193 static DEFINE_SEMAPHORE(start_stop_sem);
194 
195 /*
196  * bulk transfers to usbduxfast
197  */
198 #define SENDADCOMMANDS 0
199 #define SENDINITEP6 1
200 
201 static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
202 {
203  int tmp, nsent;
204 
205  udfs->dux_commands[0] = cmd_type;
206 
207 #ifdef CONFIG_COMEDI_DEBUG
208  printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
209  udfs->comedidev->minor);
210  for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
211  printk(" %02x", udfs->dux_commands[tmp]);
212  printk("\n");
213 #endif
214 
215  tmp = usb_bulk_msg(udfs->usbdev,
216  usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
217  udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
218  if (tmp < 0)
219  printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
220  "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
221  return tmp;
222 }
223 
224 /*
225  * Stops the data acquision.
226  * It should be safe to call this function from any context.
227  */
228 static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
229 {
230  int j = 0;
231  int err = 0;
232 
233  if (udfs && udfs->urbIn) {
234  udfs->ai_cmd_running = 0;
235  /* waits until a running transfer is over */
236  usb_kill_urb(udfs->urbIn);
237  j = 0;
238  }
239 #ifdef CONFIG_COMEDI_DEBUG
240  printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
241 #endif
242  return err;
243 }
244 
245 /*
246  * This will stop a running acquisition operation.
247  * Is called from within this driver from both the
248  * interrupt context and from comedi.
249  */
250 static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink)
251 {
252  int ret = 0;
253 
254  if (!udfs) {
255  printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
256  return -EFAULT;
257  }
258 #ifdef CONFIG_COMEDI_DEBUG
259  printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
260 #endif
261 
262  udfs->ai_cmd_running = 0;
263 
264  if (do_unlink)
265  /* stop aquistion */
266  ret = usbduxfastsub_unlink_InURBs(udfs);
267 
268  return ret;
269 }
270 
271 /*
272  * This will cancel a running acquisition operation.
273  * This is called by comedi but never from inside the driver.
274  */
275 static int usbduxfast_ai_cancel(struct comedi_device *dev,
276  struct comedi_subdevice *s)
277 {
278  struct usbduxfastsub_s *udfs;
279  int ret;
280 
281  /* force unlink of all urbs */
282 #ifdef CONFIG_COMEDI_DEBUG
283  printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
284 #endif
285  udfs = dev->private;
286  if (!udfs) {
287  printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
288  return -EFAULT;
289  }
290  down(&udfs->sem);
291  if (!udfs->probed) {
292  up(&udfs->sem);
293  return -ENODEV;
294  }
295  /* unlink */
296  ret = usbduxfast_ai_stop(udfs, 1);
297  up(&udfs->sem);
298 
299  return ret;
300 }
301 
302 /*
303  * analogue IN
304  * interrupt service routine
305  */
306 static void usbduxfastsub_ai_Irq(struct urb *urb)
307 {
308  int n, err;
309  struct usbduxfastsub_s *udfs;
310  struct comedi_device *this_comedidev;
311  struct comedi_subdevice *s;
312  uint16_t *p;
313 
314  /* sanity checks - is the urb there? */
315  if (!urb) {
316  printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
317  "with urb=NULL!\n");
318  return;
319  }
320  /* the context variable points to the subdevice */
321  this_comedidev = urb->context;
322  if (!this_comedidev) {
323  printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
324  "pointer!\n");
325  return;
326  }
327  /* the private structure of the subdevice is usbduxfastsub_s */
328  udfs = this_comedidev->private;
329  if (!udfs) {
330  printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
331  "subdev is a NULL pointer!\n");
332  return;
333  }
334  /* are we running a command? */
335  if (unlikely(!udfs->ai_cmd_running)) {
336  /*
337  * not running a command
338  * do not continue execution if no asynchronous command
339  * is running in particular not resubmit
340  */
341  return;
342  }
343 
344  if (unlikely(!udfs->attached)) {
345  /* no comedi device there */
346  return;
347  }
348  /* subdevice which is the AD converter */
349  s = &this_comedidev->subdevices[SUBDEV_AD];
350 
351  /* first we test if something unusual has just happened */
352  switch (urb->status) {
353  case 0:
354  break;
355 
356  /*
357  * happens after an unlink command or when the device
358  * is plugged out
359  */
360  case -ECONNRESET:
361  case -ENOENT:
362  case -ESHUTDOWN:
363  case -ECONNABORTED:
364  /* tell this comedi */
365  s->async->events |= COMEDI_CB_EOA;
366  s->async->events |= COMEDI_CB_ERROR;
367  comedi_event(udfs->comedidev, s);
368  /* stop the transfer w/o unlink */
369  usbduxfast_ai_stop(udfs, 0);
370  return;
371 
372  default:
373  printk("comedi%d: usbduxfast: non-zero urb status received in "
374  "ai intr context: %d\n",
375  udfs->comedidev->minor, urb->status);
376  s->async->events |= COMEDI_CB_EOA;
377  s->async->events |= COMEDI_CB_ERROR;
378  comedi_event(udfs->comedidev, s);
379  usbduxfast_ai_stop(udfs, 0);
380  return;
381  }
382 
383  p = urb->transfer_buffer;
384  if (!udfs->ignore) {
385  if (!udfs->ai_continous) {
386  /* not continuous, fixed number of samples */
387  n = urb->actual_length / sizeof(uint16_t);
388  if (unlikely(udfs->ai_sample_count < n)) {
389  /*
390  * we have send only a fraction of the bytes
391  * received
392  */
394  urb->transfer_buffer,
395  udfs->ai_sample_count
396  * sizeof(uint16_t));
397  usbduxfast_ai_stop(udfs, 0);
398  /* tell comedi that the acquistion is over */
399  s->async->events |= COMEDI_CB_EOA;
400  comedi_event(udfs->comedidev, s);
401  return;
402  }
403  udfs->ai_sample_count -= n;
404  }
405  /* write the full buffer to comedi */
406  err = cfc_write_array_to_buffer(s, urb->transfer_buffer,
407  urb->actual_length);
408  if (unlikely(err == 0)) {
409  /* buffer overflow */
410  usbduxfast_ai_stop(udfs, 0);
411  return;
412  }
413 
414  /* tell comedi that data is there */
415  comedi_event(udfs->comedidev, s);
416 
417  } else {
418  /* ignore this packet */
419  udfs->ignore--;
420  }
421 
422  /*
423  * command is still running
424  * resubmit urb for BULK transfer
425  */
426  urb->dev = udfs->usbdev;
427  urb->status = 0;
428  err = usb_submit_urb(urb, GFP_ATOMIC);
429  if (err < 0) {
430  printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
431  udfs->comedidev->minor, err);
432  s->async->events |= COMEDI_CB_EOA;
433  s->async->events |= COMEDI_CB_ERROR;
434  comedi_event(udfs->comedidev, s);
435  usbduxfast_ai_stop(udfs, 0);
436  }
437 }
438 
439 static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
440 {
441  int ret;
442  unsigned char local_transfer_buffer[16];
443 
444  /* 7f92 to zero */
445  local_transfer_buffer[0] = 0;
446  /* bRequest, "Firmware" */
447  ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
449  VENDOR_DIR_OUT, /* bmRequestType */
450  USBDUXFASTSUB_CPUCS, /* Value */
451  0x0000, /* Index */
452  /* address of the transfer buffer */
453  local_transfer_buffer,
454  1, /* Length */
455  EZTIMEOUT); /* Timeout */
456  if (ret < 0) {
457  printk("comedi_: usbduxfast_: control msg failed (start)\n");
458  return ret;
459  }
460 
461  return 0;
462 }
463 
464 static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
465 {
466  int ret;
467  unsigned char local_transfer_buffer[16];
468 
469  /* 7f92 to one */
470  local_transfer_buffer[0] = 1;
471  /* bRequest, "Firmware" */
472  ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
474  VENDOR_DIR_OUT, /* bmRequestType */
475  USBDUXFASTSUB_CPUCS, /* Value */
476  0x0000, /* Index */
477  local_transfer_buffer, 1, /* Length */
478  EZTIMEOUT); /* Timeout */
479  if (ret < 0) {
480  printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
481  "(stop)\n");
482  return ret;
483  }
484 
485  return 0;
486 }
487 
488 static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
489  unsigned char *local_transfer_buffer,
490  unsigned int startAddr, unsigned int len)
491 {
492  int ret;
493 
494 #ifdef CONFIG_COMEDI_DEBUG
495  printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
496  printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
497  startAddr, local_transfer_buffer[0]);
498 #endif
499  /* brequest, firmware */
500  ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
502  VENDOR_DIR_OUT, /* bmRequestType */
503  startAddr, /* value */
504  0x0000, /* index */
505  /* our local safe buffer */
506  local_transfer_buffer,
507  len, /* length */
508  EZTIMEOUT); /* timeout */
509 
510 #ifdef CONFIG_COMEDI_DEBUG
511  printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
512 #endif
513 
514  if (ret < 0) {
515  printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
516  return ret;
517  }
518 
519  return 0;
520 }
521 
522 static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
523 {
524  int ret;
525 
526  if (!udfs)
527  return -EFAULT;
528 
529  usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
530  usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
531  udfs->transfer_buffer,
532  SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
533 
534 #ifdef CONFIG_COMEDI_DEBUG
535  printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
536  "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
537  udfs->urbIn->dev);
538 #endif
539  ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
540  if (ret) {
541  printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
542  " %d\n", ret);
543  return ret;
544  }
545  return 0;
546 }
547 
548 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
549  struct comedi_subdevice *s,
550  struct comedi_cmd *cmd)
551 {
552  struct usbduxfastsub_s *udfs = dev->private;
553  int err = 0;
554  long int steps, tmp;
555  int minSamplPer;
556 
557  if (!udfs->probed)
558  return -ENODEV;
559 
560 #ifdef CONFIG_COMEDI_DEBUG
561  printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
562  printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
563  "scan_begin_arg=%u\n",
564  dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
565 #endif
566  /* Step 1 : check if triggers are trivially valid */
567 
568  err |= cfc_check_trigger_src(&cmd->start_src,
570  err |= cfc_check_trigger_src(&cmd->scan_begin_src,
572  err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
573  err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
574  err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
575 
576  if (err)
577  return 1;
578 
579  /* Step 2a : make sure trigger sources are unique */
580 
581  err |= cfc_check_trigger_is_unique(cmd->start_src);
582  err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
583  err |= cfc_check_trigger_is_unique(cmd->convert_src);
584  err |= cfc_check_trigger_is_unique(cmd->stop_src);
585 
586  /* Step 2b : and mutually compatible */
587 
588  /* can't have external stop and start triggers at once */
589  if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
590  err |= -EINVAL;
591 
592  if (err)
593  return 2;
594 
595  /* step 3: make sure arguments are trivially compatible */
596 
597  if (cmd->start_src == TRIG_NOW && cmd->start_arg != 0) {
598  cmd->start_arg = 0;
599  err++;
600  }
601 
602  if (!cmd->chanlist_len)
603  err++;
604 
605  if (cmd->scan_end_arg != cmd->chanlist_len) {
606  cmd->scan_end_arg = cmd->chanlist_len;
607  err++;
608  }
609 
610  if (cmd->chanlist_len == 1)
611  minSamplPer = 1;
612  else
613  minSamplPer = MIN_SAMPLING_PERIOD;
614 
615  if (cmd->convert_src == TRIG_TIMER) {
616  steps = cmd->convert_arg * 30;
617  if (steps < (minSamplPer * 1000))
618  steps = minSamplPer * 1000;
619 
620  if (steps > (MAX_SAMPLING_PERIOD * 1000))
621  steps = MAX_SAMPLING_PERIOD * 1000;
622 
623  /* calc arg again */
624  tmp = steps / 30;
625  if (cmd->convert_arg != tmp) {
626  cmd->convert_arg = tmp;
627  err++;
628  }
629  }
630 
631  if (cmd->scan_begin_src == TRIG_TIMER)
632  err++;
633 
634  /* stop source */
635  switch (cmd->stop_src) {
636  case TRIG_COUNT:
637  if (!cmd->stop_arg) {
638  cmd->stop_arg = 1;
639  err++;
640  }
641  break;
642  case TRIG_NONE:
643  if (cmd->stop_arg != 0) {
644  cmd->stop_arg = 0;
645  err++;
646  }
647  break;
648  /*
649  * TRIG_EXT doesn't care since it doesn't trigger
650  * off a numbered channel
651  */
652  default:
653  break;
654  }
655 
656  if (err)
657  return 3;
658 
659  /* step 4: fix up any arguments */
660 
661  return 0;
662 
663 }
664 
665 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
666  struct comedi_subdevice *s,
667  unsigned int trignum)
668 {
669  int ret;
670  struct usbduxfastsub_s *udfs = dev->private;
671 
672  if (!udfs)
673  return -EFAULT;
674 
675  down(&udfs->sem);
676  if (!udfs->probed) {
677  up(&udfs->sem);
678  return -ENODEV;
679  }
680 #ifdef CONFIG_COMEDI_DEBUG
681  printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
682 #endif
683 
684  if (trignum != 0) {
685  printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
686  " trignum\n", dev->minor);
687  up(&udfs->sem);
688  return -EINVAL;
689  }
690  if (!udfs->ai_cmd_running) {
691  udfs->ai_cmd_running = 1;
692  ret = usbduxfastsub_submit_InURBs(udfs);
693  if (ret < 0) {
694  printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
695  "urbSubmit: err=%d\n", dev->minor, ret);
696  udfs->ai_cmd_running = 0;
697  up(&udfs->sem);
698  return ret;
699  }
700  s->async->inttrig = NULL;
701  } else {
702  printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
703  " running\n", dev->minor);
704  }
705  up(&udfs->sem);
706  return 1;
707 }
708 
709 /*
710  * offsets for the GPIF bytes
711  * the first byte is the command byte
712  */
713 #define LENBASE (1+0x00)
714 #define OPBASE (1+0x08)
715 #define OUTBASE (1+0x10)
716 #define LOGBASE (1+0x18)
717 
718 static int usbduxfast_ai_cmd(struct comedi_device *dev,
719  struct comedi_subdevice *s)
720 {
721  struct comedi_cmd *cmd = &s->async->cmd;
722  unsigned int chan, gain, rngmask = 0xff;
723  int i, j, ret;
724  struct usbduxfastsub_s *udfs;
725  int result;
726  long steps, steps_tmp;
727 
728 #ifdef CONFIG_COMEDI_DEBUG
729  printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
730 #endif
731  udfs = dev->private;
732  if (!udfs)
733  return -EFAULT;
734 
735  down(&udfs->sem);
736  if (!udfs->probed) {
737  up(&udfs->sem);
738  return -ENODEV;
739  }
740  if (udfs->ai_cmd_running) {
741  printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
742  " is running.\n", dev->minor);
743  up(&udfs->sem);
744  return -EBUSY;
745  }
746  /* set current channel of the running acquisition to zero */
747  s->async->cur_chan = 0;
748 
749  /*
750  * ignore the first buffers from the device if there
751  * is an error condition
752  */
753  udfs->ignore = PACKETS_TO_IGNORE;
754 
755  if (cmd->chanlist_len > 0) {
756  gain = CR_RANGE(cmd->chanlist[0]);
757  for (i = 0; i < cmd->chanlist_len; ++i) {
758  chan = CR_CHAN(cmd->chanlist[i]);
759  if (chan != i) {
760  printk(KERN_ERR "comedi%d: cmd is accepting "
761  "only consecutive channels.\n",
762  dev->minor);
763  up(&udfs->sem);
764  return -EINVAL;
765  }
766  if ((gain != CR_RANGE(cmd->chanlist[i]))
767  && (cmd->chanlist_len > 3)) {
768  printk(KERN_ERR "comedi%d: the gain must be"
769  " the same for all channels.\n",
770  dev->minor);
771  up(&udfs->sem);
772  return -EINVAL;
773  }
774  if (i >= NUMCHANNELS) {
775  printk(KERN_ERR "comedi%d: channel list too"
776  " long\n", dev->minor);
777  break;
778  }
779  }
780  }
781  steps = 0;
782  if (cmd->scan_begin_src == TRIG_TIMER) {
783  printk(KERN_ERR "comedi%d: usbduxfast: "
784  "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
785  up(&udfs->sem);
786  return -EINVAL;
787  }
788  if (cmd->convert_src == TRIG_TIMER)
789  steps = (cmd->convert_arg * 30) / 1000;
790 
791  if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
792  printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
793  "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
794  dev->minor, steps, cmd->scan_begin_arg);
795  up(&udfs->sem);
796  return -EINVAL;
797  }
798  if (steps > MAX_SAMPLING_PERIOD) {
799  printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
800  "too low.\n", dev->minor);
801  up(&udfs->sem);
802  return -EINVAL;
803  }
804  if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
805  && (cmd->chanlist_len != 16)) {
806  printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
807  " with 1 or 16 channels possible.\n", dev->minor);
808  up(&udfs->sem);
809  return -EINVAL;
810  }
811 #ifdef CONFIG_COMEDI_DEBUG
812  printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
813  dev->minor, steps, cmd->convert_arg);
814 #endif
815 
816  switch (cmd->chanlist_len) {
817  case 1:
818  /*
819  * one channel
820  */
821 
822  if (CR_RANGE(cmd->chanlist[0]) > 0)
823  rngmask = 0xff - 0x04;
824  else
825  rngmask = 0xff;
826 
827  /*
828  * for external trigger: looping in this state until
829  * the RDY0 pin becomes zero
830  */
831 
832  /* we loop here until ready has been set */
833  if (cmd->start_src == TRIG_EXT) {
834  /* branch back to state 0 */
835  udfs->dux_commands[LENBASE + 0] = 0x01;
836  /* deceision state w/o data */
837  udfs->dux_commands[OPBASE + 0] = 0x01;
838  udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
839  /* RDY0 = 0 */
840  udfs->dux_commands[LOGBASE + 0] = 0x00;
841  } else { /* we just proceed to state 1 */
842  udfs->dux_commands[LENBASE + 0] = 1;
843  udfs->dux_commands[OPBASE + 0] = 0;
844  udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
845  udfs->dux_commands[LOGBASE + 0] = 0;
846  }
847 
848  if (steps < MIN_SAMPLING_PERIOD) {
849  /* for fast single channel aqu without mux */
850  if (steps <= 1) {
851  /*
852  * we just stay here at state 1 and rexecute
853  * the same state this gives us 30MHz sampling
854  * rate
855  */
856 
857  /* branch back to state 1 */
858  udfs->dux_commands[LENBASE + 1] = 0x89;
859  /* deceision state with data */
860  udfs->dux_commands[OPBASE + 1] = 0x03;
861  udfs->dux_commands[OUTBASE + 1] =
862  0xFF & rngmask;
863  /* doesn't matter */
864  udfs->dux_commands[LOGBASE + 1] = 0xFF;
865  } else {
866  /*
867  * we loop through two states: data and delay
868  * max rate is 15MHz
869  */
870  udfs->dux_commands[LENBASE + 1] = steps - 1;
871  /* data */
872  udfs->dux_commands[OPBASE + 1] = 0x02;
873  udfs->dux_commands[OUTBASE + 1] =
874  0xFF & rngmask;
875  /* doesn't matter */
876  udfs->dux_commands[LOGBASE + 1] = 0;
877  /* branch back to state 1 */
878  udfs->dux_commands[LENBASE + 2] = 0x09;
879  /* deceision state w/o data */
880  udfs->dux_commands[OPBASE + 2] = 0x01;
881  udfs->dux_commands[OUTBASE + 2] =
882  0xFF & rngmask;
883  /* doesn't matter */
884  udfs->dux_commands[LOGBASE + 2] = 0xFF;
885  }
886  } else {
887  /*
888  * we loop through 3 states: 2x delay and 1x data
889  * this gives a min sampling rate of 60kHz
890  */
891 
892  /* we have 1 state with duration 1 */
893  steps = steps - 1;
894 
895  /* do the first part of the delay */
896  udfs->dux_commands[LENBASE + 1] = steps / 2;
897  udfs->dux_commands[OPBASE + 1] = 0;
898  udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
899  udfs->dux_commands[LOGBASE + 1] = 0;
900 
901  /* and the second part */
902  udfs->dux_commands[LENBASE + 2] = steps - steps / 2;
903  udfs->dux_commands[OPBASE + 2] = 0;
904  udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
905  udfs->dux_commands[LOGBASE + 2] = 0;
906 
907  /* get the data and branch back */
908 
909  /* branch back to state 1 */
910  udfs->dux_commands[LENBASE + 3] = 0x09;
911  /* deceision state w data */
912  udfs->dux_commands[OPBASE + 3] = 0x03;
913  udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
914  /* doesn't matter */
915  udfs->dux_commands[LOGBASE + 3] = 0xFF;
916  }
917  break;
918 
919  case 2:
920  /*
921  * two channels
922  * commit data to the FIFO
923  */
924 
925  if (CR_RANGE(cmd->chanlist[0]) > 0)
926  rngmask = 0xff - 0x04;
927  else
928  rngmask = 0xff;
929 
930  udfs->dux_commands[LENBASE + 0] = 1;
931  /* data */
932  udfs->dux_commands[OPBASE + 0] = 0x02;
933  udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
934  udfs->dux_commands[LOGBASE + 0] = 0;
935 
936  /* we have 1 state with duration 1: state 0 */
937  steps_tmp = steps - 1;
938 
939  if (CR_RANGE(cmd->chanlist[1]) > 0)
940  rngmask = 0xff - 0x04;
941  else
942  rngmask = 0xff;
943 
944  /* do the first part of the delay */
945  udfs->dux_commands[LENBASE + 1] = steps_tmp / 2;
946  udfs->dux_commands[OPBASE + 1] = 0;
947  /* count */
948  udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
949  udfs->dux_commands[LOGBASE + 1] = 0;
950 
951  /* and the second part */
952  udfs->dux_commands[LENBASE + 2] = steps_tmp - steps_tmp / 2;
953  udfs->dux_commands[OPBASE + 2] = 0;
954  udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
955  udfs->dux_commands[LOGBASE + 2] = 0;
956 
957  udfs->dux_commands[LENBASE + 3] = 1;
958  /* data */
959  udfs->dux_commands[OPBASE + 3] = 0x02;
960  udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
961  udfs->dux_commands[LOGBASE + 3] = 0;
962 
963  /*
964  * we have 2 states with duration 1: step 6 and
965  * the IDLE state
966  */
967  steps_tmp = steps - 2;
968 
969  if (CR_RANGE(cmd->chanlist[0]) > 0)
970  rngmask = 0xff - 0x04;
971  else
972  rngmask = 0xff;
973 
974  /* do the first part of the delay */
975  udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
976  udfs->dux_commands[OPBASE + 4] = 0;
977  /* reset */
978  udfs->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask;
979  udfs->dux_commands[LOGBASE + 4] = 0;
980 
981  /* and the second part */
982  udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
983  udfs->dux_commands[OPBASE + 5] = 0;
984  udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
985  udfs->dux_commands[LOGBASE + 5] = 0;
986 
987  udfs->dux_commands[LENBASE + 6] = 1;
988  udfs->dux_commands[OPBASE + 6] = 0;
989  udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
990  udfs->dux_commands[LOGBASE + 6] = 0;
991  break;
992 
993  case 3:
994  /*
995  * three channels
996  */
997  for (j = 0; j < 1; j++) {
998  if (CR_RANGE(cmd->chanlist[j]) > 0)
999  rngmask = 0xff - 0x04;
1000  else
1001  rngmask = 0xff;
1002  /*
1003  * commit data to the FIFO and do the first part
1004  * of the delay
1005  */
1006  udfs->dux_commands[LENBASE + j * 2] = steps / 2;
1007  /* data */
1008  udfs->dux_commands[OPBASE + j * 2] = 0x02;
1009  /* no change */
1010  udfs->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask;
1011  udfs->dux_commands[LOGBASE + j * 2] = 0;
1012 
1013  if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
1014  rngmask = 0xff - 0x04;
1015  else
1016  rngmask = 0xff;
1017 
1018  /* do the second part of the delay */
1019  udfs->dux_commands[LENBASE + j * 2 + 1] =
1020  steps - steps / 2;
1021  /* no data */
1022  udfs->dux_commands[OPBASE + j * 2 + 1] = 0;
1023  /* count */
1024  udfs->dux_commands[OUTBASE + j * 2 + 1] =
1025  0xFE & rngmask;
1026  udfs->dux_commands[LOGBASE + j * 2 + 1] = 0;
1027  }
1028 
1029  /* 2 steps with duration 1: the idele step and step 6: */
1030  steps_tmp = steps - 2;
1031 
1032  /* commit data to the FIFO and do the first part of the delay */
1033  udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
1034  /* data */
1035  udfs->dux_commands[OPBASE + 4] = 0x02;
1036  udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
1037  udfs->dux_commands[LOGBASE + 4] = 0;
1038 
1039  if (CR_RANGE(cmd->chanlist[0]) > 0)
1040  rngmask = 0xff - 0x04;
1041  else
1042  rngmask = 0xff;
1043 
1044  /* do the second part of the delay */
1045  udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
1046  /* no data */
1047  udfs->dux_commands[OPBASE + 5] = 0;
1048  /* reset */
1049  udfs->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask;
1050  udfs->dux_commands[LOGBASE + 5] = 0;
1051 
1052  udfs->dux_commands[LENBASE + 6] = 1;
1053  udfs->dux_commands[OPBASE + 6] = 0;
1054  udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
1055  udfs->dux_commands[LOGBASE + 6] = 0;
1056 
1057  case 16:
1058  if (CR_RANGE(cmd->chanlist[0]) > 0)
1059  rngmask = 0xff - 0x04;
1060  else
1061  rngmask = 0xff;
1062 
1063  if (cmd->start_src == TRIG_EXT) {
1064  /*
1065  * we loop here until ready has been set
1066  */
1067 
1068  /* branch back to state 0 */
1069  udfs->dux_commands[LENBASE + 0] = 0x01;
1070  /* deceision state w/o data */
1071  udfs->dux_commands[OPBASE + 0] = 0x01;
1072  /* reset */
1073  udfs->dux_commands[OUTBASE + 0] =
1074  (0xFF - 0x02) & rngmask;
1075  /* RDY0 = 0 */
1076  udfs->dux_commands[LOGBASE + 0] = 0x00;
1077  } else {
1078  /*
1079  * we just proceed to state 1
1080  */
1081 
1082  /* 30us reset pulse */
1083  udfs->dux_commands[LENBASE + 0] = 255;
1084  udfs->dux_commands[OPBASE + 0] = 0;
1085  /* reset */
1086  udfs->dux_commands[OUTBASE + 0] =
1087  (0xFF - 0x02) & rngmask;
1088  udfs->dux_commands[LOGBASE + 0] = 0;
1089  }
1090 
1091  /* commit data to the FIFO */
1092  udfs->dux_commands[LENBASE + 1] = 1;
1093  /* data */
1094  udfs->dux_commands[OPBASE + 1] = 0x02;
1095  udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
1096  udfs->dux_commands[LOGBASE + 1] = 0;
1097 
1098  /* we have 2 states with duration 1 */
1099  steps = steps - 2;
1100 
1101  /* do the first part of the delay */
1102  udfs->dux_commands[LENBASE + 2] = steps / 2;
1103  udfs->dux_commands[OPBASE + 2] = 0;
1104  udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
1105  udfs->dux_commands[LOGBASE + 2] = 0;
1106 
1107  /* and the second part */
1108  udfs->dux_commands[LENBASE + 3] = steps - steps / 2;
1109  udfs->dux_commands[OPBASE + 3] = 0;
1110  udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
1111  udfs->dux_commands[LOGBASE + 3] = 0;
1112 
1113  /* branch back to state 1 */
1114  udfs->dux_commands[LENBASE + 4] = 0x09;
1115  /* deceision state w/o data */
1116  udfs->dux_commands[OPBASE + 4] = 0x01;
1117  udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
1118  /* doesn't matter */
1119  udfs->dux_commands[LOGBASE + 4] = 0xFF;
1120 
1121  break;
1122 
1123  default:
1124  printk(KERN_ERR "comedi %d: unsupported combination of "
1125  "channels\n", dev->minor);
1126  up(&udfs->sem);
1127  return -EFAULT;
1128  }
1129 
1130 #ifdef CONFIG_COMEDI_DEBUG
1131  printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
1132  dev->minor);
1133 #endif
1134  /* 0 means that the AD commands are sent */
1135  result = send_dux_commands(udfs, SENDADCOMMANDS);
1136  if (result < 0) {
1137  printk(KERN_ERR "comedi%d: adc command could not be submitted."
1138  "Aborting...\n", dev->minor);
1139  up(&udfs->sem);
1140  return result;
1141  }
1142  if (cmd->stop_src == TRIG_COUNT) {
1143  udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
1144  if (udfs->ai_sample_count < 1) {
1145  printk(KERN_ERR "comedi%d: "
1146  "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
1147  "aborting.\n", dev->minor);
1148  up(&udfs->sem);
1149  return -EFAULT;
1150  }
1151  udfs->ai_continous = 0;
1152  } else {
1153  /* continous acquisition */
1154  udfs->ai_continous = 1;
1155  udfs->ai_sample_count = 0;
1156  }
1157 
1158  if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
1159  /* enable this acquisition operation */
1160  udfs->ai_cmd_running = 1;
1161  ret = usbduxfastsub_submit_InURBs(udfs);
1162  if (ret < 0) {
1163  udfs->ai_cmd_running = 0;
1164  /* fixme: unlink here?? */
1165  up(&udfs->sem);
1166  return ret;
1167  }
1168  s->async->inttrig = NULL;
1169  } else {
1170  /*
1171  * TRIG_INT
1172  * don't enable the acquision operation
1173  * wait for an internal signal
1174  */
1175  s->async->inttrig = usbduxfast_ai_inttrig;
1176  }
1177  up(&udfs->sem);
1178 
1179  return 0;
1180 }
1181 
1182 /*
1183  * Mode 0 is used to get a single conversion on demand.
1184  */
1185 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
1186  struct comedi_subdevice *s,
1187  struct comedi_insn *insn, unsigned int *data)
1188 {
1189  int i, j, n, actual_length;
1190  int chan, range, rngmask;
1191  int err;
1192  struct usbduxfastsub_s *udfs;
1193 
1194  udfs = dev->private;
1195  if (!udfs) {
1196  printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
1197  dev->minor);
1198  return -ENODEV;
1199  }
1200 #ifdef CONFIG_COMEDI_DEBUG
1201  printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
1202  "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
1203 #endif
1204  down(&udfs->sem);
1205  if (!udfs->probed) {
1206  up(&udfs->sem);
1207  return -ENODEV;
1208  }
1209  if (udfs->ai_cmd_running) {
1210  printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
1211  "Command is running.\n", dev->minor);
1212  up(&udfs->sem);
1213  return -EBUSY;
1214  }
1215  /* sample one channel */
1216  chan = CR_CHAN(insn->chanspec);
1217  range = CR_RANGE(insn->chanspec);
1218  /* set command for the first channel */
1219 
1220  if (range > 0)
1221  rngmask = 0xff - 0x04;
1222  else
1223  rngmask = 0xff;
1224 
1225  /* commit data to the FIFO */
1226  udfs->dux_commands[LENBASE + 0] = 1;
1227  /* data */
1228  udfs->dux_commands[OPBASE + 0] = 0x02;
1229  udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
1230  udfs->dux_commands[LOGBASE + 0] = 0;
1231 
1232  /* do the first part of the delay */
1233  udfs->dux_commands[LENBASE + 1] = 12;
1234  udfs->dux_commands[OPBASE + 1] = 0;
1235  udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
1236  udfs->dux_commands[LOGBASE + 1] = 0;
1237 
1238  udfs->dux_commands[LENBASE + 2] = 1;
1239  udfs->dux_commands[OPBASE + 2] = 0;
1240  udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
1241  udfs->dux_commands[LOGBASE + 2] = 0;
1242 
1243  udfs->dux_commands[LENBASE + 3] = 1;
1244  udfs->dux_commands[OPBASE + 3] = 0;
1245  udfs->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
1246  udfs->dux_commands[LOGBASE + 3] = 0;
1247 
1248  udfs->dux_commands[LENBASE + 4] = 1;
1249  udfs->dux_commands[OPBASE + 4] = 0;
1250  udfs->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
1251  udfs->dux_commands[LOGBASE + 4] = 0;
1252 
1253  /* second part */
1254  udfs->dux_commands[LENBASE + 5] = 12;
1255  udfs->dux_commands[OPBASE + 5] = 0;
1256  udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
1257  udfs->dux_commands[LOGBASE + 5] = 0;
1258 
1259  udfs->dux_commands[LENBASE + 6] = 1;
1260  udfs->dux_commands[OPBASE + 6] = 0;
1261  udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
1262  udfs->dux_commands[LOGBASE + 0] = 0;
1263 
1264 #ifdef CONFIG_COMEDI_DEBUG
1265  printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
1266  dev->minor);
1267 #endif
1268  /* 0 means that the AD commands are sent */
1269  err = send_dux_commands(udfs, SENDADCOMMANDS);
1270  if (err < 0) {
1271  printk(KERN_ERR "comedi%d: adc command could not be submitted."
1272  "Aborting...\n", dev->minor);
1273  up(&udfs->sem);
1274  return err;
1275  }
1276 #ifdef CONFIG_COMEDI_DEBUG
1277  printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
1278  "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
1279  udfs->urbIn->dev);
1280 #endif
1281  for (i = 0; i < PACKETS_TO_IGNORE; i++) {
1282  err = usb_bulk_msg(udfs->usbdev,
1283  usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
1284  udfs->transfer_buffer, SIZEINBUF,
1285  &actual_length, 10000);
1286  if (err < 0) {
1287  printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
1288  dev->minor);
1289  up(&udfs->sem);
1290  return err;
1291  }
1292  }
1293  /* data points */
1294  for (i = 0; i < insn->n;) {
1295  err = usb_bulk_msg(udfs->usbdev,
1296  usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
1297  udfs->transfer_buffer, SIZEINBUF,
1298  &actual_length, 10000);
1299  if (err < 0) {
1300  printk(KERN_ERR "comedi%d: insn data error: %d\n",
1301  dev->minor, err);
1302  up(&udfs->sem);
1303  return err;
1304  }
1305  n = actual_length / sizeof(uint16_t);
1306  if ((n % 16) != 0) {
1307  printk(KERN_ERR "comedi%d: insn data packet "
1308  "corrupted.\n", dev->minor);
1309  up(&udfs->sem);
1310  return -EINVAL;
1311  }
1312  for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
1313  data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
1314  i++;
1315  }
1316  }
1317  up(&udfs->sem);
1318  return i;
1319 }
1320 
1321 #define FIRMWARE_MAX_LEN 0x2000
1322 
1323 static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
1324  const u8 *firmwareBinary, int sizeFirmware)
1325 {
1326  int ret;
1327  uint8_t *fwBuf;
1328 
1329  if (!firmwareBinary)
1330  return 0;
1331 
1332  if (sizeFirmware > FIRMWARE_MAX_LEN) {
1333  dev_err(&usbduxfastsub->interface->dev,
1334  "comedi_: usbduxfast firmware binary it too large for FX2.\n");
1335  return -ENOMEM;
1336  }
1337 
1338  /* we generate a local buffer for the firmware */
1339  fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
1340  if (!fwBuf) {
1341  dev_err(&usbduxfastsub->interface->dev,
1342  "comedi_: mem alloc for firmware failed\n");
1343  return -ENOMEM;
1344  }
1345 
1346  ret = usbduxfastsub_stop(usbduxfastsub);
1347  if (ret < 0) {
1348  dev_err(&usbduxfastsub->interface->dev,
1349  "comedi_: can not stop firmware\n");
1350  kfree(fwBuf);
1351  return ret;
1352  }
1353 
1354  ret = usbduxfastsub_upload(usbduxfastsub, fwBuf, 0, sizeFirmware);
1355  if (ret < 0) {
1356  dev_err(&usbduxfastsub->interface->dev,
1357  "comedi_: firmware upload failed\n");
1358  kfree(fwBuf);
1359  return ret;
1360  }
1361  ret = usbduxfastsub_start(usbduxfastsub);
1362  if (ret < 0) {
1363  dev_err(&usbduxfastsub->interface->dev,
1364  "comedi_: can not start firmware\n");
1365  kfree(fwBuf);
1366  return ret;
1367  }
1368  kfree(fwBuf);
1369  return 0;
1370 }
1371 
1372 static void tidy_up(struct usbduxfastsub_s *udfs)
1373 {
1374 #ifdef CONFIG_COMEDI_DEBUG
1375  printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
1376 #endif
1377 
1378  if (!udfs)
1379  return;
1380 
1381  /* shows the usb subsystem that the driver is down */
1382  if (udfs->interface)
1383  usb_set_intfdata(udfs->interface, NULL);
1384 
1385  udfs->probed = 0;
1386 
1387  if (udfs->urbIn) {
1388  /* waits until a running transfer is over */
1389  usb_kill_urb(udfs->urbIn);
1390 
1391  kfree(udfs->transfer_buffer);
1392  udfs->transfer_buffer = NULL;
1393 
1394  usb_free_urb(udfs->urbIn);
1395  udfs->urbIn = NULL;
1396  }
1397 
1398  kfree(udfs->insnBuffer);
1399  udfs->insnBuffer = NULL;
1400 
1401  kfree(udfs->dux_commands);
1402  udfs->dux_commands = NULL;
1403 
1404  udfs->ai_cmd_running = 0;
1405 }
1406 
1407 static int usbduxfast_attach_common(struct comedi_device *dev,
1408  struct usbduxfastsub_s *udfs)
1409 {
1410  int ret;
1411  struct comedi_subdevice *s;
1412 
1413  down(&udfs->sem);
1414  /* pointer back to the corresponding comedi device */
1415  udfs->comedidev = dev;
1416  dev->board_name = "usbduxfast";
1417  ret = comedi_alloc_subdevices(dev, 1);
1418  if (ret) {
1419  up(&udfs->sem);
1420  return ret;
1421  }
1422  /* private structure is also simply the usb-structure */
1423  dev->private = udfs;
1424  /* the first subdevice is the A/D converter */
1425  s = &dev->subdevices[SUBDEV_AD];
1426  /*
1427  * the URBs get the comedi subdevice which is responsible for reading
1428  * this is the subdevice which reads data
1429  */
1430  dev->read_subdev = s;
1431  /* the subdevice receives as private structure the usb-structure */
1432  s->private = NULL;
1433  /* analog input */
1434  s->type = COMEDI_SUBD_AI;
1435  /* readable and ref is to ground */
1437  /* 16 channels */
1438  s->n_chan = 16;
1439  /* length of the channellist */
1440  s->len_chanlist = 16;
1441  /* callback functions */
1442  s->insn_read = usbduxfast_ai_insn_read;
1443  s->do_cmdtest = usbduxfast_ai_cmdtest;
1444  s->do_cmd = usbduxfast_ai_cmd;
1445  s->cancel = usbduxfast_ai_cancel;
1446  /* max value from the A/D converter (12bit+1 bit for overflow) */
1447  s->maxdata = 0x1000;
1448  /* range table to convert to physical units */
1449  s->range_table = &range_usbduxfast_ai_range;
1450  /* finally decide that it's attached */
1451  udfs->attached = 1;
1452  up(&udfs->sem);
1453  dev_info(dev->class_dev, "successfully attached to usbduxfast.\n");
1454  return 0;
1455 }
1456 
1457 static int usbduxfast_attach_usb(struct comedi_device *dev,
1458  struct usb_interface *uinterf)
1459 {
1460  int ret;
1461  struct usbduxfastsub_s *udfs;
1462 
1463  dev->private = NULL;
1464  down(&start_stop_sem);
1465  udfs = usb_get_intfdata(uinterf);
1466  if (!udfs || !udfs->probed) {
1467  dev_err(dev->class_dev,
1468  "usbduxfast: error: attach_usb failed, not connected\n");
1469  ret = -ENODEV;
1470  } else if (udfs->attached) {
1471  dev_err(dev->class_dev,
1472  "usbduxfast: error: attach_usb failed, already attached\n");
1473  ret = -ENODEV;
1474  } else
1475  ret = usbduxfast_attach_common(dev, udfs);
1476  up(&start_stop_sem);
1477  return ret;
1478 }
1479 
1480 static void usbduxfast_detach(struct comedi_device *dev)
1481 {
1482  struct usbduxfastsub_s *usb = dev->private;
1483 
1484  if (usb) {
1485  down(&usb->sem);
1486  down(&start_stop_sem);
1487  dev->private = NULL;
1488  usb->attached = 0;
1489  usb->comedidev = NULL;
1490  up(&start_stop_sem);
1491  up(&usb->sem);
1492  }
1493 }
1494 
1495 static struct comedi_driver usbduxfast_driver = {
1496  .driver_name = "usbduxfast",
1497  .module = THIS_MODULE,
1498  .attach_usb = usbduxfast_attach_usb,
1499  .detach = usbduxfast_detach,
1500 };
1501 
1502 static void usbduxfast_firmware_request_complete_handler(const struct firmware
1503  *fw, void *context)
1504 {
1505  struct usbduxfastsub_s *usbduxfastsub_tmp = context;
1506  struct usb_interface *uinterf = usbduxfastsub_tmp->interface;
1507  int ret;
1508 
1509  if (fw == NULL)
1510  return;
1511 
1512  /*
1513  * we need to upload the firmware here because fw will be
1514  * freed once we've left this function
1515  */
1516  ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size);
1517 
1518  if (ret) {
1519  dev_err(&uinterf->dev,
1520  "Could not upload firmware (err=%d)\n", ret);
1521  goto out;
1522  }
1523 
1524  comedi_usb_auto_config(uinterf, &usbduxfast_driver);
1525  out:
1526  release_firmware(fw);
1527 }
1528 
1529 static int usbduxfast_usb_probe(struct usb_interface *uinterf,
1530  const struct usb_device_id *id)
1531 {
1532  struct usb_device *udev = interface_to_usbdev(uinterf);
1533  int i;
1534  int index;
1535  int ret;
1536 
1537  if (udev->speed != USB_SPEED_HIGH) {
1538  printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
1539  "USB 2.0 to operate. Aborting...\n");
1540  return -ENODEV;
1541  }
1542 #ifdef CONFIG_COMEDI_DEBUG
1543  printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
1544  "the usb-device\n");
1545 #endif
1546  down(&start_stop_sem);
1547  /* look for a free place in the usbduxfast array */
1548  index = -1;
1549  for (i = 0; i < NUMUSBDUXFAST; i++) {
1550  if (!usbduxfastsub[i].probed) {
1551  index = i;
1552  break;
1553  }
1554  }
1555 
1556  /* no more space */
1557  if (index == -1) {
1558  printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
1559  up(&start_stop_sem);
1560  return -EMFILE;
1561  }
1562 #ifdef CONFIG_COMEDI_DEBUG
1563  printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
1564  "connect to comedi.\n", index);
1565 #endif
1566 
1567  sema_init(&(usbduxfastsub[index].sem), 1);
1568  /* save a pointer to the usb device */
1569  usbduxfastsub[index].usbdev = udev;
1570 
1571  /* save the interface itself */
1572  usbduxfastsub[index].interface = uinterf;
1573  /* get the interface number from the interface */
1574  usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
1575  /*
1576  * hand the private data over to the usb subsystem
1577  * will be needed for disconnect
1578  */
1579  usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
1580 
1581 #ifdef CONFIG_COMEDI_DEBUG
1582  printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
1583  usbduxfastsub[index].ifnum);
1584 #endif
1585  /* create space for the commands going to the usb device */
1586  usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
1587  GFP_KERNEL);
1588  if (!usbduxfastsub[index].dux_commands) {
1589  printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
1590  "dac commands\n");
1591  tidy_up(&(usbduxfastsub[index]));
1592  up(&start_stop_sem);
1593  return -ENOMEM;
1594  }
1595  /* create space of the instruction buffer */
1596  usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
1597  if (!usbduxfastsub[index].insnBuffer) {
1598  printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
1599  "for insnBuffer\n");
1600  tidy_up(&(usbduxfastsub[index]));
1601  up(&start_stop_sem);
1602  return -ENOMEM;
1603  }
1604  /* setting to alternate setting 1: enabling bulk ep */
1605  i = usb_set_interface(usbduxfastsub[index].usbdev,
1606  usbduxfastsub[index].ifnum, 1);
1607  if (i < 0) {
1608  printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
1609  "alternate setting 1.\n", index);
1610  tidy_up(&(usbduxfastsub[index]));
1611  up(&start_stop_sem);
1612  return -ENODEV;
1613  }
1614  usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
1615  if (!usbduxfastsub[index].urbIn) {
1616  printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
1617  "urb\n", index);
1618  tidy_up(&(usbduxfastsub[index]));
1619  up(&start_stop_sem);
1620  return -ENOMEM;
1621  }
1622  usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
1623  if (!usbduxfastsub[index].transfer_buffer) {
1624  printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
1625  "transb.\n", index);
1626  tidy_up(&(usbduxfastsub[index]));
1627  up(&start_stop_sem);
1628  return -ENOMEM;
1629  }
1630  /* we've reached the bottom of the function */
1631  usbduxfastsub[index].probed = 1;
1632  up(&start_stop_sem);
1633 
1636  FIRMWARE,
1637  &udev->dev,
1638  GFP_KERNEL,
1639  usbduxfastsub + index,
1640  usbduxfast_firmware_request_complete_handler);
1641 
1642  if (ret) {
1643  dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret);
1644  return ret;
1645  }
1646 
1647  printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
1648  "initialized.\n", index);
1649  /* success */
1650  return 0;
1651 }
1652 
1653 static void usbduxfast_usb_disconnect(struct usb_interface *intf)
1654 {
1655  struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
1656  struct usb_device *udev = interface_to_usbdev(intf);
1657 
1658  if (!udfs) {
1659  printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
1660  "null pointer.\n");
1661  return;
1662  }
1663  if (udfs->usbdev != udev) {
1664  printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
1665  "ptr!!!\n");
1666  return;
1667  }
1668 
1670 
1671  down(&start_stop_sem);
1672  down(&udfs->sem);
1673  tidy_up(udfs);
1674  up(&udfs->sem);
1675  up(&start_stop_sem);
1676 
1677 #ifdef CONFIG_COMEDI_DEBUG
1678  printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
1679 #endif
1680 }
1681 
1682 static const struct usb_device_id usbduxfast_usb_table[] = {
1683  /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1684  { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1685  { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1686  { }
1687 };
1688 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1689 
1690 static struct usb_driver usbduxfast_usb_driver = {
1691 #ifdef COMEDI_HAVE_USB_DRIVER_OWNER
1692  .owner = THIS_MODULE,
1693 #endif
1694  .name = "usbduxfast",
1695  .probe = usbduxfast_usb_probe,
1696  .disconnect = usbduxfast_usb_disconnect,
1697  .id_table = usbduxfast_usb_table,
1698 };
1699 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1700 
1701 MODULE_AUTHOR("Bernd Porr, [email protected]");
1702 MODULE_DESCRIPTION("USB-DUXfast, [email protected]");
1703 MODULE_LICENSE("GPL");