usbdux.c revision 9ebfbd45f9d4ee9cd72529cf99e5f300eb398e67
1#define DRIVER_VERSION "v2.2"
2#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
3#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
4/*
5   comedi/drivers/usbdux.c
6   Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23/*
24Driver: usbdux
25Description: University of Stirling USB DAQ & INCITE Technology Limited
26Devices: [ITL] USB-DUX (usbdux.o)
27Author: Bernd Porr <BerndPorr@f2s.com>
28Updated: 8 Dec 2008
29Status: Stable
30Configuration options:
31  You have to upload firmware with the -i option. The
32  firmware is usually installed under /usr/share/usb or
33  /usr/local/share/usb or /lib/firmware.
34
35Connection scheme for the counter at the digital port:
36  0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
37  The sampling rate of the counter is approximately 500Hz.
38
39Please note that under USB2.0 the length of the channel list determines
40the max sampling rate. If you sample only one channel you get 8kHz
41sampling rate. If you sample two channels you get 4kHz and so on.
42*/
43/*
44 * I must give credit here to Chris Baugher who
45 * wrote the driver for AT-MIO-16d. I used some parts of this
46 * driver. I also must give credits to David Brownell
47 * who supported me with the USB development.
48 *
49 * Bernd Porr
50 *
51 *
52 * Revision history:
53 * 0.94: D/A output should work now with any channel list combinations
54 * 0.95: .owner commented out for kernel vers below 2.4.19
55 *       sanity checks in ai/ao_cmd
56 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
57 *       attach final USB IDs
58 *       moved memory allocation completely to the corresponding comedi
59 *       functions firmware upload is by fxload and no longer by comedi (due to
60 *       enumeration)
61 * 0.97: USB IDs received, adjusted table
62 * 0.98: SMP, locking, memroy alloc: moved all usb memory alloc
63 *       to the usb subsystem and moved all comedi related memory
64 *       alloc to comedi.
65 *       | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
66 * 0.99: USB 2.0: changed protocol to isochronous transfer
67 *                IRQ transfer is too buggy and too risky in 2.0
68 *                for the high speed ISO transfer is now a working version
69 *                available
70 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
71 *        chipsets miss out IRQs. Deeper buffering is needed.
72 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
73 *       rate.
74 *       Firmware vers 1.00 is needed for this.
75 *       Two 16 bit up/down/reset counter with a sampling rate of 1kHz
76 *       And loads of cleaning up, in particular streamlining the
77 *       bulk transfers.
78 * 1.1:  moved EP4 transfers to EP1 to make space for a PWM output on EP4
79 * 1.2:  added PWM suport via EP4
80 * 2.0:  PWM seems to be stable and is not interfering with the other functions
81 * 2.1:  changed PWM API
82 * 2.2:  added firmware kernel request to fix an udev problem
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/smp_lock.h>
96#include <linux/fcntl.h>
97#include <linux/compiler.h>
98#include <linux/firmware.h>
99
100#include "../comedidev.h"
101
102#define BOARDNAME "usbdux"
103
104/* timeout for the USB-transfer */
105#define EZTIMEOUT 30
106
107/* constants for "firmware" upload and download */
108#define USBDUXSUB_FIRMWARE 0xA0
109#define VENDOR_DIR_IN  0xC0
110#define VENDOR_DIR_OUT 0x40
111
112/* internal adresses 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 */
217static 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
229static 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 */
245struct 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 */
253	int numOfInBuffers;
254	/* actual number of out-buffers */
255	int numOfOutBuffers;
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 */
264	int8_t pwmDelay;
265	/* size of the PWM buffer which holds the bit pattern */
266	int sizePwmBuf;
267	/* input buffer for the ISO-transfer */
268	int16_t *inBuffer;
269	/* input buffer for single insn */
270	int16_t *insnBuffer;
271	/* output buffer for single DA outputs */
272	int16_t *outBuffer;
273	/* interface number */
274	int ifnum;
275	/* interface structure in 2.6 */
276	struct usb_interface *interface;
277	/* comedi device for the interrupt context */
278	struct comedi_device *comedidev;
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 aquisition */
287	short int ai_continous;
288	short int ao_continous;
289	/* number of samples to aquire */
290	int ai_sample_count;
291	int ao_sample_count;
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 */
301	int8_t *dac_commands;
302	/* commands */
303	int8_t *dux_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 */
314static struct usbduxsub usbduxsub[NUMUSBDUX];
315
316static DECLARE_MUTEX(start_stop_sem);
317
318/*
319 * Stops the data acquision
320 * It should be safe to call this function from any context
321 */
322static 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 */
347static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
348{
349	int ret = 0;
350
351	if (!this_usbduxsub) {
352		dev_err(&this_usbduxsub->interface->dev,
353			"comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
354		return -EFAULT;
355	}
356	dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
357
358	if (do_unlink) {
359		/* stop aquistion */
360		ret = usbduxsub_unlink_InURBs(this_usbduxsub);
361	}
362
363	this_usbduxsub->ai_cmd_running = 0;
364
365	return ret;
366}
367
368/*
369 * This will cancel a running acquisition operation.
370 * This is called by comedi but never from inside the driver.
371 */
372static int usbdux_ai_cancel(struct comedi_device *dev,
373			    struct comedi_subdevice *s)
374{
375	struct usbduxsub *this_usbduxsub;
376	int res = 0;
377
378	/* force unlink of all urbs */
379	this_usbduxsub = dev->private;
380	if (!this_usbduxsub)
381		return -EFAULT;
382
383	dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
384
385	/* prevent other CPUs from submitting new commands just now */
386	down(&this_usbduxsub->sem);
387	if (!(this_usbduxsub->probed)) {
388		up(&this_usbduxsub->sem);
389		return -ENODEV;
390	}
391	/* unlink only if the urb really has been submitted */
392	res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
393	up(&this_usbduxsub->sem);
394	return res;
395}
396
397/* analogue IN - interrupt service routine */
398static void usbduxsub_ai_IsocIrq(struct urb *urb)
399{
400	int i, err, n;
401	struct usbduxsub *this_usbduxsub;
402	struct comedi_device *this_comedidev;
403	struct comedi_subdevice *s;
404
405	/* the context variable points to the subdevice */
406	this_comedidev = urb->context;
407	/* the private structure of the subdevice is struct usbduxsub */
408	this_usbduxsub = this_comedidev->private;
409	/* subdevice which is the AD converter */
410	s = this_comedidev->subdevices + SUBDEV_AD;
411
412	/* first we test if something unusual has just happened */
413	switch (urb->status) {
414	case 0:
415		/* copy the result in the transfer buffer */
416		memcpy(this_usbduxsub->inBuffer,
417		       urb->transfer_buffer, SIZEINBUF);
418		break;
419	case -EILSEQ:
420		/* error in the ISOchronous data */
421		/* we don't copy the data into the transfer buffer */
422		/* and recycle the last data byte */
423		dev_dbg(&urb->dev->dev,
424			"comedi%d: usbdux: CRC error in ISO IN stream.\n",
425			this_usbduxsub->comedidev->minor);
426
427		break;
428
429	case -ECONNRESET:
430	case -ENOENT:
431	case -ESHUTDOWN:
432	case -ECONNABORTED:
433		/* happens after an unlink command */
434		if (this_usbduxsub->ai_cmd_running) {
435			/* we are still running a command */
436			/* tell this comedi */
437			s->async->events |= COMEDI_CB_EOA;
438			s->async->events |= COMEDI_CB_ERROR;
439			comedi_event(this_usbduxsub->comedidev, s);
440			/* stop the transfer w/o unlink */
441			usbdux_ai_stop(this_usbduxsub, 0);
442		}
443		return;
444
445	default:
446		/* a real error on the bus */
447		/* pass error to comedi if we are really running a command */
448		if (this_usbduxsub->ai_cmd_running) {
449			dev_err(&urb->dev->dev,
450				"Non-zero urb status received in ai intr "
451				"context: %d\n", urb->status);
452			s->async->events |= COMEDI_CB_EOA;
453			s->async->events |= COMEDI_CB_ERROR;
454			comedi_event(this_usbduxsub->comedidev, s);
455			/* don't do an unlink here */
456			usbdux_ai_stop(this_usbduxsub, 0);
457		}
458		return;
459	}
460
461	/*
462	 * at this point we are reasonably sure that nothing dodgy has happened
463	 * are we running a command?
464	 */
465	if (unlikely((!(this_usbduxsub->ai_cmd_running)))) {
466		/*
467		 * not running a command, do not continue execution if no
468		 * asynchronous command is running in particular not resubmit
469		 */
470		return;
471	}
472
473	urb->dev = this_usbduxsub->usbdev;
474
475	/* resubmit the urb */
476	err = usb_submit_urb(urb, GFP_ATOMIC);
477	if (unlikely(err < 0)) {
478		dev_err(&urb->dev->dev,
479			"comedi_: urb resubmit failed in int-context! err=%d\n",
480			err);
481		if (err == -EL2NSYNC)
482			dev_err(&urb->dev->dev,
483				"buggy USB host controller or bug in IRQ "
484				"handler!\n");
485		s->async->events |= COMEDI_CB_EOA;
486		s->async->events |= COMEDI_CB_ERROR;
487		comedi_event(this_usbduxsub->comedidev, s);
488		/* don't do an unlink here */
489		usbdux_ai_stop(this_usbduxsub, 0);
490		return;
491	}
492
493	this_usbduxsub->ai_counter--;
494	if (likely(this_usbduxsub->ai_counter > 0))
495		return;
496
497	/* timer zero, transfer measurements to comedi */
498	this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
499
500	/* test, if we transmit only a fixed number of samples */
501	if (!(this_usbduxsub->ai_continous)) {
502		/* not continous, fixed number of samples */
503		this_usbduxsub->ai_sample_count--;
504		/* all samples received? */
505		if (this_usbduxsub->ai_sample_count < 0) {
506			/* prevent a resubmit next time */
507			usbdux_ai_stop(this_usbduxsub, 0);
508			/* say comedi that the acquistion is over */
509			s->async->events |= COMEDI_CB_EOA;
510			comedi_event(this_usbduxsub->comedidev, s);
511			return;
512		}
513	}
514	/* get the data from the USB bus and hand it over to comedi */
515	n = s->async->cmd.chanlist_len;
516	for (i = 0; i < n; i++) {
517		/* transfer data */
518		if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
519			err = comedi_buf_put
520			    (s->async,
521			     le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800);
522		} else {
523			err = comedi_buf_put
524			    (s->async,
525			     le16_to_cpu(this_usbduxsub->inBuffer[i]));
526		}
527		if (unlikely(err == 0)) {
528			/* buffer overflow */
529			usbdux_ai_stop(this_usbduxsub, 0);
530			return;
531		}
532	}
533	/* tell comedi that data is there */
534	comedi_event(this_usbduxsub->comedidev, s);
535}
536
537static 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 */
558static 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 */
575static 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
596static 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 (this_usbduxsub->ao_counter <= 0) {
651		/* timer zero */
652		this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
653
654		/* handle non continous aquisition */
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
730static 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" */
741				  USBDUXSUB_FIRMWARE,
742				  /* bmRequestType */
743				  VENDOR_DIR_OUT,
744				  /* Value */
745				  USBDUXSUB_CPUCS,
746				  /* Index */
747				  0x0000,
748				  /* address of the transfer buffer */
749				  local_transfer_buffer,
750				  /* Length */
751				  1,
752				  /* Timeout */
753				  EZTIMEOUT);
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
762static 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" */
773				  USBDUXSUB_FIRMWARE,
774				  /* bmRequestType */
775				  VENDOR_DIR_OUT,
776				  /* Value */
777				  USBDUXSUB_CPUCS,
778				  /* Index */
779				  0x0000, local_transfer_buffer,
780				  /* Length */
781				  1,
782				  /* Timeout */
783				  EZTIMEOUT);
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
792static 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 */
801				  USBDUXSUB_FIRMWARE,
802				  /* bmRequestType */
803				  VENDOR_DIR_OUT,
804				  /* value */
805				  startAddr,
806				  /* index */
807				  0x0000,
808				  /* our local safe buffer */
809				  local_transfer_buffer,
810				  /* length */
811				  len,
812				  /* timeout */
813				  EZTIMEOUT);
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
824static 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			"comedi_: 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 = kzalloc(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	memcpy(fwBuf, firmwareBinary, sizeFirmware);
847
848	ret = usbduxsub_stop(usbduxsub);
849	if (ret < 0) {
850		dev_err(&usbduxsub->interface->dev,
851			"comedi_: can not stop firmware\n");
852		kfree(fwBuf);
853		return ret;
854	}
855
856	ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
857	if (ret < 0) {
858		dev_err(&usbduxsub->interface->dev,
859			"comedi_: firmware upload failed\n");
860		kfree(fwBuf);
861		return ret;
862	}
863	ret = usbduxsub_start(usbduxsub);
864	if (ret < 0) {
865		dev_err(&usbduxsub->interface->dev,
866			"comedi_: can not start firmware\n");
867		kfree(fwBuf);
868		return ret;
869	}
870	kfree(fwBuf);
871	return 0;
872}
873
874static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub)
875{
876	int i, errFlag;
877
878	if (!usbduxsub)
879		return -EFAULT;
880
881	/* Submit all URBs and start the transfer on the bus */
882	for (i = 0; i < usbduxsub->numOfInBuffers; i++) {
883		/* in case of a resubmission after an unlink... */
884		usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval;
885		usbduxsub->urbIn[i]->context = usbduxsub->comedidev;
886		usbduxsub->urbIn[i]->dev = usbduxsub->usbdev;
887		usbduxsub->urbIn[i]->status = 0;
888		usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP;
889		dev_dbg(&usbduxsub->interface->dev,
890			"comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
891			usbduxsub->comedidev->minor, i,
892			(usbduxsub->urbIn[i]->context),
893			(usbduxsub->urbIn[i]->dev),
894			(usbduxsub->urbIn[i]->interval));
895		errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC);
896		if (errFlag) {
897			dev_err(&usbduxsub->interface->dev,
898				"comedi_: ai: usb_submit_urb(%d) error %d\n",
899				i, errFlag);
900			return errFlag;
901		}
902	}
903	return 0;
904}
905
906static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
907{
908	int i, errFlag;
909
910	if (!usbduxsub)
911		return -EFAULT;
912
913	for (i = 0; i < usbduxsub->numOfOutBuffers; i++) {
914		dev_dbg(&usbduxsub->interface->dev,
915			"comedi_: submitting out-urb[%d]\n", i);
916		/* in case of a resubmission after an unlink... */
917		usbduxsub->urbOut[i]->context = usbduxsub->comedidev;
918		usbduxsub->urbOut[i]->dev = usbduxsub->usbdev;
919		usbduxsub->urbOut[i]->status = 0;
920		usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP;
921		errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC);
922		if (errFlag) {
923			dev_err(&usbduxsub->interface->dev,
924				"comedi_: ao: usb_submit_urb(%d) error %d\n",
925				i, errFlag);
926			return errFlag;
927		}
928	}
929	return 0;
930}
931
932static int usbdux_ai_cmdtest(struct comedi_device *dev,
933			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
934{
935	int err = 0, tmp, i;
936	unsigned int tmpTimer;
937	struct usbduxsub *this_usbduxsub = dev->private;
938
939	if (!(this_usbduxsub->probed))
940		return -ENODEV;
941
942	dev_dbg(&this_usbduxsub->interface->dev,
943		"comedi%d: usbdux_ai_cmdtest\n", dev->minor);
944
945	/* make sure triggers are valid */
946	/* Only immediate triggers are allowed */
947	tmp = cmd->start_src;
948	cmd->start_src &= TRIG_NOW | TRIG_INT;
949	if (!cmd->start_src || tmp != cmd->start_src)
950		err++;
951
952	/* trigger should happen timed */
953	tmp = cmd->scan_begin_src;
954	/* start a new _scan_ with a timer */
955	cmd->scan_begin_src &= TRIG_TIMER;
956	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
957		err++;
958
959	/* scanning is continous */
960	tmp = cmd->convert_src;
961	cmd->convert_src &= TRIG_NOW;
962	if (!cmd->convert_src || tmp != cmd->convert_src)
963		err++;
964
965	/* issue a trigger when scan is finished and start a new scan */
966	tmp = cmd->scan_end_src;
967	cmd->scan_end_src &= TRIG_COUNT;
968	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
969		err++;
970
971	/* trigger at the end of count events or not, stop condition or not */
972	tmp = cmd->stop_src;
973	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
974	if (!cmd->stop_src || tmp != cmd->stop_src)
975		err++;
976
977	if (err)
978		return 1;
979
980	/*
981	 * step 2: make sure trigger sources are unique and mutually compatible
982	 * note that mutual compatiblity is not an issue here
983	 */
984	if (cmd->scan_begin_src != TRIG_FOLLOW &&
985	    cmd->scan_begin_src != TRIG_EXT &&
986	    cmd->scan_begin_src != TRIG_TIMER)
987		err++;
988	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
989		err++;
990
991	if (err)
992		return 2;
993
994	/* step 3: make sure arguments are trivially compatible */
995	if (cmd->start_arg != 0) {
996		cmd->start_arg = 0;
997		err++;
998	}
999
1000	if (cmd->scan_begin_src == TRIG_FOLLOW) {
1001		/* internal trigger */
1002		if (cmd->scan_begin_arg != 0) {
1003			cmd->scan_begin_arg = 0;
1004			err++;
1005		}
1006	}
1007
1008	if (cmd->scan_begin_src == TRIG_TIMER) {
1009		if (this_usbduxsub->high_speed) {
1010			/*
1011			 * In high speed mode microframes are possible.
1012			 * However, during one microframe we can roughly
1013			 * sample one channel. Thus, the more channels
1014			 * are in the channel list the more time we need.
1015			 */
1016			i = 1;
1017			/* find a power of 2 for the number of channels */
1018			while (i < (cmd->chanlist_len))
1019				i = i * 2;
1020
1021			if (cmd->scan_begin_arg < (1000000 / 8 * i)) {
1022				cmd->scan_begin_arg = 1000000 / 8 * i;
1023				err++;
1024			}
1025			/* now calc the real sampling rate with all the
1026			 * rounding errors */
1027			tmpTimer =
1028			    ((unsigned int)(cmd->scan_begin_arg / 125000)) *
1029			    125000;
1030			if (cmd->scan_begin_arg != tmpTimer) {
1031				cmd->scan_begin_arg = tmpTimer;
1032				err++;
1033			}
1034		} else {
1035			/* full speed */
1036			/* 1kHz scans every USB frame */
1037			if (cmd->scan_begin_arg < 1000000) {
1038				cmd->scan_begin_arg = 1000000;
1039				err++;
1040			}
1041			/*
1042			 * calc the real sampling rate with the rounding errors
1043			 */
1044			tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
1045						   1000000)) * 1000000;
1046			if (cmd->scan_begin_arg != tmpTimer) {
1047				cmd->scan_begin_arg = tmpTimer;
1048				err++;
1049			}
1050		}
1051	}
1052	/* the same argument */
1053	if (cmd->scan_end_arg != cmd->chanlist_len) {
1054		cmd->scan_end_arg = cmd->chanlist_len;
1055		err++;
1056	}
1057
1058	if (cmd->stop_src == TRIG_COUNT) {
1059		/* any count is allowed */
1060	} else {
1061		/* TRIG_NONE */
1062		if (cmd->stop_arg != 0) {
1063			cmd->stop_arg = 0;
1064			err++;
1065		}
1066	}
1067
1068	if (err)
1069		return 3;
1070
1071	return 0;
1072}
1073
1074/*
1075 * creates the ADC command for the MAX1271
1076 * range is the range value from comedi
1077 */
1078static int8_t create_adc_command(unsigned int chan, int range)
1079{
1080	int8_t p = (range <= 1);
1081	int8_t r = ((range % 2) == 0);
1082	return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
1083}
1084
1085/* bulk transfers to usbdux */
1086
1087#define SENDADCOMMANDS            0
1088#define SENDDACOMMANDS            1
1089#define SENDDIOCONFIGCOMMAND      2
1090#define SENDDIOBITSCOMMAND        3
1091#define SENDSINGLEAD              4
1092#define READCOUNTERCOMMAND        5
1093#define WRITECOUNTERCOMMAND       6
1094#define SENDPWMON                 7
1095#define SENDPWMOFF                8
1096
1097static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
1098{
1099	int result, nsent;
1100
1101	this_usbduxsub->dux_commands[0] = cmd_type;
1102#ifdef NOISY_DUX_DEBUGBUG
1103	printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
1104	       this_usbduxsub->comedidev->minor);
1105	for (result = 0; result < SIZEOFDUXBUFFER; result++)
1106		printk(" %02x", this_usbduxsub->dux_commands[result]);
1107	printk("\n");
1108#endif
1109	result = usb_bulk_msg(this_usbduxsub->usbdev,
1110			      usb_sndbulkpipe(this_usbduxsub->usbdev,
1111					      COMMAND_OUT_EP),
1112			      this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
1113			      &nsent, 10);
1114	if (result < 0)
1115		dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1116			"could not transmit dux_command to the usb-device, "
1117			"err=%d\n", this_usbduxsub->comedidev->minor, result);
1118
1119	return result;
1120}
1121
1122static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
1123{
1124	int result = (-EFAULT);
1125	int nrec;
1126	int i;
1127
1128	for (i = 0; i < RETRIES; i++) {
1129		result = usb_bulk_msg(this_usbduxsub->usbdev,
1130				      usb_rcvbulkpipe(this_usbduxsub->usbdev,
1131						      COMMAND_IN_EP),
1132				      this_usbduxsub->insnBuffer, SIZEINSNBUF,
1133				      &nrec, 1);
1134		if (result < 0) {
1135			dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1136				"insn: USB error %d while receiving DUX command"
1137				"\n", this_usbduxsub->comedidev->minor, result);
1138			return result;
1139		}
1140		if (le16_to_cpu(this_usbduxsub->insnBuffer[0]) == command)
1141			return result;
1142	}
1143	/* this is only reached if the data has been requested a couple of
1144	 * times */
1145	dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
1146		"wrong data returned from firmware: want cmd %d, got cmd %d.\n",
1147		this_usbduxsub->comedidev->minor, command,
1148		le16_to_cpu(this_usbduxsub->insnBuffer[0]));
1149	return -EFAULT;
1150}
1151
1152static int usbdux_ai_inttrig(struct comedi_device *dev,
1153			     struct comedi_subdevice *s, unsigned int trignum)
1154{
1155	int ret;
1156	struct usbduxsub *this_usbduxsub = dev->private;
1157	if (!this_usbduxsub)
1158		return -EFAULT;
1159
1160	down(&this_usbduxsub->sem);
1161	if (!(this_usbduxsub->probed)) {
1162		up(&this_usbduxsub->sem);
1163		return -ENODEV;
1164	}
1165	dev_dbg(&this_usbduxsub->interface->dev,
1166		"comedi%d: usbdux_ai_inttrig\n", dev->minor);
1167
1168	if (trignum != 0) {
1169		dev_err(&this_usbduxsub->interface->dev,
1170			"comedi%d: usbdux_ai_inttrig: invalid trignum\n",
1171			dev->minor);
1172		up(&this_usbduxsub->sem);
1173		return -EINVAL;
1174	}
1175	if (!(this_usbduxsub->ai_cmd_running)) {
1176		this_usbduxsub->ai_cmd_running = 1;
1177		ret = usbduxsub_submit_InURBs(this_usbduxsub);
1178		if (ret < 0) {
1179			dev_err(&this_usbduxsub->interface->dev,
1180				"comedi%d: usbdux_ai_inttrig: "
1181				"urbSubmit: err=%d\n", dev->minor, ret);
1182			this_usbduxsub->ai_cmd_running = 0;
1183			up(&this_usbduxsub->sem);
1184			return ret;
1185		}
1186		s->async->inttrig = NULL;
1187	} else {
1188		dev_err(&this_usbduxsub->interface->dev,
1189			"comedi%d: ai_inttrig but acqu is already running\n",
1190			dev->minor);
1191	}
1192	up(&this_usbduxsub->sem);
1193	return 1;
1194}
1195
1196static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1197{
1198	struct comedi_cmd *cmd = &s->async->cmd;
1199	unsigned int chan, range;
1200	int i, ret;
1201	struct usbduxsub *this_usbduxsub = dev->private;
1202	int result;
1203
1204	if (!this_usbduxsub)
1205		return -EFAULT;
1206
1207	dev_dbg(&this_usbduxsub->interface->dev,
1208		"comedi%d: usbdux_ai_cmd\n", dev->minor);
1209
1210	/* block other CPUs from starting an ai_cmd */
1211	down(&this_usbduxsub->sem);
1212
1213	if (!(this_usbduxsub->probed)) {
1214		up(&this_usbduxsub->sem);
1215		return -ENODEV;
1216	}
1217	if (this_usbduxsub->ai_cmd_running) {
1218		dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
1219			"ai_cmd not possible. Another ai_cmd is running.\n",
1220			dev->minor);
1221		up(&this_usbduxsub->sem);
1222		return -EBUSY;
1223	}
1224	/* set current channel of the running aquisition to zero */
1225	s->async->cur_chan = 0;
1226
1227	this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
1228	for (i = 0; i < cmd->chanlist_len; ++i) {
1229		chan = CR_CHAN(cmd->chanlist[i]);
1230		range = CR_RANGE(cmd->chanlist[i]);
1231		if (i >= NUMCHANNELS) {
1232			dev_err(&this_usbduxsub->interface->dev,
1233				"comedi%d: channel list too long\n",
1234				dev->minor);
1235			break;
1236		}
1237		this_usbduxsub->dux_commands[i + 2] =
1238		    create_adc_command(chan, range);
1239	}
1240
1241	dev_dbg(&this_usbduxsub->interface->dev,
1242		"comedi %d: sending commands to the usb device: size=%u\n",
1243		dev->minor, NUMCHANNELS);
1244
1245	result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
1246	if (result < 0) {
1247		up(&this_usbduxsub->sem);
1248		return result;
1249	}
1250
1251	if (this_usbduxsub->high_speed) {
1252		/*
1253		 * every channel gets a time window of 125us. Thus, if we
1254		 * sample all 8 channels we need 1ms. If we sample only one
1255		 * channel we need only 125us
1256		 */
1257		this_usbduxsub->ai_interval = 1;
1258		/* find a power of 2 for the interval */
1259		while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
1260			this_usbduxsub->ai_interval =
1261			    (this_usbduxsub->ai_interval) * 2;
1262		}
1263		this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
1264								  (this_usbduxsub->
1265								   ai_interval));
1266	} else {
1267		/* interval always 1ms */
1268		this_usbduxsub->ai_interval = 1;
1269		this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
1270	}
1271	if (this_usbduxsub->ai_timer < 1) {
1272		dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
1273			"timer=%d, scan_begin_arg=%d. "
1274			"Not properly tested by cmdtest?\n", dev->minor,
1275			this_usbduxsub->ai_timer, cmd->scan_begin_arg);
1276		up(&this_usbduxsub->sem);
1277		return -EINVAL;
1278	}
1279	this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
1280
1281	if (cmd->stop_src == TRIG_COUNT) {
1282		/* data arrives as one packet */
1283		this_usbduxsub->ai_sample_count = cmd->stop_arg;
1284		this_usbduxsub->ai_continous = 0;
1285	} else {
1286		/* continous aquisition */
1287		this_usbduxsub->ai_continous = 1;
1288		this_usbduxsub->ai_sample_count = 0;
1289	}
1290
1291	if (cmd->start_src == TRIG_NOW) {
1292		/* enable this acquisition operation */
1293		this_usbduxsub->ai_cmd_running = 1;
1294		ret = usbduxsub_submit_InURBs(this_usbduxsub);
1295		if (ret < 0) {
1296			this_usbduxsub->ai_cmd_running = 0;
1297			/* fixme: unlink here?? */
1298			up(&this_usbduxsub->sem);
1299			return ret;
1300		}
1301		s->async->inttrig = NULL;
1302	} else {
1303		/* TRIG_INT */
1304		/* don't enable the acquision operation */
1305		/* wait for an internal signal */
1306		s->async->inttrig = usbdux_ai_inttrig;
1307	}
1308	up(&this_usbduxsub->sem);
1309	return 0;
1310}
1311
1312/* Mode 0 is used to get a single conversion on demand */
1313static int usbdux_ai_insn_read(struct comedi_device *dev,
1314			       struct comedi_subdevice *s,
1315			       struct comedi_insn *insn, unsigned int *data)
1316{
1317	int i;
1318	unsigned int one = 0;
1319	int chan, range;
1320	int err;
1321	struct usbduxsub *this_usbduxsub = dev->private;
1322
1323	if (!this_usbduxsub)
1324		return 0;
1325
1326	dev_dbg(&this_usbduxsub->interface->dev,
1327		"comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1328		dev->minor, insn->n, insn->subdev);
1329
1330	down(&this_usbduxsub->sem);
1331	if (!(this_usbduxsub->probed)) {
1332		up(&this_usbduxsub->sem);
1333		return -ENODEV;
1334	}
1335	if (this_usbduxsub->ai_cmd_running) {
1336		dev_err(&this_usbduxsub->interface->dev,
1337			"comedi%d: ai_insn_read not possible. "
1338			"Async Command is running.\n", dev->minor);
1339		up(&this_usbduxsub->sem);
1340		return 0;
1341	}
1342
1343	/* sample one channel */
1344	chan = CR_CHAN(insn->chanspec);
1345	range = CR_RANGE(insn->chanspec);
1346	/* set command for the first channel */
1347	this_usbduxsub->dux_commands[1] = create_adc_command(chan, range);
1348
1349	/* adc commands */
1350	err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
1351	if (err < 0) {
1352		up(&this_usbduxsub->sem);
1353		return err;
1354	}
1355
1356	for (i = 0; i < insn->n; i++) {
1357		err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
1358		if (err < 0) {
1359			up(&this_usbduxsub->sem);
1360			return 0;
1361		}
1362		one = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
1363		if (CR_RANGE(insn->chanspec) <= 1)
1364			one = one ^ 0x800;
1365
1366		data[i] = one;
1367	}
1368	up(&this_usbduxsub->sem);
1369	return i;
1370}
1371
1372/************************************/
1373/* analog out */
1374
1375static int usbdux_ao_insn_read(struct comedi_device *dev,
1376			       struct comedi_subdevice *s,
1377			       struct comedi_insn *insn, unsigned int *data)
1378{
1379	int i;
1380	int chan = CR_CHAN(insn->chanspec);
1381	struct usbduxsub *this_usbduxsub = dev->private;
1382
1383	if (!this_usbduxsub)
1384		return -EFAULT;
1385
1386	down(&this_usbduxsub->sem);
1387	if (!(this_usbduxsub->probed)) {
1388		up(&this_usbduxsub->sem);
1389		return -ENODEV;
1390	}
1391	for (i = 0; i < insn->n; i++)
1392		data[i] = this_usbduxsub->outBuffer[chan];
1393
1394	up(&this_usbduxsub->sem);
1395	return i;
1396}
1397
1398static int usbdux_ao_insn_write(struct comedi_device *dev,
1399				struct comedi_subdevice *s,
1400				struct comedi_insn *insn, unsigned int *data)
1401{
1402	int i, err;
1403	int chan = CR_CHAN(insn->chanspec);
1404	struct usbduxsub *this_usbduxsub = dev->private;
1405
1406	if (!this_usbduxsub)
1407		return -EFAULT;
1408
1409	dev_dbg(&this_usbduxsub->interface->dev,
1410		"comedi%d: ao_insn_write\n", dev->minor);
1411
1412	down(&this_usbduxsub->sem);
1413	if (!(this_usbduxsub->probed)) {
1414		up(&this_usbduxsub->sem);
1415		return -ENODEV;
1416	}
1417	if (this_usbduxsub->ao_cmd_running) {
1418		dev_err(&this_usbduxsub->interface->dev,
1419			"comedi%d: ao_insn_write: "
1420			"ERROR: asynchronous ao_cmd is running\n", dev->minor);
1421		up(&this_usbduxsub->sem);
1422		return 0;
1423	}
1424
1425	for (i = 0; i < insn->n; i++) {
1426		dev_dbg(&this_usbduxsub->interface->dev,
1427			"comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1428			dev->minor, chan, i, data[i]);
1429
1430		/* number of channels: 1 */
1431		this_usbduxsub->dux_commands[1] = 1;
1432		/* one 16 bit value */
1433		*((int16_t *) (this_usbduxsub->dux_commands + 2)) =
1434		    cpu_to_le16(data[i]);
1435		this_usbduxsub->outBuffer[chan] = data[i];
1436		/* channel number */
1437		this_usbduxsub->dux_commands[4] = (chan << 6);
1438		err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
1439		if (err < 0) {
1440			up(&this_usbduxsub->sem);
1441			return err;
1442		}
1443	}
1444	up(&this_usbduxsub->sem);
1445
1446	return i;
1447}
1448
1449static int usbdux_ao_inttrig(struct comedi_device *dev,
1450			     struct comedi_subdevice *s, unsigned int trignum)
1451{
1452	int ret;
1453	struct usbduxsub *this_usbduxsub = dev->private;
1454
1455	if (!this_usbduxsub)
1456		return -EFAULT;
1457
1458	down(&this_usbduxsub->sem);
1459	if (!(this_usbduxsub->probed)) {
1460		up(&this_usbduxsub->sem);
1461		return -ENODEV;
1462	}
1463	if (trignum != 0) {
1464		dev_err(&this_usbduxsub->interface->dev,
1465			"comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1466			dev->minor);
1467		return -EINVAL;
1468	}
1469	if (!(this_usbduxsub->ao_cmd_running)) {
1470		this_usbduxsub->ao_cmd_running = 1;
1471		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1472		if (ret < 0) {
1473			dev_err(&this_usbduxsub->interface->dev,
1474				"comedi%d: usbdux_ao_inttrig: submitURB: "
1475				"err=%d\n", dev->minor, ret);
1476			this_usbduxsub->ao_cmd_running = 0;
1477			up(&this_usbduxsub->sem);
1478			return ret;
1479		}
1480		s->async->inttrig = NULL;
1481	} else {
1482		dev_err(&this_usbduxsub->interface->dev,
1483			"comedi%d: ao_inttrig but acqu is already running.\n",
1484			dev->minor);
1485	}
1486	up(&this_usbduxsub->sem);
1487	return 1;
1488}
1489
1490static int usbdux_ao_cmdtest(struct comedi_device *dev,
1491			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1492{
1493	int err = 0, tmp;
1494	struct usbduxsub *this_usbduxsub = dev->private;
1495
1496	if (!this_usbduxsub)
1497		return -EFAULT;
1498
1499	if (!(this_usbduxsub->probed))
1500		return -ENODEV;
1501
1502	dev_dbg(&this_usbduxsub->interface->dev,
1503		"comedi%d: usbdux_ao_cmdtest\n", dev->minor);
1504
1505	/* make sure triggers are valid */
1506	/* Only immediate triggers are allowed */
1507	tmp = cmd->start_src;
1508	cmd->start_src &= TRIG_NOW | TRIG_INT;
1509	if (!cmd->start_src || tmp != cmd->start_src)
1510		err++;
1511
1512	/* trigger should happen timed */
1513	tmp = cmd->scan_begin_src;
1514	/* just now we scan also in the high speed mode every frame */
1515	/* this is due to ehci driver limitations */
1516	if (0) {		/* (this_usbduxsub->high_speed) */
1517		/* start immidiately a new scan */
1518		/* the sampling rate is set by the coversion rate */
1519		cmd->scan_begin_src &= TRIG_FOLLOW;
1520	} else {
1521		/* start a new scan (output at once) with a timer */
1522		cmd->scan_begin_src &= TRIG_TIMER;
1523	}
1524	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1525		err++;
1526
1527	/* scanning is continous */
1528	tmp = cmd->convert_src;
1529	/* we always output at 1kHz just now all channels at once */
1530	if (0) {		/* (this_usbduxsub->high_speed) */
1531		/*
1532		 * in usb-2.0 only one conversion it tranmitted but with 8kHz/n
1533		 */
1534		cmd->convert_src &= TRIG_TIMER;
1535	} else {
1536		/* all conversion events happen simultaneously with a rate of
1537		 * 1kHz/n */
1538		cmd->convert_src &= TRIG_NOW;
1539	}
1540	if (!cmd->convert_src || tmp != cmd->convert_src)
1541		err++;
1542
1543	/* issue a trigger when scan is finished and start a new scan */
1544	tmp = cmd->scan_end_src;
1545	cmd->scan_end_src &= TRIG_COUNT;
1546	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1547		err++;
1548
1549	/* trigger at the end of count events or not, stop condition or not */
1550	tmp = cmd->stop_src;
1551	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1552	if (!cmd->stop_src || tmp != cmd->stop_src)
1553		err++;
1554
1555	if (err)
1556		return 1;
1557
1558	/*
1559	 * step 2: make sure trigger sources are unique and mutually compatible
1560	 * note that mutual compatiblity is not an issue here
1561	 */
1562	if (cmd->scan_begin_src != TRIG_FOLLOW &&
1563	    cmd->scan_begin_src != TRIG_EXT &&
1564	    cmd->scan_begin_src != TRIG_TIMER)
1565		err++;
1566	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1567		err++;
1568
1569	if (err)
1570		return 2;
1571
1572	/* step 3: make sure arguments are trivially compatible */
1573
1574	if (cmd->start_arg != 0) {
1575		cmd->start_arg = 0;
1576		err++;
1577	}
1578
1579	if (cmd->scan_begin_src == TRIG_FOLLOW) {
1580		/* internal trigger */
1581		if (cmd->scan_begin_arg != 0) {
1582			cmd->scan_begin_arg = 0;
1583			err++;
1584		}
1585	}
1586
1587	if (cmd->scan_begin_src == TRIG_TIMER) {
1588		/* timer */
1589		if (cmd->scan_begin_arg < 1000000) {
1590			cmd->scan_begin_arg = 1000000;
1591			err++;
1592		}
1593	}
1594	/* not used now, is for later use */
1595	if (cmd->convert_src == TRIG_TIMER) {
1596		if (cmd->convert_arg < 125000) {
1597			cmd->convert_arg = 125000;
1598			err++;
1599		}
1600	}
1601
1602	/* the same argument */
1603	if (cmd->scan_end_arg != cmd->chanlist_len) {
1604		cmd->scan_end_arg = cmd->chanlist_len;
1605		err++;
1606	}
1607
1608	if (cmd->stop_src == TRIG_COUNT) {
1609		/* any count is allowed */
1610	} else {
1611		/* TRIG_NONE */
1612		if (cmd->stop_arg != 0) {
1613			cmd->stop_arg = 0;
1614			err++;
1615		}
1616	}
1617
1618	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
1619		"scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
1620		"convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
1621		cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
1622
1623	if (err)
1624		return 3;
1625
1626	return 0;
1627}
1628
1629static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1630{
1631	struct comedi_cmd *cmd = &s->async->cmd;
1632	unsigned int chan, gain;
1633	int i, ret;
1634	struct usbduxsub *this_usbduxsub = dev->private;
1635
1636	if (!this_usbduxsub)
1637		return -EFAULT;
1638
1639	down(&this_usbduxsub->sem);
1640	if (!(this_usbduxsub->probed)) {
1641		up(&this_usbduxsub->sem);
1642		return -ENODEV;
1643	}
1644	dev_dbg(&this_usbduxsub->interface->dev,
1645		"comedi%d: %s\n", dev->minor, __func__);
1646
1647	/* set current channel of the running aquisition to zero */
1648	s->async->cur_chan = 0;
1649	for (i = 0; i < cmd->chanlist_len; ++i) {
1650		chan = CR_CHAN(cmd->chanlist[i]);
1651		gain = CR_RANGE(cmd->chanlist[i]);
1652		if (i >= NUMOUTCHANNELS) {
1653			dev_err(&this_usbduxsub->interface->dev,
1654				"comedi%d: %s: channel list too long\n",
1655				dev->minor, __func__);
1656			break;
1657		}
1658		this_usbduxsub->dac_commands[i] = (chan << 6);
1659		dev_dbg(&this_usbduxsub->interface->dev,
1660			"comedi%d: dac command for ch %d is %x\n",
1661			dev->minor, i, this_usbduxsub->dac_commands[i]);
1662	}
1663
1664	/* we count in steps of 1ms (125us) */
1665	/* 125us mode not used yet */
1666	if (0) {		/* (this_usbduxsub->high_speed) */
1667		/* 125us */
1668		/* timing of the conversion itself: every 125 us */
1669		this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1670	} else {
1671		/* 1ms */
1672		/* timing of the scan: we get all channels at once */
1673		this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1674		dev_dbg(&this_usbduxsub->interface->dev,
1675			"comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1676			"convert_src=%d, convert_arg=%d\n", dev->minor,
1677			cmd->scan_begin_src, cmd->scan_begin_arg,
1678			cmd->convert_src, cmd->convert_arg);
1679		dev_dbg(&this_usbduxsub->interface->dev,
1680			"comedi%d: ao_timer=%d (ms)\n",
1681			dev->minor, this_usbduxsub->ao_timer);
1682		if (this_usbduxsub->ao_timer < 1) {
1683			dev_err(&this_usbduxsub->interface->dev,
1684				"comedi%d: usbdux: ao_timer=%d, "
1685				"scan_begin_arg=%d. "
1686				"Not properly tested by cmdtest?\n",
1687				dev->minor, this_usbduxsub->ao_timer,
1688				cmd->scan_begin_arg);
1689			up(&this_usbduxsub->sem);
1690			return -EINVAL;
1691		}
1692	}
1693	this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1694
1695	if (cmd->stop_src == TRIG_COUNT) {
1696		/* not continous */
1697		/* counter */
1698		/* high speed also scans everything at once */
1699		if (0) {	/* (this_usbduxsub->high_speed) */
1700			this_usbduxsub->ao_sample_count =
1701			    (cmd->stop_arg) * (cmd->scan_end_arg);
1702		} else {
1703			/* there's no scan as the scan has been */
1704			/* perf inside the FX2 */
1705			/* data arrives as one packet */
1706			this_usbduxsub->ao_sample_count = cmd->stop_arg;
1707		}
1708		this_usbduxsub->ao_continous = 0;
1709	} else {
1710		/* continous aquisition */
1711		this_usbduxsub->ao_continous = 1;
1712		this_usbduxsub->ao_sample_count = 0;
1713	}
1714
1715	if (cmd->start_src == TRIG_NOW) {
1716		/* enable this acquisition operation */
1717		this_usbduxsub->ao_cmd_running = 1;
1718		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1719		if (ret < 0) {
1720			this_usbduxsub->ao_cmd_running = 0;
1721			/* fixme: unlink here?? */
1722			up(&this_usbduxsub->sem);
1723			return ret;
1724		}
1725		s->async->inttrig = NULL;
1726	} else {
1727		/* TRIG_INT */
1728		/* submit the urbs later */
1729		/* wait for an internal signal */
1730		s->async->inttrig = usbdux_ao_inttrig;
1731	}
1732
1733	up(&this_usbduxsub->sem);
1734	return 0;
1735}
1736
1737static int usbdux_dio_insn_config(struct comedi_device *dev,
1738				  struct comedi_subdevice *s,
1739				  struct comedi_insn *insn, unsigned int *data)
1740{
1741	int chan = CR_CHAN(insn->chanspec);
1742
1743	/* The input or output configuration of each digital line is
1744	 * configured by a special insn_config instruction.  chanspec
1745	 * contains the channel to be changed, and data[0] contains the
1746	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1747
1748	switch (data[0]) {
1749	case INSN_CONFIG_DIO_OUTPUT:
1750		s->io_bits |= 1 << chan;	/* 1 means Out */
1751		break;
1752	case INSN_CONFIG_DIO_INPUT:
1753		s->io_bits &= ~(1 << chan);
1754		break;
1755	case INSN_CONFIG_DIO_QUERY:
1756		data[1] =
1757		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1758		break;
1759	default:
1760		return -EINVAL;
1761		break;
1762	}
1763	/* we don't tell the firmware here as it would take 8 frames */
1764	/* to submit the information. We do it in the insn_bits. */
1765	return insn->n;
1766}
1767
1768static int usbdux_dio_insn_bits(struct comedi_device *dev,
1769				struct comedi_subdevice *s,
1770				struct comedi_insn *insn, unsigned int *data)
1771{
1772
1773	struct usbduxsub *this_usbduxsub = dev->private;
1774	int err;
1775
1776	if (!this_usbduxsub)
1777		return -EFAULT;
1778
1779	if (insn->n != 2)
1780		return -EINVAL;
1781
1782	down(&this_usbduxsub->sem);
1783
1784	if (!(this_usbduxsub->probed)) {
1785		up(&this_usbduxsub->sem);
1786		return -ENODEV;
1787	}
1788
1789	/* The insn data is a mask in data[0] and the new data
1790	 * in data[1], each channel cooresponding to a bit. */
1791	s->state &= ~data[0];
1792	s->state |= data[0] & data[1];
1793	this_usbduxsub->dux_commands[1] = s->io_bits;
1794	this_usbduxsub->dux_commands[2] = s->state;
1795
1796	/* This command also tells the firmware to return */
1797	/* the digital input lines */
1798	err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1799	if (err < 0) {
1800		up(&this_usbduxsub->sem);
1801		return err;
1802	}
1803	err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1804	if (err < 0) {
1805		up(&this_usbduxsub->sem);
1806		return err;
1807	}
1808
1809	data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
1810	up(&this_usbduxsub->sem);
1811	return 2;
1812}
1813
1814/* reads the 4 counters, only two are used just now */
1815static int usbdux_counter_read(struct comedi_device *dev,
1816			       struct comedi_subdevice *s,
1817			       struct comedi_insn *insn, unsigned int *data)
1818{
1819	struct usbduxsub *this_usbduxsub = dev->private;
1820	int chan = insn->chanspec;
1821	int err;
1822
1823	if (!this_usbduxsub)
1824		return -EFAULT;
1825
1826	down(&this_usbduxsub->sem);
1827
1828	if (!(this_usbduxsub->probed)) {
1829		up(&this_usbduxsub->sem);
1830		return -ENODEV;
1831	}
1832
1833	err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1834	if (err < 0) {
1835		up(&this_usbduxsub->sem);
1836		return err;
1837	}
1838
1839	err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1840	if (err < 0) {
1841		up(&this_usbduxsub->sem);
1842		return err;
1843	}
1844
1845	data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]);
1846	up(&this_usbduxsub->sem);
1847	return 1;
1848}
1849
1850static int usbdux_counter_write(struct comedi_device *dev,
1851				struct comedi_subdevice *s,
1852				struct comedi_insn *insn, unsigned int *data)
1853{
1854	struct usbduxsub *this_usbduxsub = dev->private;
1855	int err;
1856
1857	if (!this_usbduxsub)
1858		return -EFAULT;
1859
1860	down(&this_usbduxsub->sem);
1861
1862	if (!(this_usbduxsub->probed)) {
1863		up(&this_usbduxsub->sem);
1864		return -ENODEV;
1865	}
1866
1867	this_usbduxsub->dux_commands[1] = insn->chanspec;
1868	*((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1869
1870	err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1871	if (err < 0) {
1872		up(&this_usbduxsub->sem);
1873		return err;
1874	}
1875
1876	up(&this_usbduxsub->sem);
1877
1878	return 1;
1879}
1880
1881static int usbdux_counter_config(struct comedi_device *dev,
1882				 struct comedi_subdevice *s,
1883				 struct comedi_insn *insn, unsigned int *data)
1884{
1885	/* nothing to do so far */
1886	return 2;
1887}
1888
1889/***********************************/
1890/* PWM */
1891
1892static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
1893{
1894	int err = 0;
1895
1896	if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
1897		if (usbduxsub_tmp->urbPwm)
1898			usb_kill_urb(usbduxsub_tmp->urbPwm);
1899		dev_dbg(&usbduxsub_tmp->interface->dev,
1900			"comedi: unlinked PwmURB: res=%d\n", err);
1901	}
1902	return err;
1903}
1904
1905/* This cancels a running acquisition operation
1906 * in any context.
1907 */
1908static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
1909{
1910	int ret = 0;
1911
1912	if (!this_usbduxsub)
1913		return -EFAULT;
1914
1915	dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1916	if (do_unlink)
1917		ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
1918
1919	this_usbduxsub->pwm_cmd_running = 0;
1920
1921	return ret;
1922}
1923
1924/* force unlink - is called by comedi */
1925static int usbdux_pwm_cancel(struct comedi_device *dev,
1926			     struct comedi_subdevice *s)
1927{
1928	struct usbduxsub *this_usbduxsub = dev->private;
1929	int res = 0;
1930
1931	/* unlink only if it is really running */
1932	res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1933
1934	dev_dbg(&this_usbduxsub->interface->dev,
1935		"comedi %d: sending pwm off command to the usb device.\n",
1936		dev->minor);
1937	res = send_dux_commands(this_usbduxsub, SENDPWMOFF);
1938	if (res < 0)
1939		return res;
1940
1941	return res;
1942}
1943
1944static void usbduxsub_pwm_irq(struct urb *urb)
1945{
1946	int ret;
1947	struct usbduxsub *this_usbduxsub;
1948	struct comedi_device *this_comedidev;
1949	struct comedi_subdevice *s;
1950
1951	/* printk(KERN_DEBUG "PWM: IRQ\n"); */
1952
1953	/* the context variable points to the subdevice */
1954	this_comedidev = urb->context;
1955	/* the private structure of the subdevice is struct usbduxsub */
1956	this_usbduxsub = this_comedidev->private;
1957
1958	s = this_comedidev->subdevices + SUBDEV_DA;
1959
1960	switch (urb->status) {
1961	case 0:
1962		/* success */
1963		break;
1964
1965	case -ECONNRESET:
1966	case -ENOENT:
1967	case -ESHUTDOWN:
1968	case -ECONNABORTED:
1969		/*
1970		 * after an unlink command, unplug, ... etc
1971		 * no unlink needed here. Already shutting down.
1972		 */
1973		if (this_usbduxsub->pwm_cmd_running)
1974			usbdux_pwm_stop(this_usbduxsub, 0);
1975
1976		return;
1977
1978	default:
1979		/* a real error */
1980		if (this_usbduxsub->pwm_cmd_running) {
1981			dev_err(&this_usbduxsub->interface->dev,
1982				"comedi_: Non-zero urb status received in "
1983				"pwm intr context: %d\n", urb->status);
1984			usbdux_pwm_stop(this_usbduxsub, 0);
1985		}
1986		return;
1987	}
1988
1989	/* are we actually running? */
1990	if (!(this_usbduxsub->pwm_cmd_running))
1991		return;
1992
1993	urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
1994	urb->dev = this_usbduxsub->usbdev;
1995	urb->status = 0;
1996	if (this_usbduxsub->pwm_cmd_running) {
1997		ret = usb_submit_urb(urb, GFP_ATOMIC);
1998		if (ret < 0) {
1999			dev_err(&this_usbduxsub->interface->dev,
2000				"comedi_: pwm urb resubm failed in int-cont. "
2001				"ret=%d", ret);
2002			if (ret == EL2NSYNC)
2003				dev_err(&this_usbduxsub->interface->dev,
2004					"buggy USB host controller or bug in "
2005					"IRQ handling!\n");
2006
2007			/* don't do an unlink here */
2008			usbdux_pwm_stop(this_usbduxsub, 0);
2009		}
2010	}
2011}
2012
2013static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
2014{
2015	int errFlag;
2016
2017	if (!usbduxsub)
2018		return -EFAULT;
2019
2020	dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
2021
2022	/* in case of a resubmission after an unlink... */
2023	usb_fill_bulk_urb(usbduxsub->urbPwm,
2024			  usbduxsub->usbdev,
2025			  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
2026			  usbduxsub->urbPwm->transfer_buffer,
2027			  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
2028			  usbduxsub->comedidev);
2029
2030	errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
2031	if (errFlag) {
2032		dev_err(&usbduxsub->interface->dev,
2033			"comedi_: usbdux: pwm: usb_submit_urb error %d\n",
2034			errFlag);
2035		return errFlag;
2036	}
2037	return 0;
2038}
2039
2040static int usbdux_pwm_period(struct comedi_device *dev,
2041			     struct comedi_subdevice *s, unsigned int period)
2042{
2043	struct usbduxsub *this_usbduxsub = dev->private;
2044	int fx2delay = 255;
2045
2046	if (period < MIN_PWM_PERIOD) {
2047		dev_err(&this_usbduxsub->interface->dev,
2048			"comedi%d: illegal period setting for pwm.\n",
2049			dev->minor);
2050		return -EAGAIN;
2051	} else {
2052		fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
2053		if (fx2delay > 255) {
2054			dev_err(&this_usbduxsub->interface->dev,
2055				"comedi%d: period %d for pwm is too low.\n",
2056				dev->minor, period);
2057			return -EAGAIN;
2058		}
2059	}
2060	this_usbduxsub->pwmDelay = fx2delay;
2061	this_usbduxsub->pwmPeriod = period;
2062	dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
2063		__func__, period, fx2delay);
2064	return 0;
2065}
2066
2067/* is called from insn so there's no need to do all the sanity checks */
2068static int usbdux_pwm_start(struct comedi_device *dev,
2069			    struct comedi_subdevice *s)
2070{
2071	int ret, i;
2072	struct usbduxsub *this_usbduxsub = dev->private;
2073
2074	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
2075		dev->minor, __func__);
2076
2077	if (this_usbduxsub->pwm_cmd_running) {
2078		/* already running */
2079		return 0;
2080	}
2081
2082	this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay);
2083	ret = send_dux_commands(this_usbduxsub, SENDPWMON);
2084	if (ret < 0)
2085		return ret;
2086
2087	/* initalise the buffer */
2088	for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
2089		((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
2090
2091	this_usbduxsub->pwm_cmd_running = 1;
2092	ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2093	if (ret < 0) {
2094		this_usbduxsub->pwm_cmd_running = 0;
2095		return ret;
2096	}
2097	return 0;
2098}
2099
2100/* generates the bit pattern for PWM with the optional sign bit */
2101static int usbdux_pwm_pattern(struct comedi_device *dev,
2102			      struct comedi_subdevice *s, int channel,
2103			      unsigned int value, unsigned int sign)
2104{
2105	struct usbduxsub *this_usbduxsub = dev->private;
2106	int i, szbuf;
2107	char *pBuf;
2108	char pwm_mask;
2109	char sgn_mask;
2110	char c;
2111
2112	if (!this_usbduxsub)
2113		return -EFAULT;
2114
2115	/* this is the DIO bit which carries the PWM data */
2116	pwm_mask = (1 << channel);
2117	/* this is the DIO bit which carries the optional direction bit */
2118	sgn_mask = (16 << channel);
2119	/* this is the buffer which will be filled with the with bit */
2120	/* pattern for one period */
2121	szbuf = this_usbduxsub->sizePwmBuf;
2122	pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
2123	for (i = 0; i < szbuf; i++) {
2124		c = *pBuf;
2125		/* reset bits */
2126		c = c & (~pwm_mask);
2127		/* set the bit as long as the index is lower than the value */
2128		if (i < value)
2129			c = c | pwm_mask;
2130		/* set the optional sign bit for a relay */
2131		if (!sign) {
2132			/* positive value */
2133			c = c & (~sgn_mask);
2134		} else {
2135			/* negative value */
2136			c = c | sgn_mask;
2137		}
2138		*(pBuf++) = c;
2139	}
2140	return 1;
2141}
2142
2143static int usbdux_pwm_write(struct comedi_device *dev,
2144			    struct comedi_subdevice *s,
2145			    struct comedi_insn *insn, unsigned int *data)
2146{
2147	struct usbduxsub *this_usbduxsub = dev->private;
2148
2149	if (!this_usbduxsub)
2150		return -EFAULT;
2151
2152	if ((insn->n) != 1) {
2153		/*
2154		 * doesn't make sense to have more than one value here because
2155		 * it would just overwrite the PWM buffer a couple of times
2156		 */
2157		return -EINVAL;
2158	}
2159
2160	/*
2161	 * the sign is set via a special INSN only, this gives us 8 bits for
2162	 * normal operation
2163	 * relay sign 0 by default
2164	 */
2165	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2166}
2167
2168static int usbdux_pwm_read(struct comedi_device *x1,
2169			   struct comedi_subdevice *x2, struct comedi_insn *x3,
2170			   unsigned int *x4)
2171{
2172	/* not needed */
2173	return -EINVAL;
2174};
2175
2176/* switches on/off PWM */
2177static int usbdux_pwm_config(struct comedi_device *dev,
2178			     struct comedi_subdevice *s,
2179			     struct comedi_insn *insn, unsigned int *data)
2180{
2181	struct usbduxsub *this_usbduxsub = dev->private;
2182	switch (data[0]) {
2183	case INSN_CONFIG_ARM:
2184		/* switch it on */
2185		dev_dbg(&this_usbduxsub->interface->dev,
2186			"comedi%d: %s: pwm on\n", dev->minor, __func__);
2187		/*
2188		 * if not zero the PWM is limited to a certain time which is
2189		 * not supported here
2190		 */
2191		if (data[1] != 0)
2192			return -EINVAL;
2193		return usbdux_pwm_start(dev, s);
2194	case INSN_CONFIG_DISARM:
2195		dev_dbg(&this_usbduxsub->interface->dev,
2196			"comedi%d: %s: pwm off\n", dev->minor, __func__);
2197		return usbdux_pwm_cancel(dev, s);
2198	case INSN_CONFIG_GET_PWM_STATUS:
2199		/*
2200		 * to check if the USB transmission has failed or in case PWM
2201		 * was limited to n cycles to check if it has terminated
2202		 */
2203		data[1] = this_usbduxsub->pwm_cmd_running;
2204		return 0;
2205	case INSN_CONFIG_PWM_SET_PERIOD:
2206		dev_dbg(&this_usbduxsub->interface->dev,
2207			"comedi%d: %s: setting period\n", dev->minor, __func__);
2208		return usbdux_pwm_period(dev, s, data[1]);
2209	case INSN_CONFIG_PWM_GET_PERIOD:
2210		data[1] = this_usbduxsub->pwmPeriod;
2211		return 0;
2212	case INSN_CONFIG_PWM_SET_H_BRIDGE:
2213		/* value in the first byte and the sign in the second for a
2214		   relay */
2215		return usbdux_pwm_pattern(dev, s,
2216					  /* the channel number */
2217					  CR_CHAN(insn->chanspec),
2218					  /* actual PWM data */
2219					  data[1],
2220					  /* just a sign */
2221					  (data[2] != 0));
2222	case INSN_CONFIG_PWM_GET_H_BRIDGE:
2223		/* values are not kept in this driver, nothing to return here */
2224		return -EINVAL;
2225	}
2226	return -EINVAL;
2227}
2228
2229/* end of PWM */
2230/*****************************************************************/
2231
2232static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2233{
2234	int i;
2235
2236	if (!usbduxsub_tmp)
2237		return;
2238	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2239
2240	/* shows the usb subsystem that the driver is down */
2241	if (usbduxsub_tmp->interface)
2242		usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2243
2244	usbduxsub_tmp->probed = 0;
2245
2246	if (usbduxsub_tmp->urbIn) {
2247		if (usbduxsub_tmp->ai_cmd_running) {
2248			usbduxsub_tmp->ai_cmd_running = 0;
2249			usbduxsub_unlink_InURBs(usbduxsub_tmp);
2250		}
2251		for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
2252			kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
2253			usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
2254			usb_kill_urb(usbduxsub_tmp->urbIn[i]);
2255			usb_free_urb(usbduxsub_tmp->urbIn[i]);
2256			usbduxsub_tmp->urbIn[i] = NULL;
2257		}
2258		kfree(usbduxsub_tmp->urbIn);
2259		usbduxsub_tmp->urbIn = NULL;
2260	}
2261	if (usbduxsub_tmp->urbOut) {
2262		if (usbduxsub_tmp->ao_cmd_running) {
2263			usbduxsub_tmp->ao_cmd_running = 0;
2264			usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2265		}
2266		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
2267			if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
2268				kfree(usbduxsub_tmp->
2269				      urbOut[i]->transfer_buffer);
2270				usbduxsub_tmp->urbOut[i]->transfer_buffer =
2271				    NULL;
2272			}
2273			if (usbduxsub_tmp->urbOut[i]) {
2274				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
2275				usb_free_urb(usbduxsub_tmp->urbOut[i]);
2276				usbduxsub_tmp->urbOut[i] = NULL;
2277			}
2278		}
2279		kfree(usbduxsub_tmp->urbOut);
2280		usbduxsub_tmp->urbOut = NULL;
2281	}
2282	if (usbduxsub_tmp->urbPwm) {
2283		if (usbduxsub_tmp->pwm_cmd_running) {
2284			usbduxsub_tmp->pwm_cmd_running = 0;
2285			usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2286		}
2287		kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
2288		usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
2289		usb_kill_urb(usbduxsub_tmp->urbPwm);
2290		usb_free_urb(usbduxsub_tmp->urbPwm);
2291		usbduxsub_tmp->urbPwm = NULL;
2292	}
2293	kfree(usbduxsub_tmp->inBuffer);
2294	usbduxsub_tmp->inBuffer = NULL;
2295	kfree(usbduxsub_tmp->insnBuffer);
2296	usbduxsub_tmp->insnBuffer = NULL;
2297	kfree(usbduxsub_tmp->inBuffer);
2298	usbduxsub_tmp->inBuffer = NULL;
2299	kfree(usbduxsub_tmp->dac_commands);
2300	usbduxsub_tmp->dac_commands = NULL;
2301	kfree(usbduxsub_tmp->dux_commands);
2302	usbduxsub_tmp->dux_commands = NULL;
2303	usbduxsub_tmp->ai_cmd_running = 0;
2304	usbduxsub_tmp->ao_cmd_running = 0;
2305	usbduxsub_tmp->pwm_cmd_running = 0;
2306}
2307
2308static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2309						     void *context)
2310{
2311	struct usbduxsub *usbduxsub_tmp = context;
2312	struct usb_device *usbdev = usbduxsub_tmp->usbdev;
2313	int ret;
2314
2315	if (fw == NULL) {
2316		dev_err(&usbdev->dev,
2317			"Firmware complete handler without firmware!\n");
2318		return;
2319	}
2320
2321	/*
2322	 * we need to upload the firmware here because fw will be
2323	 * freed once we've left this function
2324	 */
2325	ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
2326
2327	if (ret) {
2328		dev_err(&usbdev->dev,
2329			"Could not upload firmware (err=%d)\n", ret);
2330		goto out;
2331	}
2332	comedi_usb_auto_config(usbdev, BOARDNAME);
2333 out:
2334	release_firmware(fw);
2335}
2336
2337/* allocate memory for the urbs and initialise them */
2338static int usbduxsub_probe(struct usb_interface *uinterf,
2339			   const struct usb_device_id *id)
2340{
2341	struct usb_device *udev = interface_to_usbdev(uinterf);
2342	struct device *dev = &uinterf->dev;
2343	int i;
2344	int index;
2345	int ret;
2346
2347	dev_dbg(dev, "comedi_: usbdux_: "
2348		"finding a free structure for the usb-device\n");
2349
2350	down(&start_stop_sem);
2351	/* look for a free place in the usbdux array */
2352	index = -1;
2353	for (i = 0; i < NUMUSBDUX; i++) {
2354		if (!(usbduxsub[i].probed)) {
2355			index = i;
2356			break;
2357		}
2358	}
2359
2360	/* no more space */
2361	if (index == -1) {
2362		dev_err(dev, "Too many usbdux-devices connected.\n");
2363		up(&start_stop_sem);
2364		return -EMFILE;
2365	}
2366	dev_dbg(dev, "comedi_: usbdux: "
2367		"usbduxsub[%d] is ready to connect to comedi.\n", index);
2368
2369	init_MUTEX(&(usbduxsub[index].sem));
2370	/* save a pointer to the usb device */
2371	usbduxsub[index].usbdev = udev;
2372
2373	/* 2.6: save the interface itself */
2374	usbduxsub[index].interface = uinterf;
2375	/* get the interface number from the interface */
2376	usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2377	/* hand the private data over to the usb subsystem */
2378	/* will be needed for disconnect */
2379	usb_set_intfdata(uinterf, &(usbduxsub[index]));
2380
2381	dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2382
2383	/* test if it is high speed (USB 2.0) */
2384	usbduxsub[index].high_speed =
2385	    (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2386
2387	/* create space for the commands of the DA converter */
2388	usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2389	if (!usbduxsub[index].dac_commands) {
2390		dev_err(dev, "comedi_: usbdux: "
2391			"error alloc space for dac commands\n");
2392		tidy_up(&(usbduxsub[index]));
2393		up(&start_stop_sem);
2394		return -ENOMEM;
2395	}
2396	/* create space for the commands going to the usb device */
2397	usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2398	if (!usbduxsub[index].dux_commands) {
2399		dev_err(dev, "comedi_: usbdux: "
2400			"error alloc space for dac commands\n");
2401		tidy_up(&(usbduxsub[index]));
2402		up(&start_stop_sem);
2403		return -ENOMEM;
2404	}
2405	/* create space for the in buffer and set it to zero */
2406	usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2407	if (!(usbduxsub[index].inBuffer)) {
2408		dev_err(dev, "comedi_: usbdux: "
2409			"could not alloc space for inBuffer\n");
2410		tidy_up(&(usbduxsub[index]));
2411		up(&start_stop_sem);
2412		return -ENOMEM;
2413	}
2414	/* create space of the instruction buffer */
2415	usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2416	if (!(usbduxsub[index].insnBuffer)) {
2417		dev_err(dev, "comedi_: usbdux: "
2418			"could not alloc space for insnBuffer\n");
2419		tidy_up(&(usbduxsub[index]));
2420		up(&start_stop_sem);
2421		return -ENOMEM;
2422	}
2423	/* create space for the outbuffer */
2424	usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2425	if (!(usbduxsub[index].outBuffer)) {
2426		dev_err(dev, "comedi_: usbdux: "
2427			"could not alloc space for outBuffer\n");
2428		tidy_up(&(usbduxsub[index]));
2429		up(&start_stop_sem);
2430		return -ENOMEM;
2431	}
2432	/* setting to alternate setting 3: enabling iso ep and bulk ep. */
2433	i = usb_set_interface(usbduxsub[index].usbdev,
2434			      usbduxsub[index].ifnum, 3);
2435	if (i < 0) {
2436		dev_err(dev, "comedi_: usbdux%d: "
2437			"could not set alternate setting 3 in high speed.\n",
2438			index);
2439		tidy_up(&(usbduxsub[index]));
2440		up(&start_stop_sem);
2441		return -ENODEV;
2442	}
2443	if (usbduxsub[index].high_speed)
2444		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
2445	else
2446		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
2447
2448	usbduxsub[index].urbIn =
2449	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
2450		    GFP_KERNEL);
2451	if (!(usbduxsub[index].urbIn)) {
2452		dev_err(dev, "comedi_: usbdux: Could not alloc. urbIn array\n");
2453		tidy_up(&(usbduxsub[index]));
2454		up(&start_stop_sem);
2455		return -ENOMEM;
2456	}
2457	for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
2458		/* one frame: 1ms */
2459		usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
2460		if (usbduxsub[index].urbIn[i] == NULL) {
2461			dev_err(dev, "comedi_: usbdux%d: "
2462				"Could not alloc. urb(%d)\n", index, i);
2463			tidy_up(&(usbduxsub[index]));
2464			up(&start_stop_sem);
2465			return -ENOMEM;
2466		}
2467		usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
2468		/* will be filled later with a pointer to the comedi-device */
2469		/* and ONLY then the urb should be submitted */
2470		usbduxsub[index].urbIn[i]->context = NULL;
2471		usbduxsub[index].urbIn[i]->pipe =
2472		    usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2473		usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
2474		usbduxsub[index].urbIn[i]->transfer_buffer =
2475		    kzalloc(SIZEINBUF, GFP_KERNEL);
2476		if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
2477			dev_err(dev, "comedi_: usbdux%d: "
2478				"could not alloc. transb.\n", index);
2479			tidy_up(&(usbduxsub[index]));
2480			up(&start_stop_sem);
2481			return -ENOMEM;
2482		}
2483		usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
2484		usbduxsub[index].urbIn[i]->number_of_packets = 1;
2485		usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
2486		usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
2487		usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF;
2488	}
2489
2490	/* out */
2491	if (usbduxsub[index].high_speed)
2492		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
2493	else
2494		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
2495
2496	usbduxsub[index].urbOut =
2497	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
2498		    GFP_KERNEL);
2499	if (!(usbduxsub[index].urbOut)) {
2500		dev_err(dev, "comedi_: usbdux: "
2501			"Could not alloc. urbOut array\n");
2502		tidy_up(&(usbduxsub[index]));
2503		up(&start_stop_sem);
2504		return -ENOMEM;
2505	}
2506	for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
2507		/* one frame: 1ms */
2508		usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
2509		if (usbduxsub[index].urbOut[i] == NULL) {
2510			dev_err(dev, "comedi_: usbdux%d: "
2511				"Could not alloc. urb(%d)\n", index, i);
2512			tidy_up(&(usbduxsub[index]));
2513			up(&start_stop_sem);
2514			return -ENOMEM;
2515		}
2516		usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
2517		/* will be filled later with a pointer to the comedi-device */
2518		/* and ONLY then the urb should be submitted */
2519		usbduxsub[index].urbOut[i]->context = NULL;
2520		usbduxsub[index].urbOut[i]->pipe =
2521		    usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2522		usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
2523		usbduxsub[index].urbOut[i]->transfer_buffer =
2524		    kzalloc(SIZEOUTBUF, GFP_KERNEL);
2525		if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
2526			dev_err(dev, "comedi_: usbdux%d: "
2527				"could not alloc. transb.\n", index);
2528			tidy_up(&(usbduxsub[index]));
2529			up(&start_stop_sem);
2530			return -ENOMEM;
2531		}
2532		usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
2533		usbduxsub[index].urbOut[i]->number_of_packets = 1;
2534		usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
2535		usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
2536		usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
2537		    SIZEOUTBUF;
2538		if (usbduxsub[index].high_speed) {
2539			/* uframes */
2540			usbduxsub[index].urbOut[i]->interval = 8;
2541		} else {
2542			/* frames */
2543			usbduxsub[index].urbOut[i]->interval = 1;
2544		}
2545	}
2546
2547	/* pwm */
2548	if (usbduxsub[index].high_speed) {
2549		/* max bulk ep size in high speed */
2550		usbduxsub[index].sizePwmBuf = 512;
2551		usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
2552		if (usbduxsub[index].urbPwm == NULL) {
2553			dev_err(dev, "comedi_: usbdux%d: "
2554				"Could not alloc. pwm urb\n", index);
2555			tidy_up(&(usbduxsub[index]));
2556			up(&start_stop_sem);
2557			return -ENOMEM;
2558		}
2559		usbduxsub[index].urbPwm->transfer_buffer =
2560		    kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
2561		if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2562			dev_err(dev, "comedi_: usbdux%d: "
2563				"could not alloc. transb. for pwm\n", index);
2564			tidy_up(&(usbduxsub[index]));
2565			up(&start_stop_sem);
2566			return -ENOMEM;
2567		}
2568	} else {
2569		usbduxsub[index].urbPwm = NULL;
2570		usbduxsub[index].sizePwmBuf = 0;
2571	}
2572
2573	usbduxsub[index].ai_cmd_running = 0;
2574	usbduxsub[index].ao_cmd_running = 0;
2575	usbduxsub[index].pwm_cmd_running = 0;
2576
2577	/* we've reached the bottom of the function */
2578	usbduxsub[index].probed = 1;
2579	up(&start_stop_sem);
2580
2581	ret = request_firmware_nowait(THIS_MODULE,
2582				      FW_ACTION_HOTPLUG,
2583				      "usbdux_firmware.bin",
2584				      &udev->dev,
2585				      GFP_KERNEL,
2586				      usbduxsub + index,
2587				      usbdux_firmware_request_complete_handler);
2588
2589	if (ret) {
2590		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2591		return ret;
2592	}
2593
2594	dev_info(dev, "comedi_: usbdux%d "
2595		 "has been successfully initialised.\n", index);
2596	/* success */
2597	return 0;
2598}
2599
2600static void usbduxsub_disconnect(struct usb_interface *intf)
2601{
2602	struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2603	struct usb_device *udev = interface_to_usbdev(intf);
2604
2605	if (!usbduxsub_tmp) {
2606		dev_err(&intf->dev,
2607			"comedi_: disconnect called with null pointer.\n");
2608		return;
2609	}
2610	if (usbduxsub_tmp->usbdev != udev) {
2611		dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
2612		return;
2613	}
2614	comedi_usb_auto_unconfig(udev);
2615	down(&start_stop_sem);
2616	down(&usbduxsub_tmp->sem);
2617	tidy_up(usbduxsub_tmp);
2618	up(&usbduxsub_tmp->sem);
2619	up(&start_stop_sem);
2620	dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n");
2621}
2622
2623/* is called when comedi-config is called */
2624static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2625{
2626	int ret;
2627	int index;
2628	int i;
2629	struct usbduxsub *udev;
2630
2631	struct comedi_subdevice *s = NULL;
2632	dev->private = NULL;
2633
2634	down(&start_stop_sem);
2635	/* find a valid device which has been detected by the probe function of
2636	 * the usb */
2637	index = -1;
2638	for (i = 0; i < NUMUSBDUX; i++) {
2639		if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
2640			index = i;
2641			break;
2642		}
2643	}
2644
2645	if (index < 0) {
2646		printk(KERN_ERR "comedi%d: usbdux: error: attach failed, no "
2647		       "usbdux devs connected to the usb bus.\n", dev->minor);
2648		up(&start_stop_sem);
2649		return -ENODEV;
2650	}
2651
2652	udev = &usbduxsub[index];
2653	down(&udev->sem);
2654	/* pointer back to the corresponding comedi device */
2655	udev->comedidev = dev;
2656
2657	/* trying to upload the firmware into the chip */
2658	if (comedi_aux_data(it->options, 0) &&
2659	    it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
2660		firmwareUpload(udev, comedi_aux_data(it->options, 0),
2661			       it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
2662	}
2663
2664	dev->board_name = BOARDNAME;
2665
2666	/* set number of subdevices */
2667	if (udev->high_speed) {
2668		/* with pwm */
2669		dev->n_subdevices = 5;
2670	} else {
2671		/* without pwm */
2672		dev->n_subdevices = 4;
2673	}
2674
2675	/* allocate space for the subdevices */
2676	ret = alloc_subdevices(dev, dev->n_subdevices);
2677	if (ret < 0) {
2678		dev_err(&udev->interface->dev,
2679			"comedi%d: error alloc space for subdev\n", dev->minor);
2680		up(&start_stop_sem);
2681		return ret;
2682	}
2683
2684	dev_info(&udev->interface->dev,
2685		 "comedi%d: usb-device %d is attached to comedi.\n",
2686		 dev->minor, index);
2687	/* private structure is also simply the usb-structure */
2688	dev->private = udev;
2689
2690	/* the first subdevice is the A/D converter */
2691	s = dev->subdevices + SUBDEV_AD;
2692	/* the URBs get the comedi subdevice */
2693	/* which is responsible for reading */
2694	/* this is the subdevice which reads data */
2695	dev->read_subdev = s;
2696	/* the subdevice receives as private structure the */
2697	/* usb-structure */
2698	s->private = NULL;
2699	/* analog input */
2700	s->type = COMEDI_SUBD_AI;
2701	/* readable and ref is to ground */
2702	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2703	/* 8 channels */
2704	s->n_chan = 8;
2705	/* length of the channellist */
2706	s->len_chanlist = 8;
2707	/* callback functions */
2708	s->insn_read = usbdux_ai_insn_read;
2709	s->do_cmdtest = usbdux_ai_cmdtest;
2710	s->do_cmd = usbdux_ai_cmd;
2711	s->cancel = usbdux_ai_cancel;
2712	/* max value from the A/D converter (12bit) */
2713	s->maxdata = 0xfff;
2714	/* range table to convert to physical units */
2715	s->range_table = (&range_usbdux_ai_range);
2716
2717	/* analog out */
2718	s = dev->subdevices + SUBDEV_DA;
2719	/* analog out */
2720	s->type = COMEDI_SUBD_AO;
2721	/* backward pointer */
2722	dev->write_subdev = s;
2723	/* the subdevice receives as private structure the */
2724	/* usb-structure */
2725	s->private = NULL;
2726	/* are writable */
2727	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2728	/* 4 channels */
2729	s->n_chan = 4;
2730	/* length of the channellist */
2731	s->len_chanlist = 4;
2732	/* 12 bit resolution */
2733	s->maxdata = 0x0fff;
2734	/* bipolar range */
2735	s->range_table = (&range_usbdux_ao_range);
2736	/* callback */
2737	s->do_cmdtest = usbdux_ao_cmdtest;
2738	s->do_cmd = usbdux_ao_cmd;
2739	s->cancel = usbdux_ao_cancel;
2740	s->insn_read = usbdux_ao_insn_read;
2741	s->insn_write = usbdux_ao_insn_write;
2742
2743	/* digital I/O */
2744	s = dev->subdevices + SUBDEV_DIO;
2745	s->type = COMEDI_SUBD_DIO;
2746	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2747	s->n_chan = 8;
2748	s->maxdata = 1;
2749	s->range_table = (&range_digital);
2750	s->insn_bits = usbdux_dio_insn_bits;
2751	s->insn_config = usbdux_dio_insn_config;
2752	/* we don't use it */
2753	s->private = NULL;
2754
2755	/* counter */
2756	s = dev->subdevices + SUBDEV_COUNTER;
2757	s->type = COMEDI_SUBD_COUNTER;
2758	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2759	s->n_chan = 4;
2760	s->maxdata = 0xFFFF;
2761	s->insn_read = usbdux_counter_read;
2762	s->insn_write = usbdux_counter_write;
2763	s->insn_config = usbdux_counter_config;
2764
2765	if (udev->high_speed) {
2766		/* timer / pwm */
2767		s = dev->subdevices + SUBDEV_PWM;
2768		s->type = COMEDI_SUBD_PWM;
2769		s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2770		s->n_chan = 8;
2771		/* this defines the max duty cycle resolution */
2772		s->maxdata = udev->sizePwmBuf;
2773		s->insn_write = usbdux_pwm_write;
2774		s->insn_read = usbdux_pwm_read;
2775		s->insn_config = usbdux_pwm_config;
2776		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2777	}
2778	/* finally decide that it's attached */
2779	udev->attached = 1;
2780
2781	up(&udev->sem);
2782
2783	up(&start_stop_sem);
2784
2785	dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n",
2786		 dev->minor);
2787
2788	return 0;
2789}
2790
2791static int usbdux_detach(struct comedi_device *dev)
2792{
2793	struct usbduxsub *usbduxsub_tmp;
2794
2795	if (!dev) {
2796		printk(KERN_ERR
2797		       "comedi?: usbdux: detach without dev variable...\n");
2798		return -EFAULT;
2799	}
2800
2801	usbduxsub_tmp = dev->private;
2802	if (!usbduxsub_tmp) {
2803		printk(KERN_ERR
2804		       "comedi?: usbdux: detach without ptr to usbduxsub[]\n");
2805		return -EFAULT;
2806	}
2807
2808	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi%d: detach usb device\n",
2809		dev->minor);
2810
2811	down(&usbduxsub_tmp->sem);
2812	/* Don't allow detach to free the private structure */
2813	/* It's one entry of of usbduxsub[] */
2814	dev->private = NULL;
2815	usbduxsub_tmp->attached = 0;
2816	usbduxsub_tmp->comedidev = NULL;
2817	dev_dbg(&usbduxsub_tmp->interface->dev,
2818		"comedi%d: detach: successfully removed\n", dev->minor);
2819	up(&usbduxsub_tmp->sem);
2820	return 0;
2821}
2822
2823/* main driver struct */
2824static struct comedi_driver driver_usbdux = {
2825	.driver_name = "usbdux",
2826	.module = THIS_MODULE,
2827	.attach = usbdux_attach,
2828	.detach = usbdux_detach,
2829};
2830
2831/* Table with the USB-devices: just now only testing IDs */
2832static struct usb_device_id usbduxsub_table[] = {
2833	{USB_DEVICE(0x13d8, 0x0001)},
2834	{USB_DEVICE(0x13d8, 0x0002)},
2835	{}			/* Terminating entry */
2836};
2837
2838MODULE_DEVICE_TABLE(usb, usbduxsub_table);
2839
2840/* The usbduxsub-driver */
2841static struct usb_driver usbduxsub_driver = {
2842	.name = BOARDNAME,
2843	.probe = usbduxsub_probe,
2844	.disconnect = usbduxsub_disconnect,
2845	.id_table = usbduxsub_table,
2846};
2847
2848/* Can't use the nice macro as I have also to initialise the USB */
2849/* subsystem: */
2850/* registering the usb-system _and_ the comedi-driver */
2851static int __init init_usbdux(void)
2852{
2853	printk(KERN_INFO KBUILD_MODNAME ": "
2854	       DRIVER_VERSION ":" DRIVER_DESC "\n");
2855	usb_register(&usbduxsub_driver);
2856	comedi_driver_register(&driver_usbdux);
2857	return 0;
2858}
2859
2860/* deregistering the comedi driver and the usb-subsystem */
2861static void __exit exit_usbdux(void)
2862{
2863	comedi_driver_unregister(&driver_usbdux);
2864	usb_deregister(&usbduxsub_driver);
2865}
2866
2867module_init(init_usbdux);
2868module_exit(exit_usbdux);
2869
2870MODULE_AUTHOR(DRIVER_AUTHOR);
2871MODULE_DESCRIPTION(DRIVER_DESC);
2872MODULE_LICENSE("GPL");
2873