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