Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
usbdux.c
Go to the documentation of this file.
1 /*
2  comedi/drivers/usbdux.c
3  Copyright (C) 2003-2007 Bernd Porr, [email protected]
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  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19  */
20 /*
21 Driver: usbdux
22 Description: University of Stirling USB DAQ & INCITE Technology Limited
23 Devices: [ITL] USB-DUX (usbdux.o)
24 Author: Bernd Porr <[email protected]>
25 Updated: 8 Dec 2008
26 Status: Stable
27 Configuration options:
28  You have to upload firmware with the -i option. The
29  firmware is usually installed under /usr/share/usb or
30  /usr/local/share/usb or /lib/firmware.
31 
32 Connection scheme for the counter at the digital port:
33  0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
34  The sampling rate of the counter is approximately 500Hz.
35 
36 Please note that under USB2.0 the length of the channel list determines
37 the max sampling rate. If you sample only one channel you get 8kHz
38 sampling rate. If you sample two channels you get 4kHz and so on.
39 */
40 /*
41  * I must give credit here to Chris Baugher who
42  * wrote the driver for AT-MIO-16d. I used some parts of this
43  * driver. I also must give credits to David Brownell
44  * who supported me with the USB development.
45  *
46  * Bernd Porr
47  *
48  *
49  * Revision history:
50  * 0.94: D/A output should work now with any channel list combinations
51  * 0.95: .owner commented out for kernel vers below 2.4.19
52  * sanity checks in ai/ao_cmd
53  * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
54  * attach final USB IDs
55  * moved memory allocation completely to the corresponding comedi
56  * functions firmware upload is by fxload and no longer by comedi (due to
57  * enumeration)
58  * 0.97: USB IDs received, adjusted table
59  * 0.98: SMP, locking, memroy alloc: moved all usb memory alloc
60  * to the usb subsystem and moved all comedi related memory
61  * alloc to comedi.
62  * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
63  * 0.99: USB 2.0: changed protocol to isochronous transfer
64  * IRQ transfer is too buggy and too risky in 2.0
65  * for the high speed ISO transfer is now a working version
66  * available
67  * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
68  * chipsets miss out IRQs. Deeper buffering is needed.
69  * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
70  * rate.
71  * Firmware vers 1.00 is needed for this.
72  * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
73  * And loads of cleaning up, in particular streamlining the
74  * bulk transfers.
75  * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
76  * 1.2: added PWM suport via EP4
77  * 2.0: PWM seems to be stable and is not interfering with the other functions
78  * 2.1: changed PWM API
79  * 2.2: added firmware kernel request to fix an udev problem
80  * 2.3: corrected a bug in bulk timeouts which were far too short
81  * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
82  * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
83  *
84  */
85 
86 /* generates loads of debug info */
87 /* #define NOISY_DUX_DEBUGBUG */
88 
89 #include <linux/kernel.h>
90 #include <linux/module.h>
91 #include <linux/init.h>
92 #include <linux/slab.h>
93 #include <linux/input.h>
94 #include <linux/usb.h>
95 #include <linux/fcntl.h>
96 #include <linux/compiler.h>
97 #include <linux/firmware.h>
98 
99 #include "../comedidev.h"
100 
101 #include "comedi_fc.h"
102 
103 /* timeout for the USB-transfer in ms*/
104 #define BULK_TIMEOUT 1000
105 
106 /* constants for "firmware" upload and download */
107 #define FIRMWARE "usbdux_firmware.bin"
108 #define USBDUXSUB_FIRMWARE 0xA0
109 #define VENDOR_DIR_IN 0xC0
110 #define VENDOR_DIR_OUT 0x40
111 
112 /* internal addresses of the 8051 processor */
113 #define USBDUXSUB_CPUCS 0xE600
114 
115 /*
116  * the minor device number, major is 180 only for debugging purposes and to
117  * upload special firmware (programming the eeprom etc) which is not compatible
118  * with the comedi framwork
119  */
120 #define USBDUXSUB_MINOR 32
121 
122 /* max lenghth of the transfer-buffer for software upload */
123 #define TB_LEN 0x2000
124 
125 /* Input endpoint number: ISO/IRQ */
126 #define ISOINEP 6
127 
128 /* Output endpoint number: ISO/IRQ */
129 #define ISOOUTEP 2
130 
131 /* This EP sends DUX commands to USBDUX */
132 #define COMMAND_OUT_EP 1
133 
134 /* This EP receives the DUX commands from USBDUX */
135 #define COMMAND_IN_EP 8
136 
137 /* Output endpoint for PWM */
138 #define PWM_EP 4
139 
140 /* 300Hz max frequ under PWM */
141 #define MIN_PWM_PERIOD ((long)(1E9/300))
142 
143 /* Default PWM frequency */
144 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
145 
146 /* Number of channels */
147 #define NUMCHANNELS 8
148 
149 /* Size of one A/D value */
150 #define SIZEADIN ((sizeof(int16_t)))
151 
152 /*
153  * Size of the input-buffer IN BYTES
154  * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
155  */
156 #define SIZEINBUF ((8*SIZEADIN))
157 
158 /* 16 bytes. */
159 #define SIZEINSNBUF 16
160 
161 /* Number of DA channels */
162 #define NUMOUTCHANNELS 8
163 
164 /* size of one value for the D/A converter: channel and value */
165 #define SIZEDAOUT ((sizeof(int8_t)+sizeof(int16_t)))
166 
167 /*
168  * Size of the output-buffer in bytes
169  * Actually only the first 4 triplets are used but for the
170  * high speed mode we need to pad it to 8 (microframes).
171  */
172 #define SIZEOUTBUF ((8*SIZEDAOUT))
173 
174 /*
175  * Size of the buffer for the dux commands: just now max size is determined
176  * by the analogue out + command byte + panic bytes...
177  */
178 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
179 
180 /* Number of in-URBs which receive the data: min=2 */
181 #define NUMOFINBUFFERSFULL 5
182 
183 /* Number of out-URBs which send the data: min=2 */
184 #define NUMOFOUTBUFFERSFULL 5
185 
186 /* Number of in-URBs which receive the data: min=5 */
187 /* must have more buffers due to buggy USB ctr */
188 #define NUMOFINBUFFERSHIGH 10
189 
190 /* Number of out-URBs which send the data: min=5 */
191 /* must have more buffers due to buggy USB ctr */
192 #define NUMOFOUTBUFFERSHIGH 10
193 
194 /* Total number of usbdux devices */
195 #define NUMUSBDUX 16
196 
197 /* Analogue in subdevice */
198 #define SUBDEV_AD 0
199 
200 /* Analogue out subdevice */
201 #define SUBDEV_DA 1
202 
203 /* Digital I/O */
204 #define SUBDEV_DIO 2
205 
206 /* counter */
207 #define SUBDEV_COUNTER 3
208 
209 /* timer aka pwm output */
210 #define SUBDEV_PWM 4
211 
212 /* number of retries to get the right dux command */
213 #define RETRIES 10
214 
215 /**************************************************/
216 /* comedi constants */
217 static const struct comedi_lrange range_usbdux_ai_range = { 4, {
218  BIP_RANGE
219  (4.096),
220  BIP_RANGE(4.096
221  / 2),
222  UNI_RANGE
223  (4.096),
224  UNI_RANGE(4.096
225  / 2)
226  }
227 };
228 
229 static const struct comedi_lrange range_usbdux_ao_range = { 2, {
230  BIP_RANGE
231  (4.096),
232  UNI_RANGE
233  (4.096),
234  }
235 };
236 
237 /*
238  * private structure of one subdevice
239  */
240 
241 /*
242  * This is the structure which holds all the data of
243  * this driver one sub device just now: A/D
244  */
245 struct usbduxsub {
246  /* attached? */
247  int attached;
248  /* is it associated with a subdevice? */
249  int probed;
250  /* pointer to the usb-device */
251  struct usb_device *usbdev;
252  /* actual number of in-buffers */
254  /* actual number of out-buffers */
256  /* ISO-transfer handling: buffers */
257  struct urb **urbIn;
258  struct urb **urbOut;
259  /* pwm-transfer handling */
260  struct urb *urbPwm;
261  /* PWM period */
262  unsigned int pwmPeriod;
263  /* PWM internal delay for the GPIF in the FX2 */
265  /* size of the PWM buffer which holds the bit pattern */
267  /* input buffer for the ISO-transfer */
269  /* input buffer for single insn */
271  /* output buffer for single DA outputs */
273  /* interface number */
274  int ifnum;
275  /* interface structure in 2.6 */
277  /* comedi device for the interrupt context */
279  /* is it USB_SPEED_HIGH or not? */
280  short int high_speed;
281  /* asynchronous command is running */
282  short int ai_cmd_running;
283  short int ao_cmd_running;
284  /* pwm is running */
285  short int pwm_cmd_running;
286  /* continous acquisition */
287  short int ai_continous;
288  short int ao_continous;
289  /* number of samples to acquire */
292  /* time between samples in units of the timer */
293  unsigned int ai_timer;
294  unsigned int ao_timer;
295  /* counter between aquisitions */
296  unsigned int ai_counter;
297  unsigned int ao_counter;
298  /* interval in frames/uframes */
299  unsigned int ai_interval;
300  /* D/A commands */
302  /* commands */
304  struct semaphore sem;
305 };
306 
307 /*
308  * The pointer to the private usb-data of the driver is also the private data
309  * for the comedi-device. This has to be global as the usb subsystem needs
310  * global variables. The other reason is that this structure must be there
311  * _before_ any comedi command is issued. The usb subsystem must be initialised
312  * before comedi can access it.
313  */
314 static struct usbduxsub usbduxsub[NUMUSBDUX];
315 
316 static DEFINE_SEMAPHORE(start_stop_sem);
317 
318 /*
319  * Stops the data acquision
320  * It should be safe to call this function from any context
321  */
322 static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp)
323 {
324  int i = 0;
325  int err = 0;
326 
327  if (usbduxsub_tmp && usbduxsub_tmp->urbIn) {
328  for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
329  if (usbduxsub_tmp->urbIn[i]) {
330  /* We wait here until all transfers have been
331  * cancelled. */
332  usb_kill_urb(usbduxsub_tmp->urbIn[i]);
333  }
334  dev_dbg(&usbduxsub_tmp->interface->dev,
335  "comedi: usbdux: unlinked InURB %d, err=%d\n",
336  i, err);
337  }
338  }
339  return err;
340 }
341 
342 /*
343  * This will stop a running acquisition operation
344  * Is called from within this driver from both the
345  * interrupt context and from comedi
346  */
347 static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
348 {
349  int ret = 0;
350 
351  if (!this_usbduxsub) {
352  pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
353  return -EFAULT;
354  }
355  dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
356 
357  if (do_unlink) {
358  /* stop aquistion */
359  ret = usbduxsub_unlink_InURBs(this_usbduxsub);
360  }
361 
362  this_usbduxsub->ai_cmd_running = 0;
363 
364  return ret;
365 }
366 
367 /*
368  * This will cancel a running acquisition operation.
369  * This is called by comedi but never from inside the driver.
370  */
371 static int usbdux_ai_cancel(struct comedi_device *dev,
372  struct comedi_subdevice *s)
373 {
374  struct usbduxsub *this_usbduxsub;
375  int res = 0;
376 
377  /* force unlink of all urbs */
378  this_usbduxsub = dev->private;
379  if (!this_usbduxsub)
380  return -EFAULT;
381 
382  dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
383 
384  /* prevent other CPUs from submitting new commands just now */
385  down(&this_usbduxsub->sem);
386  if (!(this_usbduxsub->probed)) {
387  up(&this_usbduxsub->sem);
388  return -ENODEV;
389  }
390  /* unlink only if the urb really has been submitted */
391  res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
392  up(&this_usbduxsub->sem);
393  return res;
394 }
395 
396 /* analogue IN - interrupt service routine */
397 static void usbduxsub_ai_IsocIrq(struct urb *urb)
398 {
399  int i, err, n;
400  struct usbduxsub *this_usbduxsub;
401  struct comedi_device *this_comedidev;
402  struct comedi_subdevice *s;
403 
404  /* the context variable points to the subdevice */
405  this_comedidev = urb->context;
406  /* the private structure of the subdevice is struct usbduxsub */
407  this_usbduxsub = this_comedidev->private;
408  /* subdevice which is the AD converter */
409  s = &this_comedidev->subdevices[SUBDEV_AD];
410 
411  /* first we test if something unusual has just happened */
412  switch (urb->status) {
413  case 0:
414  /* copy the result in the transfer buffer */
415  memcpy(this_usbduxsub->inBuffer,
416  urb->transfer_buffer, SIZEINBUF);
417  break;
418  case -EILSEQ:
419  /* error in the ISOchronous data */
420  /* we don't copy the data into the transfer buffer */
421  /* and recycle the last data byte */
422  dev_dbg(&urb->dev->dev,
423  "comedi%d: usbdux: CRC error in ISO IN stream.\n",
424  this_usbduxsub->comedidev->minor);
425 
426  break;
427 
428  case -ECONNRESET:
429  case -ENOENT:
430  case -ESHUTDOWN:
431  case -ECONNABORTED:
432  /* happens after an unlink command */
433  if (this_usbduxsub->ai_cmd_running) {
434  /* we are still running a command */
435  /* tell this comedi */
436  s->async->events |= COMEDI_CB_EOA;
437  s->async->events |= COMEDI_CB_ERROR;
438  comedi_event(this_usbduxsub->comedidev, s);
439  /* stop the transfer w/o unlink */
440  usbdux_ai_stop(this_usbduxsub, 0);
441  }
442  return;
443 
444  default:
445  /* a real error on the bus */
446  /* pass error to comedi if we are really running a command */
447  if (this_usbduxsub->ai_cmd_running) {
448  dev_err(&urb->dev->dev,
449  "Non-zero urb status received in ai intr "
450  "context: %d\n", urb->status);
451  s->async->events |= COMEDI_CB_EOA;
452  s->async->events |= COMEDI_CB_ERROR;
453  comedi_event(this_usbduxsub->comedidev, s);
454  /* don't do an unlink here */
455  usbdux_ai_stop(this_usbduxsub, 0);
456  }
457  return;
458  }
459 
460  /*
461  * at this point we are reasonably sure that nothing dodgy has happened
462  * are we running a command?
463  */
464  if (unlikely((!(this_usbduxsub->ai_cmd_running)))) {
465  /*
466  * not running a command, do not continue execution if no
467  * asynchronous command is running in particular not resubmit
468  */
469  return;
470  }
471 
472  urb->dev = this_usbduxsub->usbdev;
473 
474  /* resubmit the urb */
475  err = usb_submit_urb(urb, GFP_ATOMIC);
476  if (unlikely(err < 0)) {
477  dev_err(&urb->dev->dev,
478  "comedi_: urb resubmit failed in int-context! err=%d\n",
479  err);
480  if (err == -EL2NSYNC)
481  dev_err(&urb->dev->dev,
482  "buggy USB host controller or bug in IRQ "
483  "handler!\n");
484  s->async->events |= COMEDI_CB_EOA;
485  s->async->events |= COMEDI_CB_ERROR;
486  comedi_event(this_usbduxsub->comedidev, s);
487  /* don't do an unlink here */
488  usbdux_ai_stop(this_usbduxsub, 0);
489  return;
490  }
491 
492  this_usbduxsub->ai_counter--;
493  if (likely(this_usbduxsub->ai_counter > 0))
494  return;
495 
496  /* timer zero, transfer measurements to comedi */
497  this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
498 
499  /* test, if we transmit only a fixed number of samples */
500  if (!(this_usbduxsub->ai_continous)) {
501  /* not continuous, fixed number of samples */
502  this_usbduxsub->ai_sample_count--;
503  /* all samples received? */
504  if (this_usbduxsub->ai_sample_count < 0) {
505  /* prevent a resubmit next time */
506  usbdux_ai_stop(this_usbduxsub, 0);
507  /* say comedi that the acquistion is over */
508  s->async->events |= COMEDI_CB_EOA;
509  comedi_event(this_usbduxsub->comedidev, s);
510  return;
511  }
512  }
513  /* get the data from the USB bus and hand it over to comedi */
514  n = s->async->cmd.chanlist_len;
515  for (i = 0; i < n; i++) {
516  /* transfer data */
517  if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
518  err = comedi_buf_put
519  (s->async,
520  le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800);
521  } else {
522  err = comedi_buf_put
523  (s->async,
524  le16_to_cpu(this_usbduxsub->inBuffer[i]));
525  }
526  if (unlikely(err == 0)) {
527  /* buffer overflow */
528  usbdux_ai_stop(this_usbduxsub, 0);
529  return;
530  }
531  }
532  /* tell comedi that data is there */
533  s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
534  comedi_event(this_usbduxsub->comedidev, s);
535 }
536 
537 static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp)
538 {
539  int i = 0;
540  int err = 0;
541 
542  if (usbduxsub_tmp && usbduxsub_tmp->urbOut) {
543  for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
544  if (usbduxsub_tmp->urbOut[i])
545  usb_kill_urb(usbduxsub_tmp->urbOut[i]);
546 
547  dev_dbg(&usbduxsub_tmp->interface->dev,
548  "comedi: usbdux: unlinked OutURB %d: res=%d\n",
549  i, err);
550  }
551  }
552  return err;
553 }
554 
555 /* This will cancel a running acquisition operation
556  * in any context.
557  */
558 static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
559 {
560  int ret = 0;
561 
562  if (!this_usbduxsub)
563  return -EFAULT;
564  dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
565 
566  if (do_unlink)
567  ret = usbduxsub_unlink_OutURBs(this_usbduxsub);
568 
569  this_usbduxsub->ao_cmd_running = 0;
570 
571  return ret;
572 }
573 
574 /* force unlink, is called by comedi */
575 static int usbdux_ao_cancel(struct comedi_device *dev,
576  struct comedi_subdevice *s)
577 {
578  struct usbduxsub *this_usbduxsub = dev->private;
579  int res = 0;
580 
581  if (!this_usbduxsub)
582  return -EFAULT;
583 
584  /* prevent other CPUs from submitting a command just now */
585  down(&this_usbduxsub->sem);
586  if (!(this_usbduxsub->probed)) {
587  up(&this_usbduxsub->sem);
588  return -ENODEV;
589  }
590  /* unlink only if it is really running */
591  res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
592  up(&this_usbduxsub->sem);
593  return res;
594 }
595 
596 static void usbduxsub_ao_IsocIrq(struct urb *urb)
597 {
598  int i, ret;
599  int8_t *datap;
600  struct usbduxsub *this_usbduxsub;
601  struct comedi_device *this_comedidev;
602  struct comedi_subdevice *s;
603 
604  /* the context variable points to the subdevice */
605  this_comedidev = urb->context;
606  /* the private structure of the subdevice is struct usbduxsub */
607  this_usbduxsub = this_comedidev->private;
608 
609  s = &this_comedidev->subdevices[SUBDEV_DA];
610 
611  switch (urb->status) {
612  case 0:
613  /* success */
614  break;
615 
616  case -ECONNRESET:
617  case -ENOENT:
618  case -ESHUTDOWN:
619  case -ECONNABORTED:
620  /* after an unlink command, unplug, ... etc */
621  /* no unlink needed here. Already shutting down. */
622  if (this_usbduxsub->ao_cmd_running) {
623  s->async->events |= COMEDI_CB_EOA;
624  comedi_event(this_usbduxsub->comedidev, s);
625  usbdux_ao_stop(this_usbduxsub, 0);
626  }
627  return;
628 
629  default:
630  /* a real error */
631  if (this_usbduxsub->ao_cmd_running) {
632  dev_err(&urb->dev->dev,
633  "comedi_: Non-zero urb status received in ao "
634  "intr context: %d\n", urb->status);
635  s->async->events |= COMEDI_CB_ERROR;
636  s->async->events |= COMEDI_CB_EOA;
637  comedi_event(this_usbduxsub->comedidev, s);
638  /* we do an unlink if we are in the high speed mode */
639  usbdux_ao_stop(this_usbduxsub, 0);
640  }
641  return;
642  }
643 
644  /* are we actually running? */
645  if (!(this_usbduxsub->ao_cmd_running))
646  return;
647 
648  /* normal operation: executing a command in this subdevice */
649  this_usbduxsub->ao_counter--;
650  if ((int)this_usbduxsub->ao_counter <= 0) {
651  /* timer zero */
652  this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
653 
654  /* handle non continous acquisition */
655  if (!(this_usbduxsub->ao_continous)) {
656  /* fixed number of samples */
657  this_usbduxsub->ao_sample_count--;
658  if (this_usbduxsub->ao_sample_count < 0) {
659  /* all samples transmitted */
660  usbdux_ao_stop(this_usbduxsub, 0);
661  s->async->events |= COMEDI_CB_EOA;
662  comedi_event(this_usbduxsub->comedidev, s);
663  /* no resubmit of the urb */
664  return;
665  }
666  }
667  /* transmit data to the USB bus */
668  ((uint8_t *) (urb->transfer_buffer))[0] =
669  s->async->cmd.chanlist_len;
670  for (i = 0; i < s->async->cmd.chanlist_len; i++) {
671  short temp;
672  if (i >= NUMOUTCHANNELS)
673  break;
674 
675  /* pointer to the DA */
676  datap =
677  (&(((int8_t *) urb->transfer_buffer)[i * 3 + 1]));
678  /* get the data from comedi */
679  ret = comedi_buf_get(s->async, &temp);
680  datap[0] = temp;
681  datap[1] = temp >> 8;
682  datap[2] = this_usbduxsub->dac_commands[i];
683  /* printk("data[0]=%x, data[1]=%x, data[2]=%x\n", */
684  /* datap[0],datap[1],datap[2]); */
685  if (ret < 0) {
686  dev_err(&urb->dev->dev,
687  "comedi: buffer underflow\n");
688  s->async->events |= COMEDI_CB_EOA;
689  s->async->events |= COMEDI_CB_OVERFLOW;
690  }
691  /* transmit data to comedi */
692  s->async->events |= COMEDI_CB_BLOCK;
693  comedi_event(this_usbduxsub->comedidev, s);
694  }
695  }
696  urb->transfer_buffer_length = SIZEOUTBUF;
697  urb->dev = this_usbduxsub->usbdev;
698  urb->status = 0;
699  if (this_usbduxsub->ao_cmd_running) {
700  if (this_usbduxsub->high_speed) {
701  /* uframes */
702  urb->interval = 8;
703  } else {
704  /* frames */
705  urb->interval = 1;
706  }
707  urb->number_of_packets = 1;
708  urb->iso_frame_desc[0].offset = 0;
709  urb->iso_frame_desc[0].length = SIZEOUTBUF;
710  urb->iso_frame_desc[0].status = 0;
711  ret = usb_submit_urb(urb, GFP_ATOMIC);
712  if (ret < 0) {
713  dev_err(&urb->dev->dev,
714  "comedi_: ao urb resubm failed in int-cont. "
715  "ret=%d", ret);
716  if (ret == EL2NSYNC)
717  dev_err(&urb->dev->dev,
718  "buggy USB host controller or bug in "
719  "IRQ handling!\n");
720 
721  s->async->events |= COMEDI_CB_EOA;
722  s->async->events |= COMEDI_CB_ERROR;
723  comedi_event(this_usbduxsub->comedidev, s);
724  /* don't do an unlink here */
725  usbdux_ao_stop(this_usbduxsub, 0);
726  }
727  }
728 }
729 
730 static int usbduxsub_start(struct usbduxsub *usbduxsub)
731 {
732  int errcode = 0;
733  uint8_t local_transfer_buffer[16];
734 
735  /* 7f92 to zero */
736  local_transfer_buffer[0] = 0;
737  errcode = usb_control_msg(usbduxsub->usbdev,
738  /* create a pipe for a control transfer */
739  usb_sndctrlpipe(usbduxsub->usbdev, 0),
740  /* bRequest, "Firmware" */
742  /* bmRequestType */
744  /* Value */
746  /* Index */
747  0x0000,
748  /* address of the transfer buffer */
749  local_transfer_buffer,
750  /* Length */
751  1,
752  /* Timeout */
753  BULK_TIMEOUT);
754  if (errcode < 0) {
755  dev_err(&usbduxsub->interface->dev,
756  "comedi_: control msg failed (start)\n");
757  return errcode;
758  }
759  return 0;
760 }
761 
762 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
763 {
764  int errcode = 0;
765 
766  uint8_t local_transfer_buffer[16];
767 
768  /* 7f92 to one */
769  local_transfer_buffer[0] = 1;
770  errcode = usb_control_msg(usbduxsub->usbdev,
771  usb_sndctrlpipe(usbduxsub->usbdev, 0),
772  /* bRequest, "Firmware" */
774  /* bmRequestType */
776  /* Value */
778  /* Index */
779  0x0000, local_transfer_buffer,
780  /* Length */
781  1,
782  /* Timeout */
783  BULK_TIMEOUT);
784  if (errcode < 0) {
785  dev_err(&usbduxsub->interface->dev,
786  "comedi_: control msg failed (stop)\n");
787  return errcode;
788  }
789  return 0;
790 }
791 
792 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
793  uint8_t *local_transfer_buffer,
794  unsigned int startAddr, unsigned int len)
795 {
796  int errcode;
797 
798  errcode = usb_control_msg(usbduxsub->usbdev,
799  usb_sndctrlpipe(usbduxsub->usbdev, 0),
800  /* brequest, firmware */
802  /* bmRequestType */
804  /* value */
805  startAddr,
806  /* index */
807  0x0000,
808  /* our local safe buffer */
809  local_transfer_buffer,
810  /* length */
811  len,
812  /* timeout */
813  BULK_TIMEOUT);
814  dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
815  if (errcode < 0) {
816  dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n");
817  return errcode;
818  }
819  return 0;
820 }
821 
822 #define FIRMWARE_MAX_LEN 0x2000
823 
824 static int firmwareUpload(struct usbduxsub *usbduxsub,
825  const u8 *firmwareBinary, int sizeFirmware)
826 {
827  int ret;
828  uint8_t *fwBuf;
829 
830  if (!firmwareBinary)
831  return 0;
832 
833  if (sizeFirmware > FIRMWARE_MAX_LEN) {
834  dev_err(&usbduxsub->interface->dev,
835  "usbdux firmware binary it too large for FX2.\n");
836  return -ENOMEM;
837  }
838 
839  /* we generate a local buffer for the firmware */
840  fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
841  if (!fwBuf) {
842  dev_err(&usbduxsub->interface->dev,
843  "comedi_: mem alloc for firmware failed\n");
844  return -ENOMEM;
845  }
846 
847  ret = usbduxsub_stop(usbduxsub);
848  if (ret < 0) {
849  dev_err(&usbduxsub->interface->dev,
850  "comedi_: can not stop firmware\n");
851  kfree(fwBuf);
852  return ret;
853  }
854 
855  ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
856  if (ret < 0) {
857  dev_err(&usbduxsub->interface->dev,
858  "comedi_: firmware upload failed\n");
859  kfree(fwBuf);
860  return ret;
861  }
862  ret = usbduxsub_start(usbduxsub);
863  if (ret < 0) {
864  dev_err(&usbduxsub->interface->dev,
865  "comedi_: can not start firmware\n");
866  kfree(fwBuf);
867  return ret;
868  }
869  kfree(fwBuf);
870  return 0;
871 }
872 
873 static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub)
874 {
875  int i, errFlag;
876 
877  if (!usbduxsub)
878  return -EFAULT;
879 
880  /* Submit all URBs and start the transfer on the bus */
881  for (i = 0; i < usbduxsub->numOfInBuffers; i++) {
882  /* in case of a resubmission after an unlink... */
883  usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval;
884  usbduxsub->urbIn[i]->context = usbduxsub->comedidev;
885  usbduxsub->urbIn[i]->dev = usbduxsub->usbdev;
886  usbduxsub->urbIn[i]->status = 0;
887  usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP;
888  dev_dbg(&usbduxsub->interface->dev,
889  "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
890  usbduxsub->comedidev->minor, i,
891  (usbduxsub->urbIn[i]->context),
892  (usbduxsub->urbIn[i]->dev),
893  (usbduxsub->urbIn[i]->interval));
894  errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC);
895  if (errFlag) {
896  dev_err(&usbduxsub->interface->dev,
897  "comedi_: ai: usb_submit_urb(%d) error %d\n",
898  i, errFlag);
899  return errFlag;
900  }
901  }
902  return 0;
903 }
904 
905 static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
906 {
907  int i, errFlag;
908 
909  if (!usbduxsub)
910  return -EFAULT;
911 
912  for (i = 0; i < usbduxsub->numOfOutBuffers; i++) {
913  dev_dbg(&usbduxsub->interface->dev,
914  "comedi_: submitting out-urb[%d]\n", i);
915  /* in case of a resubmission after an unlink... */
916  usbduxsub->urbOut[i]->context = usbduxsub->comedidev;
917  usbduxsub->urbOut[i]->dev = usbduxsub->usbdev;
918  usbduxsub->urbOut[i]->status = 0;
919  usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP;
920  errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC);
921  if (errFlag) {
922  dev_err(&usbduxsub->interface->dev,
923  "comedi_: ao: usb_submit_urb(%d) error %d\n",
924  i, errFlag);
925  return errFlag;
926  }
927  }
928  return 0;
929 }
930 
931 static int usbdux_ai_cmdtest(struct comedi_device *dev,
932  struct comedi_subdevice *s, struct comedi_cmd *cmd)
933 {
934  struct usbduxsub *this_usbduxsub = dev->private;
935  int err = 0, i;
936  unsigned int tmpTimer;
937 
938  if (!(this_usbduxsub->probed))
939  return -ENODEV;
940 
941  dev_dbg(&this_usbduxsub->interface->dev,
942  "comedi%d: usbdux_ai_cmdtest\n", dev->minor);
943 
944  /* Step 1 : check if triggers are trivially valid */
945 
946  err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
947  err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
948  err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
949  err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
950  err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
951 
952  if (err)
953  return 1;
954 
955  /* Step 2a : make sure trigger sources are unique */
956 
957  err |= cfc_check_trigger_is_unique(cmd->start_src);
958  err |= cfc_check_trigger_is_unique(cmd->stop_src);
959 
960  /* Step 2b : and mutually compatible */
961 
962  if (err)
963  return 2;
964 
965  /* step 3: make sure arguments are trivially compatible */
966  if (cmd->start_arg != 0) {
967  cmd->start_arg = 0;
968  err++;
969  }
970 
971  if (cmd->scan_begin_src == TRIG_FOLLOW) {
972  /* internal trigger */
973  if (cmd->scan_begin_arg != 0) {
974  cmd->scan_begin_arg = 0;
975  err++;
976  }
977  }
978 
979  if (cmd->scan_begin_src == TRIG_TIMER) {
980  if (this_usbduxsub->high_speed) {
981  /*
982  * In high speed mode microframes are possible.
983  * However, during one microframe we can roughly
984  * sample one channel. Thus, the more channels
985  * are in the channel list the more time we need.
986  */
987  i = 1;
988  /* find a power of 2 for the number of channels */
989  while (i < (cmd->chanlist_len))
990  i = i * 2;
991 
992  if (cmd->scan_begin_arg < (1000000 / 8 * i)) {
993  cmd->scan_begin_arg = 1000000 / 8 * i;
994  err++;
995  }
996  /* now calc the real sampling rate with all the
997  * rounding errors */
998  tmpTimer =
999  ((unsigned int)(cmd->scan_begin_arg / 125000)) *
1000  125000;
1001  if (cmd->scan_begin_arg != tmpTimer) {
1002  cmd->scan_begin_arg = tmpTimer;
1003  err++;
1004  }
1005  } else {
1006  /* full speed */
1007  /* 1kHz scans every USB frame */
1008  if (cmd->scan_begin_arg < 1000000) {
1009  cmd->scan_begin_arg = 1000000;
1010  err++;
1011  }
1012  /*
1013  * calc the real sampling rate with the rounding errors
1014  */
1015  tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1016  1000000)) * 1000000;
1017  if (cmd->scan_begin_arg != tmpTimer) {
1018  cmd->scan_begin_arg = tmpTimer;
1019  err++;
1020  }
1021  }
1022  }
1023  /* the same argument */
1024  if (cmd->scan_end_arg != cmd->chanlist_len) {
1025  cmd->scan_end_arg = cmd->chanlist_len;
1026  err++;
1027  }
1028 
1029  if (cmd->stop_src == TRIG_COUNT) {
1030  /* any count is allowed */
1031  } else {
1032  /* TRIG_NONE */
1033  if (cmd->stop_arg != 0) {
1034  cmd->stop_arg = 0;
1035  err++;
1036  }
1037  }
1038 
1039  if (err)
1040  return 3;
1041 
1042  return 0;
1043 }
1044 
1045 /*
1046  * creates the ADC command for the MAX1271
1047  * range is the range value from comedi
1048  */
1049 static int8_t create_adc_command(unsigned int chan, int range)
1050 {
1051  int8_t p = (range <= 1);
1052  int8_t r = ((range % 2) == 0);
1053  return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
1054 }
1055 
1056 /* bulk transfers to usbdux */
1057 
1058 #define SENDADCOMMANDS 0
1059 #define SENDDACOMMANDS 1
1060 #define SENDDIOCONFIGCOMMAND 2
1061 #define SENDDIOBITSCOMMAND 3
1062 #define SENDSINGLEAD 4
1063 #define READCOUNTERCOMMAND 5
1064 #define WRITECOUNTERCOMMAND 6
1065 #define SENDPWMON 7
1066 #define SENDPWMOFF 8
1067 
1068 static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
1069 {
1070  int result, nsent;
1071 
1072  this_usbduxsub->dux_commands[0] = cmd_type;
1073 #ifdef NOISY_DUX_DEBUGBUG
1074  printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
1075  this_usbduxsub->comedidev->minor);
1076  for (result = 0; result < SIZEOFDUXBUFFER; result++)
1077  printk(" %02x", this_usbduxsub->dux_commands[result]);
1078  printk("\n");
1079 #endif
1080  result = usb_bulk_msg(this_usbduxsub->usbdev,
1081  usb_sndbulkpipe(this_usbduxsub->usbdev,
1082  COMMAND_OUT_EP),
1083  this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
1084  &nsent, BULK_TIMEOUT);
1085  if (result < 0)
1086  dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1087  "could not transmit dux_command to the usb-device, "
1088  "err=%d\n", this_usbduxsub->comedidev->minor, result);
1089 
1090  return result;
1091 }
1092 
1093 static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
1094 {
1095  int result = (-EFAULT);
1096  int nrec;
1097  int i;
1098 
1099  for (i = 0; i < RETRIES; i++) {
1100  result = usb_bulk_msg(this_usbduxsub->usbdev,
1101  usb_rcvbulkpipe(this_usbduxsub->usbdev,
1102  COMMAND_IN_EP),
1103  this_usbduxsub->insnBuffer, SIZEINSNBUF,
1104  &nrec, BULK_TIMEOUT);
1105  if (result < 0) {
1106  dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1107  "insn: USB error %d while receiving DUX command"
1108  "\n", this_usbduxsub->comedidev->minor, result);
1109  return result;
1110  }
1111  if (le16_to_cpu(this_usbduxsub->insnBuffer[0]) == command)
1112  return result;
1113  }
1114  /* this is only reached if the data has been requested a couple of
1115  * times */
1116  dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
1117  "wrong data returned from firmware: want cmd %d, got cmd %d.\n",
1118  this_usbduxsub->comedidev->minor, command,
1119  le16_to_cpu(this_usbduxsub->insnBuffer[0]));
1120  return -EFAULT;
1121 }
1122 
1123 static int usbdux_ai_inttrig(struct comedi_device *dev,
1124  struct comedi_subdevice *s, unsigned int trignum)
1125 {
1126  int ret;
1127  struct usbduxsub *this_usbduxsub = dev->private;
1128  if (!this_usbduxsub)
1129  return -EFAULT;
1130 
1131  down(&this_usbduxsub->sem);
1132  if (!(this_usbduxsub->probed)) {
1133  up(&this_usbduxsub->sem);
1134  return -ENODEV;
1135  }
1136  dev_dbg(&this_usbduxsub->interface->dev,
1137  "comedi%d: usbdux_ai_inttrig\n", dev->minor);
1138 
1139  if (trignum != 0) {
1140  dev_err(&this_usbduxsub->interface->dev,
1141  "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
1142  dev->minor);
1143  up(&this_usbduxsub->sem);
1144  return -EINVAL;
1145  }
1146  if (!(this_usbduxsub->ai_cmd_running)) {
1147  this_usbduxsub->ai_cmd_running = 1;
1148  ret = usbduxsub_submit_InURBs(this_usbduxsub);
1149  if (ret < 0) {
1150  dev_err(&this_usbduxsub->interface->dev,
1151  "comedi%d: usbdux_ai_inttrig: "
1152  "urbSubmit: err=%d\n", dev->minor, ret);
1153  this_usbduxsub->ai_cmd_running = 0;
1154  up(&this_usbduxsub->sem);
1155  return ret;
1156  }
1157  s->async->inttrig = NULL;
1158  } else {
1159  dev_err(&this_usbduxsub->interface->dev,
1160  "comedi%d: ai_inttrig but acqu is already running\n",
1161  dev->minor);
1162  }
1163  up(&this_usbduxsub->sem);
1164  return 1;
1165 }
1166 
1167 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1168 {
1169  struct comedi_cmd *cmd = &s->async->cmd;
1170  unsigned int chan, range;
1171  int i, ret;
1172  struct usbduxsub *this_usbduxsub = dev->private;
1173  int result;
1174 
1175  if (!this_usbduxsub)
1176  return -EFAULT;
1177 
1178  dev_dbg(&this_usbduxsub->interface->dev,
1179  "comedi%d: usbdux_ai_cmd\n", dev->minor);
1180 
1181  /* block other CPUs from starting an ai_cmd */
1182  down(&this_usbduxsub->sem);
1183 
1184  if (!(this_usbduxsub->probed)) {
1185  up(&this_usbduxsub->sem);
1186  return -ENODEV;
1187  }
1188  if (this_usbduxsub->ai_cmd_running) {
1189  dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1190  "ai_cmd not possible. Another ai_cmd is running.\n",
1191  dev->minor);
1192  up(&this_usbduxsub->sem);
1193  return -EBUSY;
1194  }
1195  /* set current channel of the running acquisition to zero */
1196  s->async->cur_chan = 0;
1197 
1198  this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
1199  for (i = 0; i < cmd->chanlist_len; ++i) {
1200  chan = CR_CHAN(cmd->chanlist[i]);
1201  range = CR_RANGE(cmd->chanlist[i]);
1202  if (i >= NUMCHANNELS) {
1203  dev_err(&this_usbduxsub->interface->dev,
1204  "comedi%d: channel list too long\n",
1205  dev->minor);
1206  break;
1207  }
1208  this_usbduxsub->dux_commands[i + 2] =
1209  create_adc_command(chan, range);
1210  }
1211 
1212  dev_dbg(&this_usbduxsub->interface->dev,
1213  "comedi %d: sending commands to the usb device: size=%u\n",
1214  dev->minor, NUMCHANNELS);
1215 
1216  result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1217  if (result < 0) {
1218  up(&this_usbduxsub->sem);
1219  return result;
1220  }
1221 
1222  if (this_usbduxsub->high_speed) {
1223  /*
1224  * every channel gets a time window of 125us. Thus, if we
1225  * sample all 8 channels we need 1ms. If we sample only one
1226  * channel we need only 125us
1227  */
1228  this_usbduxsub->ai_interval = 1;
1229  /* find a power of 2 for the interval */
1230  while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
1231  this_usbduxsub->ai_interval =
1232  (this_usbduxsub->ai_interval) * 2;
1233  }
1234  this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1235  (this_usbduxsub->
1236  ai_interval));
1237  } else {
1238  /* interval always 1ms */
1239  this_usbduxsub->ai_interval = 1;
1240  this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1241  }
1242  if (this_usbduxsub->ai_timer < 1) {
1243  dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1244  "timer=%d, scan_begin_arg=%d. "
1245  "Not properly tested by cmdtest?\n", dev->minor,
1246  this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1247  up(&this_usbduxsub->sem);
1248  return -EINVAL;
1249  }
1250  this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1251 
1252  if (cmd->stop_src == TRIG_COUNT) {
1253  /* data arrives as one packet */
1254  this_usbduxsub->ai_sample_count = cmd->stop_arg;
1255  this_usbduxsub->ai_continous = 0;
1256  } else {
1257  /* continous acquisition */
1258  this_usbduxsub->ai_continous = 1;
1259  this_usbduxsub->ai_sample_count = 0;
1260  }
1261 
1262  if (cmd->start_src == TRIG_NOW) {
1263  /* enable this acquisition operation */
1264  this_usbduxsub->ai_cmd_running = 1;
1265  ret = usbduxsub_submit_InURBs(this_usbduxsub);
1266  if (ret < 0) {
1267  this_usbduxsub->ai_cmd_running = 0;
1268  /* fixme: unlink here?? */
1269  up(&this_usbduxsub->sem);
1270  return ret;
1271  }
1272  s->async->inttrig = NULL;
1273  } else {
1274  /* TRIG_INT */
1275  /* don't enable the acquision operation */
1276  /* wait for an internal signal */
1277  s->async->inttrig = usbdux_ai_inttrig;
1278  }
1279  up(&this_usbduxsub->sem);
1280  return 0;
1281 }
1282 
1283 /* Mode 0 is used to get a single conversion on demand */
1284 static int usbdux_ai_insn_read(struct comedi_device *dev,
1285  struct comedi_subdevice *s,
1286  struct comedi_insn *insn, unsigned int *data)
1287 {
1288  int i;
1289  unsigned int one = 0;
1290  int chan, range;
1291  int err;
1292  struct usbduxsub *this_usbduxsub = dev->private;
1293 
1294  if (!this_usbduxsub)
1295  return 0;
1296 
1297  dev_dbg(&this_usbduxsub->interface->dev,
1298  "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1299  dev->minor, insn->n, insn->subdev);
1300 
1301  down(&this_usbduxsub->sem);
1302  if (!(this_usbduxsub->probed)) {
1303  up(&this_usbduxsub->sem);
1304  return -ENODEV;
1305  }
1306  if (this_usbduxsub->ai_cmd_running) {
1307  dev_err(&this_usbduxsub->interface->dev,
1308  "comedi%d: ai_insn_read not possible. "
1309  "Async Command is running.\n", dev->minor);
1310  up(&this_usbduxsub->sem);
1311  return 0;
1312  }
1313 
1314  /* sample one channel */
1315  chan = CR_CHAN(insn->chanspec);
1316  range = CR_RANGE(insn->chanspec);
1317  /* set command for the first channel */
1318  this_usbduxsub->dux_commands[1] = create_adc_command(chan, range);
1319 
1320  /* adc commands */
1321  err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1322  if (err < 0) {
1323  up(&this_usbduxsub->sem);
1324  return err;
1325  }
1326 
1327  for (i = 0; i < insn->n; i++) {
1328  err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1329  if (err < 0) {
1330  up(&this_usbduxsub->sem);
1331  return 0;
1332  }
1333  one = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
1334  if (CR_RANGE(insn->chanspec) <= 1)
1335  one = one ^ 0x800;
1336 
1337  data[i] = one;
1338  }
1339  up(&this_usbduxsub->sem);
1340  return i;
1341 }
1342 
1343 /************************************/
1344 /* analog out */
1345 
1346 static int usbdux_ao_insn_read(struct comedi_device *dev,
1347  struct comedi_subdevice *s,
1348  struct comedi_insn *insn, unsigned int *data)
1349 {
1350  int i;
1351  int chan = CR_CHAN(insn->chanspec);
1352  struct usbduxsub *this_usbduxsub = dev->private;
1353 
1354  if (!this_usbduxsub)
1355  return -EFAULT;
1356 
1357  down(&this_usbduxsub->sem);
1358  if (!(this_usbduxsub->probed)) {
1359  up(&this_usbduxsub->sem);
1360  return -ENODEV;
1361  }
1362  for (i = 0; i < insn->n; i++)
1363  data[i] = this_usbduxsub->outBuffer[chan];
1364 
1365  up(&this_usbduxsub->sem);
1366  return i;
1367 }
1368 
1369 static int usbdux_ao_insn_write(struct comedi_device *dev,
1370  struct comedi_subdevice *s,
1371  struct comedi_insn *insn, unsigned int *data)
1372 {
1373  int i, err;
1374  int chan = CR_CHAN(insn->chanspec);
1375  struct usbduxsub *this_usbduxsub = dev->private;
1376 
1377  if (!this_usbduxsub)
1378  return -EFAULT;
1379 
1380  dev_dbg(&this_usbduxsub->interface->dev,
1381  "comedi%d: ao_insn_write\n", dev->minor);
1382 
1383  down(&this_usbduxsub->sem);
1384  if (!(this_usbduxsub->probed)) {
1385  up(&this_usbduxsub->sem);
1386  return -ENODEV;
1387  }
1388  if (this_usbduxsub->ao_cmd_running) {
1389  dev_err(&this_usbduxsub->interface->dev,
1390  "comedi%d: ao_insn_write: "
1391  "ERROR: asynchronous ao_cmd is running\n", dev->minor);
1392  up(&this_usbduxsub->sem);
1393  return 0;
1394  }
1395 
1396  for (i = 0; i < insn->n; i++) {
1397  dev_dbg(&this_usbduxsub->interface->dev,
1398  "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1399  dev->minor, chan, i, data[i]);
1400 
1401  /* number of channels: 1 */
1402  this_usbduxsub->dux_commands[1] = 1;
1403  /* one 16 bit value */
1404  *((int16_t *) (this_usbduxsub->dux_commands + 2)) =
1405  cpu_to_le16(data[i]);
1406  this_usbduxsub->outBuffer[chan] = data[i];
1407  /* channel number */
1408  this_usbduxsub->dux_commands[4] = (chan << 6);
1409  err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1410  if (err < 0) {
1411  up(&this_usbduxsub->sem);
1412  return err;
1413  }
1414  }
1415  up(&this_usbduxsub->sem);
1416 
1417  return i;
1418 }
1419 
1420 static int usbdux_ao_inttrig(struct comedi_device *dev,
1421  struct comedi_subdevice *s, unsigned int trignum)
1422 {
1423  int ret;
1424  struct usbduxsub *this_usbduxsub = dev->private;
1425 
1426  if (!this_usbduxsub)
1427  return -EFAULT;
1428 
1429  down(&this_usbduxsub->sem);
1430  if (!(this_usbduxsub->probed)) {
1431  up(&this_usbduxsub->sem);
1432  return -ENODEV;
1433  }
1434  if (trignum != 0) {
1435  dev_err(&this_usbduxsub->interface->dev,
1436  "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1437  dev->minor);
1438  up(&this_usbduxsub->sem);
1439  return -EINVAL;
1440  }
1441  if (!(this_usbduxsub->ao_cmd_running)) {
1442  this_usbduxsub->ao_cmd_running = 1;
1443  ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1444  if (ret < 0) {
1445  dev_err(&this_usbduxsub->interface->dev,
1446  "comedi%d: usbdux_ao_inttrig: submitURB: "
1447  "err=%d\n", dev->minor, ret);
1448  this_usbduxsub->ao_cmd_running = 0;
1449  up(&this_usbduxsub->sem);
1450  return ret;
1451  }
1452  s->async->inttrig = NULL;
1453  } else {
1454  dev_err(&this_usbduxsub->interface->dev,
1455  "comedi%d: ao_inttrig but acqu is already running.\n",
1456  dev->minor);
1457  }
1458  up(&this_usbduxsub->sem);
1459  return 1;
1460 }
1461 
1462 static int usbdux_ao_cmdtest(struct comedi_device *dev,
1463  struct comedi_subdevice *s, struct comedi_cmd *cmd)
1464 {
1465  struct usbduxsub *this_usbduxsub = dev->private;
1466  int err = 0;
1467  unsigned int flags;
1468 
1469  if (!this_usbduxsub)
1470  return -EFAULT;
1471 
1472  if (!(this_usbduxsub->probed))
1473  return -ENODEV;
1474 
1475  dev_dbg(&this_usbduxsub->interface->dev,
1476  "comedi%d: usbdux_ao_cmdtest\n", dev->minor);
1477 
1478  /* Step 1 : check if triggers are trivially valid */
1479 
1480  err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1481 
1482  if (0) { /* (this_usbduxsub->high_speed) */
1483  /* the sampling rate is set by the coversion rate */
1484  flags = TRIG_FOLLOW;
1485  } else {
1486  /* start a new scan (output at once) with a timer */
1487  flags = TRIG_TIMER;
1488  }
1489  err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1490 
1491  if (0) { /* (this_usbduxsub->high_speed) */
1492  /*
1493  * in usb-2.0 only one conversion it transmitted
1494  * but with 8kHz/n
1495  */
1496  flags = TRIG_TIMER;
1497  } else {
1498  /*
1499  * all conversion events happen simultaneously with
1500  * a rate of 1kHz/n
1501  */
1502  flags = TRIG_NOW;
1503  }
1504  err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1505 
1506  err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1507  err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1508 
1509  if (err)
1510  return 1;
1511 
1512  /* Step 2a : make sure trigger sources are unique */
1513 
1514  err |= cfc_check_trigger_is_unique(cmd->start_src);
1515  err |= cfc_check_trigger_is_unique(cmd->stop_src);
1516 
1517  /* Step 2b : and mutually compatible */
1518 
1519  if (err)
1520  return 2;
1521 
1522  /* step 3: make sure arguments are trivially compatible */
1523 
1524  if (cmd->start_arg != 0) {
1525  cmd->start_arg = 0;
1526  err++;
1527  }
1528 
1529  if (cmd->scan_begin_src == TRIG_FOLLOW) {
1530  /* internal trigger */
1531  if (cmd->scan_begin_arg != 0) {
1532  cmd->scan_begin_arg = 0;
1533  err++;
1534  }
1535  }
1536 
1537  if (cmd->scan_begin_src == TRIG_TIMER) {
1538  /* timer */
1539  if (cmd->scan_begin_arg < 1000000) {
1540  cmd->scan_begin_arg = 1000000;
1541  err++;
1542  }
1543  }
1544  /* not used now, is for later use */
1545  if (cmd->convert_src == TRIG_TIMER) {
1546  if (cmd->convert_arg < 125000) {
1547  cmd->convert_arg = 125000;
1548  err++;
1549  }
1550  }
1551 
1552  /* the same argument */
1553  if (cmd->scan_end_arg != cmd->chanlist_len) {
1554  cmd->scan_end_arg = cmd->chanlist_len;
1555  err++;
1556  }
1557 
1558  if (cmd->stop_src == TRIG_COUNT) {
1559  /* any count is allowed */
1560  } else {
1561  /* TRIG_NONE */
1562  if (cmd->stop_arg != 0) {
1563  cmd->stop_arg = 0;
1564  err++;
1565  }
1566  }
1567 
1568  dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
1569  "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
1570  "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
1571  cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
1572 
1573  if (err)
1574  return 3;
1575 
1576  return 0;
1577 }
1578 
1579 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1580 {
1581  struct comedi_cmd *cmd = &s->async->cmd;
1582  unsigned int chan, gain;
1583  int i, ret;
1584  struct usbduxsub *this_usbduxsub = dev->private;
1585 
1586  if (!this_usbduxsub)
1587  return -EFAULT;
1588 
1589  down(&this_usbduxsub->sem);
1590  if (!(this_usbduxsub->probed)) {
1591  up(&this_usbduxsub->sem);
1592  return -ENODEV;
1593  }
1594  dev_dbg(&this_usbduxsub->interface->dev,
1595  "comedi%d: %s\n", dev->minor, __func__);
1596 
1597  /* set current channel of the running acquisition to zero */
1598  s->async->cur_chan = 0;
1599  for (i = 0; i < cmd->chanlist_len; ++i) {
1600  chan = CR_CHAN(cmd->chanlist[i]);
1601  gain = CR_RANGE(cmd->chanlist[i]);
1602  if (i >= NUMOUTCHANNELS) {
1603  dev_err(&this_usbduxsub->interface->dev,
1604  "comedi%d: %s: channel list too long\n",
1605  dev->minor, __func__);
1606  break;
1607  }
1608  this_usbduxsub->dac_commands[i] = (chan << 6);
1609  dev_dbg(&this_usbduxsub->interface->dev,
1610  "comedi%d: dac command for ch %d is %x\n",
1611  dev->minor, i, this_usbduxsub->dac_commands[i]);
1612  }
1613 
1614  /* we count in steps of 1ms (125us) */
1615  /* 125us mode not used yet */
1616  if (0) { /* (this_usbduxsub->high_speed) */
1617  /* 125us */
1618  /* timing of the conversion itself: every 125 us */
1619  this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1620  } else {
1621  /* 1ms */
1622  /* timing of the scan: we get all channels at once */
1623  this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1624  dev_dbg(&this_usbduxsub->interface->dev,
1625  "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1626  "convert_src=%d, convert_arg=%d\n", dev->minor,
1627  cmd->scan_begin_src, cmd->scan_begin_arg,
1628  cmd->convert_src, cmd->convert_arg);
1629  dev_dbg(&this_usbduxsub->interface->dev,
1630  "comedi%d: ao_timer=%d (ms)\n",
1631  dev->minor, this_usbduxsub->ao_timer);
1632  if (this_usbduxsub->ao_timer < 1) {
1633  dev_err(&this_usbduxsub->interface->dev,
1634  "comedi%d: usbdux: ao_timer=%d, "
1635  "scan_begin_arg=%d. "
1636  "Not properly tested by cmdtest?\n",
1637  dev->minor, this_usbduxsub->ao_timer,
1638  cmd->scan_begin_arg);
1639  up(&this_usbduxsub->sem);
1640  return -EINVAL;
1641  }
1642  }
1643  this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1644 
1645  if (cmd->stop_src == TRIG_COUNT) {
1646  /* not continuous */
1647  /* counter */
1648  /* high speed also scans everything at once */
1649  if (0) { /* (this_usbduxsub->high_speed) */
1650  this_usbduxsub->ao_sample_count =
1651  (cmd->stop_arg) * (cmd->scan_end_arg);
1652  } else {
1653  /* there's no scan as the scan has been */
1654  /* perf inside the FX2 */
1655  /* data arrives as one packet */
1656  this_usbduxsub->ao_sample_count = cmd->stop_arg;
1657  }
1658  this_usbduxsub->ao_continous = 0;
1659  } else {
1660  /* continous acquisition */
1661  this_usbduxsub->ao_continous = 1;
1662  this_usbduxsub->ao_sample_count = 0;
1663  }
1664 
1665  if (cmd->start_src == TRIG_NOW) {
1666  /* enable this acquisition operation */
1667  this_usbduxsub->ao_cmd_running = 1;
1668  ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1669  if (ret < 0) {
1670  this_usbduxsub->ao_cmd_running = 0;
1671  /* fixme: unlink here?? */
1672  up(&this_usbduxsub->sem);
1673  return ret;
1674  }
1675  s->async->inttrig = NULL;
1676  } else {
1677  /* TRIG_INT */
1678  /* submit the urbs later */
1679  /* wait for an internal signal */
1680  s->async->inttrig = usbdux_ao_inttrig;
1681  }
1682 
1683  up(&this_usbduxsub->sem);
1684  return 0;
1685 }
1686 
1687 static int usbdux_dio_insn_config(struct comedi_device *dev,
1688  struct comedi_subdevice *s,
1689  struct comedi_insn *insn, unsigned int *data)
1690 {
1691  int chan = CR_CHAN(insn->chanspec);
1692 
1693  /* The input or output configuration of each digital line is
1694  * configured by a special insn_config instruction. chanspec
1695  * contains the channel to be changed, and data[0] contains the
1696  * value COMEDI_INPUT or COMEDI_OUTPUT. */
1697 
1698  switch (data[0]) {
1700  s->io_bits |= 1 << chan; /* 1 means Out */
1701  break;
1702  case INSN_CONFIG_DIO_INPUT:
1703  s->io_bits &= ~(1 << chan);
1704  break;
1705  case INSN_CONFIG_DIO_QUERY:
1706  data[1] =
1707  (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1708  break;
1709  default:
1710  return -EINVAL;
1711  break;
1712  }
1713  /* we don't tell the firmware here as it would take 8 frames */
1714  /* to submit the information. We do it in the insn_bits. */
1715  return insn->n;
1716 }
1717 
1718 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1719  struct comedi_subdevice *s,
1720  struct comedi_insn *insn, unsigned int *data)
1721 {
1722 
1723  struct usbduxsub *this_usbduxsub = dev->private;
1724  int err;
1725 
1726  if (!this_usbduxsub)
1727  return -EFAULT;
1728 
1729  down(&this_usbduxsub->sem);
1730 
1731  if (!(this_usbduxsub->probed)) {
1732  up(&this_usbduxsub->sem);
1733  return -ENODEV;
1734  }
1735 
1736  /* The insn data is a mask in data[0] and the new data
1737  * in data[1], each channel cooresponding to a bit. */
1738  s->state &= ~data[0];
1739  s->state |= data[0] & data[1];
1740  this_usbduxsub->dux_commands[1] = s->io_bits;
1741  this_usbduxsub->dux_commands[2] = s->state;
1742 
1743  /* This command also tells the firmware to return */
1744  /* the digital input lines */
1745  err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1746  if (err < 0) {
1747  up(&this_usbduxsub->sem);
1748  return err;
1749  }
1750  err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1751  if (err < 0) {
1752  up(&this_usbduxsub->sem);
1753  return err;
1754  }
1755 
1756  data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
1757  up(&this_usbduxsub->sem);
1758  return insn->n;
1759 }
1760 
1761 /* reads the 4 counters, only two are used just now */
1762 static int usbdux_counter_read(struct comedi_device *dev,
1763  struct comedi_subdevice *s,
1764  struct comedi_insn *insn, unsigned int *data)
1765 {
1766  struct usbduxsub *this_usbduxsub = dev->private;
1767  int chan = insn->chanspec;
1768  int err;
1769 
1770  if (!this_usbduxsub)
1771  return -EFAULT;
1772 
1773  down(&this_usbduxsub->sem);
1774 
1775  if (!(this_usbduxsub->probed)) {
1776  up(&this_usbduxsub->sem);
1777  return -ENODEV;
1778  }
1779 
1780  err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1781  if (err < 0) {
1782  up(&this_usbduxsub->sem);
1783  return err;
1784  }
1785 
1786  err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1787  if (err < 0) {
1788  up(&this_usbduxsub->sem);
1789  return err;
1790  }
1791 
1792  data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]);
1793  up(&this_usbduxsub->sem);
1794  return 1;
1795 }
1796 
1797 static int usbdux_counter_write(struct comedi_device *dev,
1798  struct comedi_subdevice *s,
1799  struct comedi_insn *insn, unsigned int *data)
1800 {
1801  struct usbduxsub *this_usbduxsub = dev->private;
1802  int err;
1803 
1804  if (!this_usbduxsub)
1805  return -EFAULT;
1806 
1807  down(&this_usbduxsub->sem);
1808 
1809  if (!(this_usbduxsub->probed)) {
1810  up(&this_usbduxsub->sem);
1811  return -ENODEV;
1812  }
1813 
1814  this_usbduxsub->dux_commands[1] = insn->chanspec;
1815  *((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1816 
1817  err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1818  if (err < 0) {
1819  up(&this_usbduxsub->sem);
1820  return err;
1821  }
1822 
1823  up(&this_usbduxsub->sem);
1824 
1825  return 1;
1826 }
1827 
1828 static int usbdux_counter_config(struct comedi_device *dev,
1829  struct comedi_subdevice *s,
1830  struct comedi_insn *insn, unsigned int *data)
1831 {
1832  /* nothing to do so far */
1833  return 2;
1834 }
1835 
1836 /***********************************/
1837 /* PWM */
1838 
1839 static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
1840 {
1841  int err = 0;
1842 
1843  if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
1844  if (usbduxsub_tmp->urbPwm)
1845  usb_kill_urb(usbduxsub_tmp->urbPwm);
1846  dev_dbg(&usbduxsub_tmp->interface->dev,
1847  "comedi: unlinked PwmURB: res=%d\n", err);
1848  }
1849  return err;
1850 }
1851 
1852 /* This cancels a running acquisition operation
1853  * in any context.
1854  */
1855 static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
1856 {
1857  int ret = 0;
1858 
1859  if (!this_usbduxsub)
1860  return -EFAULT;
1861 
1862  dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1863  if (do_unlink)
1864  ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
1865 
1866  this_usbduxsub->pwm_cmd_running = 0;
1867 
1868  return ret;
1869 }
1870 
1871 /* force unlink - is called by comedi */
1872 static int usbdux_pwm_cancel(struct comedi_device *dev,
1873  struct comedi_subdevice *s)
1874 {
1875  struct usbduxsub *this_usbduxsub = dev->private;
1876  int res = 0;
1877 
1878  /* unlink only if it is really running */
1879  res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1880 
1881  dev_dbg(&this_usbduxsub->interface->dev,
1882  "comedi %d: sending pwm off command to the usb device.\n",
1883  dev->minor);
1884 
1885  return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1886 }
1887 
1888 static void usbduxsub_pwm_irq(struct urb *urb)
1889 {
1890  int ret;
1891  struct usbduxsub *this_usbduxsub;
1892  struct comedi_device *this_comedidev;
1893  struct comedi_subdevice *s;
1894 
1895  /* printk(KERN_DEBUG "PWM: IRQ\n"); */
1896 
1897  /* the context variable points to the subdevice */
1898  this_comedidev = urb->context;
1899  /* the private structure of the subdevice is struct usbduxsub */
1900  this_usbduxsub = this_comedidev->private;
1901 
1902  s = &this_comedidev->subdevices[SUBDEV_DA];
1903 
1904  switch (urb->status) {
1905  case 0:
1906  /* success */
1907  break;
1908 
1909  case -ECONNRESET:
1910  case -ENOENT:
1911  case -ESHUTDOWN:
1912  case -ECONNABORTED:
1913  /*
1914  * after an unlink command, unplug, ... etc
1915  * no unlink needed here. Already shutting down.
1916  */
1917  if (this_usbduxsub->pwm_cmd_running)
1918  usbdux_pwm_stop(this_usbduxsub, 0);
1919 
1920  return;
1921 
1922  default:
1923  /* a real error */
1924  if (this_usbduxsub->pwm_cmd_running) {
1925  dev_err(&this_usbduxsub->interface->dev,
1926  "comedi_: Non-zero urb status received in "
1927  "pwm intr context: %d\n", urb->status);
1928  usbdux_pwm_stop(this_usbduxsub, 0);
1929  }
1930  return;
1931  }
1932 
1933  /* are we actually running? */
1934  if (!(this_usbduxsub->pwm_cmd_running))
1935  return;
1936 
1937  urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
1938  urb->dev = this_usbduxsub->usbdev;
1939  urb->status = 0;
1940  if (this_usbduxsub->pwm_cmd_running) {
1941  ret = usb_submit_urb(urb, GFP_ATOMIC);
1942  if (ret < 0) {
1943  dev_err(&this_usbduxsub->interface->dev,
1944  "comedi_: pwm urb resubm failed in int-cont. "
1945  "ret=%d", ret);
1946  if (ret == EL2NSYNC)
1947  dev_err(&this_usbduxsub->interface->dev,
1948  "buggy USB host controller or bug in "
1949  "IRQ handling!\n");
1950 
1951  /* don't do an unlink here */
1952  usbdux_pwm_stop(this_usbduxsub, 0);
1953  }
1954  }
1955 }
1956 
1957 static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
1958 {
1959  int errFlag;
1960 
1961  if (!usbduxsub)
1962  return -EFAULT;
1963 
1964  dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
1965 
1966  /* in case of a resubmission after an unlink... */
1967  usb_fill_bulk_urb(usbduxsub->urbPwm,
1968  usbduxsub->usbdev,
1969  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
1970  usbduxsub->urbPwm->transfer_buffer,
1971  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
1972  usbduxsub->comedidev);
1973 
1974  errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
1975  if (errFlag) {
1976  dev_err(&usbduxsub->interface->dev,
1977  "comedi_: usbdux: pwm: usb_submit_urb error %d\n",
1978  errFlag);
1979  return errFlag;
1980  }
1981  return 0;
1982 }
1983 
1984 static int usbdux_pwm_period(struct comedi_device *dev,
1985  struct comedi_subdevice *s, unsigned int period)
1986 {
1987  struct usbduxsub *this_usbduxsub = dev->private;
1988  int fx2delay = 255;
1989 
1990  if (period < MIN_PWM_PERIOD) {
1991  dev_err(&this_usbduxsub->interface->dev,
1992  "comedi%d: illegal period setting for pwm.\n",
1993  dev->minor);
1994  return -EAGAIN;
1995  } else {
1996  fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
1997  if (fx2delay > 255) {
1998  dev_err(&this_usbduxsub->interface->dev,
1999  "comedi%d: period %d for pwm is too low.\n",
2000  dev->minor, period);
2001  return -EAGAIN;
2002  }
2003  }
2004  this_usbduxsub->pwmDelay = fx2delay;
2005  this_usbduxsub->pwmPeriod = period;
2006  dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
2007  __func__, period, fx2delay);
2008  return 0;
2009 }
2010 
2011 /* is called from insn so there's no need to do all the sanity checks */
2012 static int usbdux_pwm_start(struct comedi_device *dev,
2013  struct comedi_subdevice *s)
2014 {
2015  int ret, i;
2016  struct usbduxsub *this_usbduxsub = dev->private;
2017 
2018  dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
2019  dev->minor, __func__);
2020 
2021  if (this_usbduxsub->pwm_cmd_running) {
2022  /* already running */
2023  return 0;
2024  }
2025 
2026  this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay);
2027  ret = send_dux_commands(this_usbduxsub, SENDPWMON);
2028  if (ret < 0)
2029  return ret;
2030 
2031  /* initialise the buffer */
2032  for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
2033  ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
2034 
2035  this_usbduxsub->pwm_cmd_running = 1;
2036  ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2037  if (ret < 0) {
2038  this_usbduxsub->pwm_cmd_running = 0;
2039  return ret;
2040  }
2041  return 0;
2042 }
2043 
2044 /* generates the bit pattern for PWM with the optional sign bit */
2045 static int usbdux_pwm_pattern(struct comedi_device *dev,
2046  struct comedi_subdevice *s, int channel,
2047  unsigned int value, unsigned int sign)
2048 {
2049  struct usbduxsub *this_usbduxsub = dev->private;
2050  int i, szbuf;
2051  char *pBuf;
2052  char pwm_mask;
2053  char sgn_mask;
2054  char c;
2055 
2056  if (!this_usbduxsub)
2057  return -EFAULT;
2058 
2059  /* this is the DIO bit which carries the PWM data */
2060  pwm_mask = (1 << channel);
2061  /* this is the DIO bit which carries the optional direction bit */
2062  sgn_mask = (16 << channel);
2063  /* this is the buffer which will be filled with the with bit */
2064  /* pattern for one period */
2065  szbuf = this_usbduxsub->sizePwmBuf;
2066  pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
2067  for (i = 0; i < szbuf; i++) {
2068  c = *pBuf;
2069  /* reset bits */
2070  c = c & (~pwm_mask);
2071  /* set the bit as long as the index is lower than the value */
2072  if (i < value)
2073  c = c | pwm_mask;
2074  /* set the optional sign bit for a relay */
2075  if (!sign) {
2076  /* positive value */
2077  c = c & (~sgn_mask);
2078  } else {
2079  /* negative value */
2080  c = c | sgn_mask;
2081  }
2082  *(pBuf++) = c;
2083  }
2084  return 1;
2085 }
2086 
2087 static int usbdux_pwm_write(struct comedi_device *dev,
2088  struct comedi_subdevice *s,
2089  struct comedi_insn *insn, unsigned int *data)
2090 {
2091  struct usbduxsub *this_usbduxsub = dev->private;
2092 
2093  if (!this_usbduxsub)
2094  return -EFAULT;
2095 
2096  if ((insn->n) != 1) {
2097  /*
2098  * doesn't make sense to have more than one value here because
2099  * it would just overwrite the PWM buffer a couple of times
2100  */
2101  return -EINVAL;
2102  }
2103 
2104  /*
2105  * the sign is set via a special INSN only, this gives us 8 bits for
2106  * normal operation
2107  * relay sign 0 by default
2108  */
2109  return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2110 }
2111 
2112 static int usbdux_pwm_read(struct comedi_device *x1,
2113  struct comedi_subdevice *x2, struct comedi_insn *x3,
2114  unsigned int *x4)
2115 {
2116  /* not needed */
2117  return -EINVAL;
2118 };
2119 
2120 /* switches on/off PWM */
2121 static int usbdux_pwm_config(struct comedi_device *dev,
2122  struct comedi_subdevice *s,
2123  struct comedi_insn *insn, unsigned int *data)
2124 {
2125  struct usbduxsub *this_usbduxsub = dev->private;
2126  switch (data[0]) {
2127  case INSN_CONFIG_ARM:
2128  /* switch it on */
2129  dev_dbg(&this_usbduxsub->interface->dev,
2130  "comedi%d: %s: pwm on\n", dev->minor, __func__);
2131  /*
2132  * if not zero the PWM is limited to a certain time which is
2133  * not supported here
2134  */
2135  if (data[1] != 0)
2136  return -EINVAL;
2137  return usbdux_pwm_start(dev, s);
2138  case INSN_CONFIG_DISARM:
2139  dev_dbg(&this_usbduxsub->interface->dev,
2140  "comedi%d: %s: pwm off\n", dev->minor, __func__);
2141  return usbdux_pwm_cancel(dev, s);
2143  /*
2144  * to check if the USB transmission has failed or in case PWM
2145  * was limited to n cycles to check if it has terminated
2146  */
2147  data[1] = this_usbduxsub->pwm_cmd_running;
2148  return 0;
2150  dev_dbg(&this_usbduxsub->interface->dev,
2151  "comedi%d: %s: setting period\n", dev->minor, __func__);
2152  return usbdux_pwm_period(dev, s, data[1]);
2154  data[1] = this_usbduxsub->pwmPeriod;
2155  return 0;
2157  /* value in the first byte and the sign in the second for a
2158  relay */
2159  return usbdux_pwm_pattern(dev, s,
2160  /* the channel number */
2161  CR_CHAN(insn->chanspec),
2162  /* actual PWM data */
2163  data[1],
2164  /* just a sign */
2165  (data[2] != 0));
2167  /* values are not kept in this driver, nothing to return here */
2168  return -EINVAL;
2169  }
2170  return -EINVAL;
2171 }
2172 
2173 /* end of PWM */
2174 /*****************************************************************/
2175 
2176 static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2177 {
2178  int i;
2179 
2180  if (!usbduxsub_tmp)
2181  return;
2182  dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2183 
2184  /* shows the usb subsystem that the driver is down */
2185  if (usbduxsub_tmp->interface)
2186  usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2187 
2188  usbduxsub_tmp->probed = 0;
2189 
2190  if (usbduxsub_tmp->urbIn) {
2191  if (usbduxsub_tmp->ai_cmd_running) {
2192  usbduxsub_tmp->ai_cmd_running = 0;
2193  usbduxsub_unlink_InURBs(usbduxsub_tmp);
2194  }
2195  for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
2196  kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
2197  usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
2198  usb_kill_urb(usbduxsub_tmp->urbIn[i]);
2199  usb_free_urb(usbduxsub_tmp->urbIn[i]);
2200  usbduxsub_tmp->urbIn[i] = NULL;
2201  }
2202  kfree(usbduxsub_tmp->urbIn);
2203  usbduxsub_tmp->urbIn = NULL;
2204  }
2205  if (usbduxsub_tmp->urbOut) {
2206  if (usbduxsub_tmp->ao_cmd_running) {
2207  usbduxsub_tmp->ao_cmd_running = 0;
2208  usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2209  }
2210  for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
2211  kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer);
2212  usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL;
2213  if (usbduxsub_tmp->urbOut[i]) {
2214  usb_kill_urb(usbduxsub_tmp->urbOut[i]);
2215  usb_free_urb(usbduxsub_tmp->urbOut[i]);
2216  usbduxsub_tmp->urbOut[i] = NULL;
2217  }
2218  }
2219  kfree(usbduxsub_tmp->urbOut);
2220  usbduxsub_tmp->urbOut = NULL;
2221  }
2222  if (usbduxsub_tmp->urbPwm) {
2223  if (usbduxsub_tmp->pwm_cmd_running) {
2224  usbduxsub_tmp->pwm_cmd_running = 0;
2225  usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2226  }
2227  kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
2228  usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
2229  usb_kill_urb(usbduxsub_tmp->urbPwm);
2230  usb_free_urb(usbduxsub_tmp->urbPwm);
2231  usbduxsub_tmp->urbPwm = NULL;
2232  }
2233  kfree(usbduxsub_tmp->inBuffer);
2234  usbduxsub_tmp->inBuffer = NULL;
2235  kfree(usbduxsub_tmp->insnBuffer);
2236  usbduxsub_tmp->insnBuffer = NULL;
2237  kfree(usbduxsub_tmp->outBuffer);
2238  usbduxsub_tmp->outBuffer = NULL;
2239  kfree(usbduxsub_tmp->dac_commands);
2240  usbduxsub_tmp->dac_commands = NULL;
2241  kfree(usbduxsub_tmp->dux_commands);
2242  usbduxsub_tmp->dux_commands = NULL;
2243  usbduxsub_tmp->ai_cmd_running = 0;
2244  usbduxsub_tmp->ao_cmd_running = 0;
2245  usbduxsub_tmp->pwm_cmd_running = 0;
2246 }
2247 
2248 static int usbdux_attach_common(struct comedi_device *dev,
2249  struct usbduxsub *udev)
2250 {
2251  int ret;
2252  struct comedi_subdevice *s = NULL;
2253  int n_subdevs;
2254 
2255  down(&udev->sem);
2256  /* pointer back to the corresponding comedi device */
2257  udev->comedidev = dev;
2258 
2259  dev->board_name = "usbdux";
2260 
2261  /* set number of subdevices */
2262  if (udev->high_speed) {
2263  /* with pwm */
2264  n_subdevs = 5;
2265  } else {
2266  /* without pwm */
2267  n_subdevs = 4;
2268  }
2269 
2270  ret = comedi_alloc_subdevices(dev, n_subdevs);
2271  if (ret) {
2272  up(&udev->sem);
2273  return ret;
2274  }
2275 
2276  /* private structure is also simply the usb-structure */
2277  dev->private = udev;
2278 
2279  /* the first subdevice is the A/D converter */
2280  s = &dev->subdevices[SUBDEV_AD];
2281  /* the URBs get the comedi subdevice */
2282  /* which is responsible for reading */
2283  /* this is the subdevice which reads data */
2284  dev->read_subdev = s;
2285  /* the subdevice receives as private structure the */
2286  /* usb-structure */
2287  s->private = NULL;
2288  /* analog input */
2289  s->type = COMEDI_SUBD_AI;
2290  /* readable and ref is to ground */
2292  /* 8 channels */
2293  s->n_chan = 8;
2294  /* length of the channellist */
2295  s->len_chanlist = 8;
2296  /* callback functions */
2297  s->insn_read = usbdux_ai_insn_read;
2298  s->do_cmdtest = usbdux_ai_cmdtest;
2299  s->do_cmd = usbdux_ai_cmd;
2300  s->cancel = usbdux_ai_cancel;
2301  /* max value from the A/D converter (12bit) */
2302  s->maxdata = 0xfff;
2303  /* range table to convert to physical units */
2304  s->range_table = (&range_usbdux_ai_range);
2305 
2306  /* analog out */
2307  s = &dev->subdevices[SUBDEV_DA];
2308  /* analog out */
2309  s->type = COMEDI_SUBD_AO;
2310  /* backward pointer */
2311  dev->write_subdev = s;
2312  /* the subdevice receives as private structure the */
2313  /* usb-structure */
2314  s->private = NULL;
2315  /* are writable */
2317  /* 4 channels */
2318  s->n_chan = 4;
2319  /* length of the channellist */
2320  s->len_chanlist = 4;
2321  /* 12 bit resolution */
2322  s->maxdata = 0x0fff;
2323  /* bipolar range */
2324  s->range_table = (&range_usbdux_ao_range);
2325  /* callback */
2326  s->do_cmdtest = usbdux_ao_cmdtest;
2327  s->do_cmd = usbdux_ao_cmd;
2328  s->cancel = usbdux_ao_cancel;
2329  s->insn_read = usbdux_ao_insn_read;
2330  s->insn_write = usbdux_ao_insn_write;
2331 
2332  /* digital I/O */
2333  s = &dev->subdevices[SUBDEV_DIO];
2334  s->type = COMEDI_SUBD_DIO;
2336  s->n_chan = 8;
2337  s->maxdata = 1;
2338  s->range_table = (&range_digital);
2339  s->insn_bits = usbdux_dio_insn_bits;
2340  s->insn_config = usbdux_dio_insn_config;
2341  /* we don't use it */
2342  s->private = NULL;
2343 
2344  /* counter */
2345  s = &dev->subdevices[SUBDEV_COUNTER];
2348  s->n_chan = 4;
2349  s->maxdata = 0xFFFF;
2350  s->insn_read = usbdux_counter_read;
2351  s->insn_write = usbdux_counter_write;
2352  s->insn_config = usbdux_counter_config;
2353 
2354  if (udev->high_speed) {
2355  /* timer / pwm */
2356  s = &dev->subdevices[SUBDEV_PWM];
2357  s->type = COMEDI_SUBD_PWM;
2359  s->n_chan = 8;
2360  /* this defines the max duty cycle resolution */
2361  s->maxdata = udev->sizePwmBuf;
2362  s->insn_write = usbdux_pwm_write;
2363  s->insn_read = usbdux_pwm_read;
2364  s->insn_config = usbdux_pwm_config;
2365  usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2366  }
2367  /* finally decide that it's attached */
2368  udev->attached = 1;
2369 
2370  up(&udev->sem);
2371 
2372  dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n",
2373  dev->minor);
2374 
2375  return 0;
2376 }
2377 
2378 static int usbdux_attach_usb(struct comedi_device *dev,
2379  struct usb_interface *uinterf)
2380 {
2381  int ret;
2382  struct usbduxsub *this_usbduxsub;
2383 
2384  dev->private = NULL;
2385 
2386  down(&start_stop_sem);
2387  this_usbduxsub = usb_get_intfdata(uinterf);
2388  if (!this_usbduxsub || !this_usbduxsub->probed) {
2390  "comedi%d: usbdux: error: attach_usb failed, not connected\n",
2391  dev->minor);
2392  ret = -ENODEV;
2393  } else if (this_usbduxsub->attached) {
2395  "comedi%d: usbdux: error: attach_usb failed, already attached\n",
2396  dev->minor);
2397  ret = -ENODEV;
2398  } else
2399  ret = usbdux_attach_common(dev, this_usbduxsub);
2400  up(&start_stop_sem);
2401  return ret;
2402 }
2403 
2404 static void usbdux_detach(struct comedi_device *dev)
2405 {
2406  struct usbduxsub *usb = dev->private;
2407 
2408  if (usb) {
2409  down(&usb->sem);
2410  dev->private = NULL;
2411  usb->attached = 0;
2412  usb->comedidev = NULL;
2413  up(&usb->sem);
2414  }
2415 }
2416 
2417 static struct comedi_driver usbdux_driver = {
2418  .driver_name = "usbdux",
2419  .module = THIS_MODULE,
2420  .attach_usb = usbdux_attach_usb,
2421  .detach = usbdux_detach,
2422 };
2423 
2424 static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2425  void *context)
2426 {
2427  struct usbduxsub *usbduxsub_tmp = context;
2428  struct usb_interface *uinterf = usbduxsub_tmp->interface;
2429  int ret;
2430 
2431  if (fw == NULL) {
2432  dev_err(&uinterf->dev,
2433  "Firmware complete handler without firmware!\n");
2434  return;
2435  }
2436 
2437  /*
2438  * we need to upload the firmware here because fw will be
2439  * freed once we've left this function
2440  */
2441  ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
2442 
2443  if (ret) {
2444  dev_err(&uinterf->dev,
2445  "Could not upload firmware (err=%d)\n", ret);
2446  goto out;
2447  }
2448  comedi_usb_auto_config(uinterf, &usbdux_driver);
2449  out:
2450  release_firmware(fw);
2451 }
2452 
2453 static int usbdux_usb_probe(struct usb_interface *uinterf,
2454  const struct usb_device_id *id)
2455 {
2456  struct usb_device *udev = interface_to_usbdev(uinterf);
2457  struct device *dev = &uinterf->dev;
2458  int i;
2459  int index;
2460  int ret;
2461 
2462  dev_dbg(dev, "comedi_: usbdux_: "
2463  "finding a free structure for the usb-device\n");
2464 
2465  down(&start_stop_sem);
2466  /* look for a free place in the usbdux array */
2467  index = -1;
2468  for (i = 0; i < NUMUSBDUX; i++) {
2469  if (!(usbduxsub[i].probed)) {
2470  index = i;
2471  break;
2472  }
2473  }
2474 
2475  /* no more space */
2476  if (index == -1) {
2477  dev_err(dev, "Too many usbdux-devices connected.\n");
2478  up(&start_stop_sem);
2479  return -EMFILE;
2480  }
2481  dev_dbg(dev, "comedi_: usbdux: "
2482  "usbduxsub[%d] is ready to connect to comedi.\n", index);
2483 
2484  sema_init(&(usbduxsub[index].sem), 1);
2485  /* save a pointer to the usb device */
2486  usbduxsub[index].usbdev = udev;
2487 
2488  /* 2.6: save the interface itself */
2489  usbduxsub[index].interface = uinterf;
2490  /* get the interface number from the interface */
2491  usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2492  /* hand the private data over to the usb subsystem */
2493  /* will be needed for disconnect */
2494  usb_set_intfdata(uinterf, &(usbduxsub[index]));
2495 
2496  dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2497 
2498  /* test if it is high speed (USB 2.0) */
2499  usbduxsub[index].high_speed =
2500  (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2501 
2502  /* create space for the commands of the DA converter */
2503  usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2504  if (!usbduxsub[index].dac_commands) {
2505  dev_err(dev, "comedi_: usbdux: "
2506  "error alloc space for dac commands\n");
2507  tidy_up(&(usbduxsub[index]));
2508  up(&start_stop_sem);
2509  return -ENOMEM;
2510  }
2511  /* create space for the commands going to the usb device */
2512  usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2513  if (!usbduxsub[index].dux_commands) {
2514  dev_err(dev, "comedi_: usbdux: "
2515  "error alloc space for dux commands\n");
2516  tidy_up(&(usbduxsub[index]));
2517  up(&start_stop_sem);
2518  return -ENOMEM;
2519  }
2520  /* create space for the in buffer and set it to zero */
2521  usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2522  if (!(usbduxsub[index].inBuffer)) {
2523  dev_err(dev, "comedi_: usbdux: "
2524  "could not alloc space for inBuffer\n");
2525  tidy_up(&(usbduxsub[index]));
2526  up(&start_stop_sem);
2527  return -ENOMEM;
2528  }
2529  /* create space of the instruction buffer */
2530  usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2531  if (!(usbduxsub[index].insnBuffer)) {
2532  dev_err(dev, "comedi_: usbdux: "
2533  "could not alloc space for insnBuffer\n");
2534  tidy_up(&(usbduxsub[index]));
2535  up(&start_stop_sem);
2536  return -ENOMEM;
2537  }
2538  /* create space for the outbuffer */
2539  usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2540  if (!(usbduxsub[index].outBuffer)) {
2541  dev_err(dev, "comedi_: usbdux: "
2542  "could not alloc space for outBuffer\n");
2543  tidy_up(&(usbduxsub[index]));
2544  up(&start_stop_sem);
2545  return -ENOMEM;
2546  }
2547  /* setting to alternate setting 3: enabling iso ep and bulk ep. */
2548  i = usb_set_interface(usbduxsub[index].usbdev,
2549  usbduxsub[index].ifnum, 3);
2550  if (i < 0) {
2551  dev_err(dev, "comedi_: usbdux%d: "
2552  "could not set alternate setting 3 in high speed.\n",
2553  index);
2554  tidy_up(&(usbduxsub[index]));
2555  up(&start_stop_sem);
2556  return -ENODEV;
2557  }
2558  if (usbduxsub[index].high_speed)
2560  else
2562 
2563  usbduxsub[index].urbIn =
2564  kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
2565  GFP_KERNEL);
2566  if (!(usbduxsub[index].urbIn)) {
2567  dev_err(dev, "comedi_: usbdux: Could not alloc. urbIn array\n");
2568  tidy_up(&(usbduxsub[index]));
2569  up(&start_stop_sem);
2570  return -ENOMEM;
2571  }
2572  for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
2573  /* one frame: 1ms */
2574  usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
2575  if (usbduxsub[index].urbIn[i] == NULL) {
2576  dev_err(dev, "comedi_: usbdux%d: "
2577  "Could not alloc. urb(%d)\n", index, i);
2578  tidy_up(&(usbduxsub[index]));
2579  up(&start_stop_sem);
2580  return -ENOMEM;
2581  }
2582  usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
2583  /* will be filled later with a pointer to the comedi-device */
2584  /* and ONLY then the urb should be submitted */
2585  usbduxsub[index].urbIn[i]->context = NULL;
2586  usbduxsub[index].urbIn[i]->pipe =
2587  usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2588  usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
2589  usbduxsub[index].urbIn[i]->transfer_buffer =
2590  kzalloc(SIZEINBUF, GFP_KERNEL);
2591  if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
2592  dev_err(dev, "comedi_: usbdux%d: "
2593  "could not alloc. transb.\n", index);
2594  tidy_up(&(usbduxsub[index]));
2595  up(&start_stop_sem);
2596  return -ENOMEM;
2597  }
2598  usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
2599  usbduxsub[index].urbIn[i]->number_of_packets = 1;
2600  usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
2601  usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
2602  usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF;
2603  }
2604 
2605  /* out */
2606  if (usbduxsub[index].high_speed)
2608  else
2610 
2611  usbduxsub[index].urbOut =
2612  kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
2613  GFP_KERNEL);
2614  if (!(usbduxsub[index].urbOut)) {
2615  dev_err(dev, "comedi_: usbdux: "
2616  "Could not alloc. urbOut array\n");
2617  tidy_up(&(usbduxsub[index]));
2618  up(&start_stop_sem);
2619  return -ENOMEM;
2620  }
2621  for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
2622  /* one frame: 1ms */
2623  usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
2624  if (usbduxsub[index].urbOut[i] == NULL) {
2625  dev_err(dev, "comedi_: usbdux%d: "
2626  "Could not alloc. urb(%d)\n", index, i);
2627  tidy_up(&(usbduxsub[index]));
2628  up(&start_stop_sem);
2629  return -ENOMEM;
2630  }
2631  usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
2632  /* will be filled later with a pointer to the comedi-device */
2633  /* and ONLY then the urb should be submitted */
2634  usbduxsub[index].urbOut[i]->context = NULL;
2635  usbduxsub[index].urbOut[i]->pipe =
2636  usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2637  usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
2638  usbduxsub[index].urbOut[i]->transfer_buffer =
2639  kzalloc(SIZEOUTBUF, GFP_KERNEL);
2640  if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
2641  dev_err(dev, "comedi_: usbdux%d: "
2642  "could not alloc. transb.\n", index);
2643  tidy_up(&(usbduxsub[index]));
2644  up(&start_stop_sem);
2645  return -ENOMEM;
2646  }
2647  usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
2648  usbduxsub[index].urbOut[i]->number_of_packets = 1;
2649  usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
2650  usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
2651  usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
2652  SIZEOUTBUF;
2653  if (usbduxsub[index].high_speed) {
2654  /* uframes */
2655  usbduxsub[index].urbOut[i]->interval = 8;
2656  } else {
2657  /* frames */
2658  usbduxsub[index].urbOut[i]->interval = 1;
2659  }
2660  }
2661 
2662  /* pwm */
2663  if (usbduxsub[index].high_speed) {
2664  /* max bulk ep size in high speed */
2665  usbduxsub[index].sizePwmBuf = 512;
2666  usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
2667  if (usbduxsub[index].urbPwm == NULL) {
2668  dev_err(dev, "comedi_: usbdux%d: "
2669  "Could not alloc. pwm urb\n", index);
2670  tidy_up(&(usbduxsub[index]));
2671  up(&start_stop_sem);
2672  return -ENOMEM;
2673  }
2674  usbduxsub[index].urbPwm->transfer_buffer =
2675  kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
2676  if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2677  dev_err(dev, "comedi_: usbdux%d: "
2678  "could not alloc. transb. for pwm\n", index);
2679  tidy_up(&(usbduxsub[index]));
2680  up(&start_stop_sem);
2681  return -ENOMEM;
2682  }
2683  } else {
2684  usbduxsub[index].urbPwm = NULL;
2685  usbduxsub[index].sizePwmBuf = 0;
2686  }
2687 
2688  usbduxsub[index].ai_cmd_running = 0;
2689  usbduxsub[index].ao_cmd_running = 0;
2690  usbduxsub[index].pwm_cmd_running = 0;
2691 
2692  /* we've reached the bottom of the function */
2693  usbduxsub[index].probed = 1;
2694  up(&start_stop_sem);
2695 
2698  FIRMWARE,
2699  &udev->dev,
2700  GFP_KERNEL,
2701  usbduxsub + index,
2702  usbdux_firmware_request_complete_handler);
2703 
2704  if (ret) {
2705  dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2706  return ret;
2707  }
2708 
2709  dev_info(dev, "comedi_: usbdux%d "
2710  "has been successfully initialised.\n", index);
2711  /* success */
2712  return 0;
2713 }
2714 
2715 static void usbdux_usb_disconnect(struct usb_interface *intf)
2716 {
2717  struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2718  struct usb_device *udev = interface_to_usbdev(intf);
2719 
2720  if (!usbduxsub_tmp) {
2721  dev_err(&intf->dev,
2722  "comedi_: disconnect called with null pointer.\n");
2723  return;
2724  }
2725  if (usbduxsub_tmp->usbdev != udev) {
2726  dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
2727  return;
2728  }
2730  down(&start_stop_sem);
2731  down(&usbduxsub_tmp->sem);
2732  tidy_up(usbduxsub_tmp);
2733  up(&usbduxsub_tmp->sem);
2734  up(&start_stop_sem);
2735  dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n");
2736 }
2737 
2738 static const struct usb_device_id usbdux_usb_table[] = {
2739  { USB_DEVICE(0x13d8, 0x0001) },
2740  { USB_DEVICE(0x13d8, 0x0002) },
2741  { }
2742 };
2743 
2744 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
2745 
2746 static struct usb_driver usbdux_usb_driver = {
2747  .name = "usbdux",
2748  .probe = usbdux_usb_probe,
2749  .disconnect = usbdux_usb_disconnect,
2750  .id_table = usbdux_usb_table,
2751 };
2752 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
2753 
2754 MODULE_AUTHOR("Bernd Porr, [email protected]");
2755 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- [email protected]");
2756 MODULE_LICENSE("GPL");