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