usbdux.c revision c5274ab09747d0ef829f9b8f040756758e5de55c
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 acquisition */
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 continuous, 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 acquisition */
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 continuous */
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 acquisition 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 acquisition */
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 immediately 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 continuous */
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 transmitted 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 acquisition 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 continuous */
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 acquisition */
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
1939	return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1940}
1941
1942static void usbduxsub_pwm_irq(struct urb *urb)
1943{
1944	int ret;
1945	struct usbduxsub *this_usbduxsub;
1946	struct comedi_device *this_comedidev;
1947	struct comedi_subdevice *s;
1948
1949	/* printk(KERN_DEBUG "PWM: IRQ\n"); */
1950
1951	/* the context variable points to the subdevice */
1952	this_comedidev = urb->context;
1953	/* the private structure of the subdevice is struct usbduxsub */
1954	this_usbduxsub = this_comedidev->private;
1955
1956	s = this_comedidev->subdevices + SUBDEV_DA;
1957
1958	switch (urb->status) {
1959	case 0:
1960		/* success */
1961		break;
1962
1963	case -ECONNRESET:
1964	case -ENOENT:
1965	case -ESHUTDOWN:
1966	case -ECONNABORTED:
1967		/*
1968		 * after an unlink command, unplug, ... etc
1969		 * no unlink needed here. Already shutting down.
1970		 */
1971		if (this_usbduxsub->pwm_cmd_running)
1972			usbdux_pwm_stop(this_usbduxsub, 0);
1973
1974		return;
1975
1976	default:
1977		/* a real error */
1978		if (this_usbduxsub->pwm_cmd_running) {
1979			dev_err(&this_usbduxsub->interface->dev,
1980				"comedi_: Non-zero urb status received in "
1981				"pwm intr context: %d\n", urb->status);
1982			usbdux_pwm_stop(this_usbduxsub, 0);
1983		}
1984		return;
1985	}
1986
1987	/* are we actually running? */
1988	if (!(this_usbduxsub->pwm_cmd_running))
1989		return;
1990
1991	urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
1992	urb->dev = this_usbduxsub->usbdev;
1993	urb->status = 0;
1994	if (this_usbduxsub->pwm_cmd_running) {
1995		ret = usb_submit_urb(urb, GFP_ATOMIC);
1996		if (ret < 0) {
1997			dev_err(&this_usbduxsub->interface->dev,
1998				"comedi_: pwm urb resubm failed in int-cont. "
1999				"ret=%d", ret);
2000			if (ret == EL2NSYNC)
2001				dev_err(&this_usbduxsub->interface->dev,
2002					"buggy USB host controller or bug in "
2003					"IRQ handling!\n");
2004
2005			/* don't do an unlink here */
2006			usbdux_pwm_stop(this_usbduxsub, 0);
2007		}
2008	}
2009}
2010
2011static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
2012{
2013	int errFlag;
2014
2015	if (!usbduxsub)
2016		return -EFAULT;
2017
2018	dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
2019
2020	/* in case of a resubmission after an unlink... */
2021	usb_fill_bulk_urb(usbduxsub->urbPwm,
2022			  usbduxsub->usbdev,
2023			  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
2024			  usbduxsub->urbPwm->transfer_buffer,
2025			  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
2026			  usbduxsub->comedidev);
2027
2028	errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
2029	if (errFlag) {
2030		dev_err(&usbduxsub->interface->dev,
2031			"comedi_: usbdux: pwm: usb_submit_urb error %d\n",
2032			errFlag);
2033		return errFlag;
2034	}
2035	return 0;
2036}
2037
2038static int usbdux_pwm_period(struct comedi_device *dev,
2039			     struct comedi_subdevice *s, unsigned int period)
2040{
2041	struct usbduxsub *this_usbduxsub = dev->private;
2042	int fx2delay = 255;
2043
2044	if (period < MIN_PWM_PERIOD) {
2045		dev_err(&this_usbduxsub->interface->dev,
2046			"comedi%d: illegal period setting for pwm.\n",
2047			dev->minor);
2048		return -EAGAIN;
2049	} else {
2050		fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
2051		if (fx2delay > 255) {
2052			dev_err(&this_usbduxsub->interface->dev,
2053				"comedi%d: period %d for pwm is too low.\n",
2054				dev->minor, period);
2055			return -EAGAIN;
2056		}
2057	}
2058	this_usbduxsub->pwmDelay = fx2delay;
2059	this_usbduxsub->pwmPeriod = period;
2060	dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
2061		__func__, period, fx2delay);
2062	return 0;
2063}
2064
2065/* is called from insn so there's no need to do all the sanity checks */
2066static int usbdux_pwm_start(struct comedi_device *dev,
2067			    struct comedi_subdevice *s)
2068{
2069	int ret, i;
2070	struct usbduxsub *this_usbduxsub = dev->private;
2071
2072	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
2073		dev->minor, __func__);
2074
2075	if (this_usbduxsub->pwm_cmd_running) {
2076		/* already running */
2077		return 0;
2078	}
2079
2080	this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay);
2081	ret = send_dux_commands(this_usbduxsub, SENDPWMON);
2082	if (ret < 0)
2083		return ret;
2084
2085	/* initialise the buffer */
2086	for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
2087		((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
2088
2089	this_usbduxsub->pwm_cmd_running = 1;
2090	ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2091	if (ret < 0) {
2092		this_usbduxsub->pwm_cmd_running = 0;
2093		return ret;
2094	}
2095	return 0;
2096}
2097
2098/* generates the bit pattern for PWM with the optional sign bit */
2099static int usbdux_pwm_pattern(struct comedi_device *dev,
2100			      struct comedi_subdevice *s, int channel,
2101			      unsigned int value, unsigned int sign)
2102{
2103	struct usbduxsub *this_usbduxsub = dev->private;
2104	int i, szbuf;
2105	char *pBuf;
2106	char pwm_mask;
2107	char sgn_mask;
2108	char c;
2109
2110	if (!this_usbduxsub)
2111		return -EFAULT;
2112
2113	/* this is the DIO bit which carries the PWM data */
2114	pwm_mask = (1 << channel);
2115	/* this is the DIO bit which carries the optional direction bit */
2116	sgn_mask = (16 << channel);
2117	/* this is the buffer which will be filled with the with bit */
2118	/* pattern for one period */
2119	szbuf = this_usbduxsub->sizePwmBuf;
2120	pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
2121	for (i = 0; i < szbuf; i++) {
2122		c = *pBuf;
2123		/* reset bits */
2124		c = c & (~pwm_mask);
2125		/* set the bit as long as the index is lower than the value */
2126		if (i < value)
2127			c = c | pwm_mask;
2128		/* set the optional sign bit for a relay */
2129		if (!sign) {
2130			/* positive value */
2131			c = c & (~sgn_mask);
2132		} else {
2133			/* negative value */
2134			c = c | sgn_mask;
2135		}
2136		*(pBuf++) = c;
2137	}
2138	return 1;
2139}
2140
2141static int usbdux_pwm_write(struct comedi_device *dev,
2142			    struct comedi_subdevice *s,
2143			    struct comedi_insn *insn, unsigned int *data)
2144{
2145	struct usbduxsub *this_usbduxsub = dev->private;
2146
2147	if (!this_usbduxsub)
2148		return -EFAULT;
2149
2150	if ((insn->n) != 1) {
2151		/*
2152		 * doesn't make sense to have more than one value here because
2153		 * it would just overwrite the PWM buffer a couple of times
2154		 */
2155		return -EINVAL;
2156	}
2157
2158	/*
2159	 * the sign is set via a special INSN only, this gives us 8 bits for
2160	 * normal operation
2161	 * relay sign 0 by default
2162	 */
2163	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2164}
2165
2166static int usbdux_pwm_read(struct comedi_device *x1,
2167			   struct comedi_subdevice *x2, struct comedi_insn *x3,
2168			   unsigned int *x4)
2169{
2170	/* not needed */
2171	return -EINVAL;
2172};
2173
2174/* switches on/off PWM */
2175static int usbdux_pwm_config(struct comedi_device *dev,
2176			     struct comedi_subdevice *s,
2177			     struct comedi_insn *insn, unsigned int *data)
2178{
2179	struct usbduxsub *this_usbduxsub = dev->private;
2180	switch (data[0]) {
2181	case INSN_CONFIG_ARM:
2182		/* switch it on */
2183		dev_dbg(&this_usbduxsub->interface->dev,
2184			"comedi%d: %s: pwm on\n", dev->minor, __func__);
2185		/*
2186		 * if not zero the PWM is limited to a certain time which is
2187		 * not supported here
2188		 */
2189		if (data[1] != 0)
2190			return -EINVAL;
2191		return usbdux_pwm_start(dev, s);
2192	case INSN_CONFIG_DISARM:
2193		dev_dbg(&this_usbduxsub->interface->dev,
2194			"comedi%d: %s: pwm off\n", dev->minor, __func__);
2195		return usbdux_pwm_cancel(dev, s);
2196	case INSN_CONFIG_GET_PWM_STATUS:
2197		/*
2198		 * to check if the USB transmission has failed or in case PWM
2199		 * was limited to n cycles to check if it has terminated
2200		 */
2201		data[1] = this_usbduxsub->pwm_cmd_running;
2202		return 0;
2203	case INSN_CONFIG_PWM_SET_PERIOD:
2204		dev_dbg(&this_usbduxsub->interface->dev,
2205			"comedi%d: %s: setting period\n", dev->minor, __func__);
2206		return usbdux_pwm_period(dev, s, data[1]);
2207	case INSN_CONFIG_PWM_GET_PERIOD:
2208		data[1] = this_usbduxsub->pwmPeriod;
2209		return 0;
2210	case INSN_CONFIG_PWM_SET_H_BRIDGE:
2211		/* value in the first byte and the sign in the second for a
2212		   relay */
2213		return usbdux_pwm_pattern(dev, s,
2214					  /* the channel number */
2215					  CR_CHAN(insn->chanspec),
2216					  /* actual PWM data */
2217					  data[1],
2218					  /* just a sign */
2219					  (data[2] != 0));
2220	case INSN_CONFIG_PWM_GET_H_BRIDGE:
2221		/* values are not kept in this driver, nothing to return here */
2222		return -EINVAL;
2223	}
2224	return -EINVAL;
2225}
2226
2227/* end of PWM */
2228/*****************************************************************/
2229
2230static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2231{
2232	int i;
2233
2234	if (!usbduxsub_tmp)
2235		return;
2236	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2237
2238	/* shows the usb subsystem that the driver is down */
2239	if (usbduxsub_tmp->interface)
2240		usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2241
2242	usbduxsub_tmp->probed = 0;
2243
2244	if (usbduxsub_tmp->urbIn) {
2245		if (usbduxsub_tmp->ai_cmd_running) {
2246			usbduxsub_tmp->ai_cmd_running = 0;
2247			usbduxsub_unlink_InURBs(usbduxsub_tmp);
2248		}
2249		for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
2250			kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
2251			usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
2252			usb_kill_urb(usbduxsub_tmp->urbIn[i]);
2253			usb_free_urb(usbduxsub_tmp->urbIn[i]);
2254			usbduxsub_tmp->urbIn[i] = NULL;
2255		}
2256		kfree(usbduxsub_tmp->urbIn);
2257		usbduxsub_tmp->urbIn = NULL;
2258	}
2259	if (usbduxsub_tmp->urbOut) {
2260		if (usbduxsub_tmp->ao_cmd_running) {
2261			usbduxsub_tmp->ao_cmd_running = 0;
2262			usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2263		}
2264		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
2265			kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer);
2266			usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL;
2267			if (usbduxsub_tmp->urbOut[i]) {
2268				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
2269				usb_free_urb(usbduxsub_tmp->urbOut[i]);
2270				usbduxsub_tmp->urbOut[i] = NULL;
2271			}
2272		}
2273		kfree(usbduxsub_tmp->urbOut);
2274		usbduxsub_tmp->urbOut = NULL;
2275	}
2276	if (usbduxsub_tmp->urbPwm) {
2277		if (usbduxsub_tmp->pwm_cmd_running) {
2278			usbduxsub_tmp->pwm_cmd_running = 0;
2279			usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2280		}
2281		kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
2282		usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
2283		usb_kill_urb(usbduxsub_tmp->urbPwm);
2284		usb_free_urb(usbduxsub_tmp->urbPwm);
2285		usbduxsub_tmp->urbPwm = NULL;
2286	}
2287	kfree(usbduxsub_tmp->inBuffer);
2288	usbduxsub_tmp->inBuffer = NULL;
2289	kfree(usbduxsub_tmp->insnBuffer);
2290	usbduxsub_tmp->insnBuffer = NULL;
2291	kfree(usbduxsub_tmp->outBuffer);
2292	usbduxsub_tmp->outBuffer = NULL;
2293	kfree(usbduxsub_tmp->dac_commands);
2294	usbduxsub_tmp->dac_commands = NULL;
2295	kfree(usbduxsub_tmp->dux_commands);
2296	usbduxsub_tmp->dux_commands = NULL;
2297	usbduxsub_tmp->ai_cmd_running = 0;
2298	usbduxsub_tmp->ao_cmd_running = 0;
2299	usbduxsub_tmp->pwm_cmd_running = 0;
2300}
2301
2302static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2303						     void *context)
2304{
2305	struct usbduxsub *usbduxsub_tmp = context;
2306	struct usb_device *usbdev = usbduxsub_tmp->usbdev;
2307	int ret;
2308
2309	if (fw == NULL) {
2310		dev_err(&usbdev->dev,
2311			"Firmware complete handler without firmware!\n");
2312		return;
2313	}
2314
2315	/*
2316	 * we need to upload the firmware here because fw will be
2317	 * freed once we've left this function
2318	 */
2319	ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
2320
2321	if (ret) {
2322		dev_err(&usbdev->dev,
2323			"Could not upload firmware (err=%d)\n", ret);
2324		goto out;
2325	}
2326	comedi_usb_auto_config(usbdev, BOARDNAME);
2327 out:
2328	release_firmware(fw);
2329}
2330
2331/* allocate memory for the urbs and initialise them */
2332static int usbduxsub_probe(struct usb_interface *uinterf,
2333			   const struct usb_device_id *id)
2334{
2335	struct usb_device *udev = interface_to_usbdev(uinterf);
2336	struct device *dev = &uinterf->dev;
2337	int i;
2338	int index;
2339	int ret;
2340
2341	dev_dbg(dev, "comedi_: usbdux_: "
2342		"finding a free structure for the usb-device\n");
2343
2344	down(&start_stop_sem);
2345	/* look for a free place in the usbdux array */
2346	index = -1;
2347	for (i = 0; i < NUMUSBDUX; i++) {
2348		if (!(usbduxsub[i].probed)) {
2349			index = i;
2350			break;
2351		}
2352	}
2353
2354	/* no more space */
2355	if (index == -1) {
2356		dev_err(dev, "Too many usbdux-devices connected.\n");
2357		up(&start_stop_sem);
2358		return -EMFILE;
2359	}
2360	dev_dbg(dev, "comedi_: usbdux: "
2361		"usbduxsub[%d] is ready to connect to comedi.\n", index);
2362
2363	sema_init(&(usbduxsub[index].sem), 1);
2364	/* save a pointer to the usb device */
2365	usbduxsub[index].usbdev = udev;
2366
2367	/* 2.6: save the interface itself */
2368	usbduxsub[index].interface = uinterf;
2369	/* get the interface number from the interface */
2370	usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2371	/* hand the private data over to the usb subsystem */
2372	/* will be needed for disconnect */
2373	usb_set_intfdata(uinterf, &(usbduxsub[index]));
2374
2375	dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2376
2377	/* test if it is high speed (USB 2.0) */
2378	usbduxsub[index].high_speed =
2379	    (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2380
2381	/* create space for the commands of the DA converter */
2382	usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2383	if (!usbduxsub[index].dac_commands) {
2384		dev_err(dev, "comedi_: usbdux: "
2385			"error alloc space for dac commands\n");
2386		tidy_up(&(usbduxsub[index]));
2387		up(&start_stop_sem);
2388		return -ENOMEM;
2389	}
2390	/* create space for the commands going to the usb device */
2391	usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2392	if (!usbduxsub[index].dux_commands) {
2393		dev_err(dev, "comedi_: usbdux: "
2394			"error alloc space for dux commands\n");
2395		tidy_up(&(usbduxsub[index]));
2396		up(&start_stop_sem);
2397		return -ENOMEM;
2398	}
2399	/* create space for the in buffer and set it to zero */
2400	usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2401	if (!(usbduxsub[index].inBuffer)) {
2402		dev_err(dev, "comedi_: usbdux: "
2403			"could not alloc space for inBuffer\n");
2404		tidy_up(&(usbduxsub[index]));
2405		up(&start_stop_sem);
2406		return -ENOMEM;
2407	}
2408	/* create space of the instruction buffer */
2409	usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2410	if (!(usbduxsub[index].insnBuffer)) {
2411		dev_err(dev, "comedi_: usbdux: "
2412			"could not alloc space for insnBuffer\n");
2413		tidy_up(&(usbduxsub[index]));
2414		up(&start_stop_sem);
2415		return -ENOMEM;
2416	}
2417	/* create space for the outbuffer */
2418	usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2419	if (!(usbduxsub[index].outBuffer)) {
2420		dev_err(dev, "comedi_: usbdux: "
2421			"could not alloc space for outBuffer\n");
2422		tidy_up(&(usbduxsub[index]));
2423		up(&start_stop_sem);
2424		return -ENOMEM;
2425	}
2426	/* setting to alternate setting 3: enabling iso ep and bulk ep. */
2427	i = usb_set_interface(usbduxsub[index].usbdev,
2428			      usbduxsub[index].ifnum, 3);
2429	if (i < 0) {
2430		dev_err(dev, "comedi_: usbdux%d: "
2431			"could not set alternate setting 3 in high speed.\n",
2432			index);
2433		tidy_up(&(usbduxsub[index]));
2434		up(&start_stop_sem);
2435		return -ENODEV;
2436	}
2437	if (usbduxsub[index].high_speed)
2438		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
2439	else
2440		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
2441
2442	usbduxsub[index].urbIn =
2443	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
2444		    GFP_KERNEL);
2445	if (!(usbduxsub[index].urbIn)) {
2446		dev_err(dev, "comedi_: usbdux: Could not alloc. urbIn array\n");
2447		tidy_up(&(usbduxsub[index]));
2448		up(&start_stop_sem);
2449		return -ENOMEM;
2450	}
2451	for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
2452		/* one frame: 1ms */
2453		usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
2454		if (usbduxsub[index].urbIn[i] == NULL) {
2455			dev_err(dev, "comedi_: usbdux%d: "
2456				"Could not alloc. urb(%d)\n", index, i);
2457			tidy_up(&(usbduxsub[index]));
2458			up(&start_stop_sem);
2459			return -ENOMEM;
2460		}
2461		usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
2462		/* will be filled later with a pointer to the comedi-device */
2463		/* and ONLY then the urb should be submitted */
2464		usbduxsub[index].urbIn[i]->context = NULL;
2465		usbduxsub[index].urbIn[i]->pipe =
2466		    usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2467		usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
2468		usbduxsub[index].urbIn[i]->transfer_buffer =
2469		    kzalloc(SIZEINBUF, GFP_KERNEL);
2470		if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
2471			dev_err(dev, "comedi_: usbdux%d: "
2472				"could not alloc. transb.\n", index);
2473			tidy_up(&(usbduxsub[index]));
2474			up(&start_stop_sem);
2475			return -ENOMEM;
2476		}
2477		usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
2478		usbduxsub[index].urbIn[i]->number_of_packets = 1;
2479		usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
2480		usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
2481		usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF;
2482	}
2483
2484	/* out */
2485	if (usbduxsub[index].high_speed)
2486		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
2487	else
2488		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
2489
2490	usbduxsub[index].urbOut =
2491	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
2492		    GFP_KERNEL);
2493	if (!(usbduxsub[index].urbOut)) {
2494		dev_err(dev, "comedi_: usbdux: "
2495			"Could not alloc. urbOut array\n");
2496		tidy_up(&(usbduxsub[index]));
2497		up(&start_stop_sem);
2498		return -ENOMEM;
2499	}
2500	for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
2501		/* one frame: 1ms */
2502		usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
2503		if (usbduxsub[index].urbOut[i] == NULL) {
2504			dev_err(dev, "comedi_: usbdux%d: "
2505				"Could not alloc. urb(%d)\n", index, i);
2506			tidy_up(&(usbduxsub[index]));
2507			up(&start_stop_sem);
2508			return -ENOMEM;
2509		}
2510		usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
2511		/* will be filled later with a pointer to the comedi-device */
2512		/* and ONLY then the urb should be submitted */
2513		usbduxsub[index].urbOut[i]->context = NULL;
2514		usbduxsub[index].urbOut[i]->pipe =
2515		    usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2516		usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
2517		usbduxsub[index].urbOut[i]->transfer_buffer =
2518		    kzalloc(SIZEOUTBUF, GFP_KERNEL);
2519		if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
2520			dev_err(dev, "comedi_: usbdux%d: "
2521				"could not alloc. transb.\n", index);
2522			tidy_up(&(usbduxsub[index]));
2523			up(&start_stop_sem);
2524			return -ENOMEM;
2525		}
2526		usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
2527		usbduxsub[index].urbOut[i]->number_of_packets = 1;
2528		usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
2529		usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
2530		usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
2531		    SIZEOUTBUF;
2532		if (usbduxsub[index].high_speed) {
2533			/* uframes */
2534			usbduxsub[index].urbOut[i]->interval = 8;
2535		} else {
2536			/* frames */
2537			usbduxsub[index].urbOut[i]->interval = 1;
2538		}
2539	}
2540
2541	/* pwm */
2542	if (usbduxsub[index].high_speed) {
2543		/* max bulk ep size in high speed */
2544		usbduxsub[index].sizePwmBuf = 512;
2545		usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
2546		if (usbduxsub[index].urbPwm == NULL) {
2547			dev_err(dev, "comedi_: usbdux%d: "
2548				"Could not alloc. pwm urb\n", index);
2549			tidy_up(&(usbduxsub[index]));
2550			up(&start_stop_sem);
2551			return -ENOMEM;
2552		}
2553		usbduxsub[index].urbPwm->transfer_buffer =
2554		    kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
2555		if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2556			dev_err(dev, "comedi_: usbdux%d: "
2557				"could not alloc. transb. for pwm\n", index);
2558			tidy_up(&(usbduxsub[index]));
2559			up(&start_stop_sem);
2560			return -ENOMEM;
2561		}
2562	} else {
2563		usbduxsub[index].urbPwm = NULL;
2564		usbduxsub[index].sizePwmBuf = 0;
2565	}
2566
2567	usbduxsub[index].ai_cmd_running = 0;
2568	usbduxsub[index].ao_cmd_running = 0;
2569	usbduxsub[index].pwm_cmd_running = 0;
2570
2571	/* we've reached the bottom of the function */
2572	usbduxsub[index].probed = 1;
2573	up(&start_stop_sem);
2574
2575	ret = request_firmware_nowait(THIS_MODULE,
2576				      FW_ACTION_HOTPLUG,
2577				      "usbdux_firmware.bin",
2578				      &udev->dev,
2579				      GFP_KERNEL,
2580				      usbduxsub + index,
2581				      usbdux_firmware_request_complete_handler);
2582
2583	if (ret) {
2584		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2585		return ret;
2586	}
2587
2588	dev_info(dev, "comedi_: usbdux%d "
2589		 "has been successfully initialised.\n", index);
2590	/* success */
2591	return 0;
2592}
2593
2594static void usbduxsub_disconnect(struct usb_interface *intf)
2595{
2596	struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2597	struct usb_device *udev = interface_to_usbdev(intf);
2598
2599	if (!usbduxsub_tmp) {
2600		dev_err(&intf->dev,
2601			"comedi_: disconnect called with null pointer.\n");
2602		return;
2603	}
2604	if (usbduxsub_tmp->usbdev != udev) {
2605		dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
2606		return;
2607	}
2608	comedi_usb_auto_unconfig(udev);
2609	down(&start_stop_sem);
2610	down(&usbduxsub_tmp->sem);
2611	tidy_up(usbduxsub_tmp);
2612	up(&usbduxsub_tmp->sem);
2613	up(&start_stop_sem);
2614	dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n");
2615}
2616
2617/* is called when comedi-config is called */
2618static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2619{
2620	int ret;
2621	int index;
2622	int i;
2623	struct usbduxsub *udev;
2624
2625	struct comedi_subdevice *s = NULL;
2626	dev->private = NULL;
2627
2628	down(&start_stop_sem);
2629	/* find a valid device which has been detected by the probe function of
2630	 * the usb */
2631	index = -1;
2632	for (i = 0; i < NUMUSBDUX; i++) {
2633		if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
2634			index = i;
2635			break;
2636		}
2637	}
2638
2639	if (index < 0) {
2640		printk(KERN_ERR "comedi%d: usbdux: error: attach failed, no "
2641		       "usbdux devs connected to the usb bus.\n", dev->minor);
2642		up(&start_stop_sem);
2643		return -ENODEV;
2644	}
2645
2646	udev = &usbduxsub[index];
2647	down(&udev->sem);
2648	/* pointer back to the corresponding comedi device */
2649	udev->comedidev = dev;
2650
2651	/* trying to upload the firmware into the chip */
2652	if (comedi_aux_data(it->options, 0) &&
2653	    it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
2654		firmwareUpload(udev, comedi_aux_data(it->options, 0),
2655			       it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
2656	}
2657
2658	dev->board_name = BOARDNAME;
2659
2660	/* set number of subdevices */
2661	if (udev->high_speed) {
2662		/* with pwm */
2663		dev->n_subdevices = 5;
2664	} else {
2665		/* without pwm */
2666		dev->n_subdevices = 4;
2667	}
2668
2669	/* allocate space for the subdevices */
2670	ret = alloc_subdevices(dev, dev->n_subdevices);
2671	if (ret < 0) {
2672		dev_err(&udev->interface->dev,
2673			"comedi%d: error alloc space for subdev\n", dev->minor);
2674		up(&start_stop_sem);
2675		return ret;
2676	}
2677
2678	dev_info(&udev->interface->dev,
2679		 "comedi%d: usb-device %d is attached to comedi.\n",
2680		 dev->minor, index);
2681	/* private structure is also simply the usb-structure */
2682	dev->private = udev;
2683
2684	/* the first subdevice is the A/D converter */
2685	s = dev->subdevices + SUBDEV_AD;
2686	/* the URBs get the comedi subdevice */
2687	/* which is responsible for reading */
2688	/* this is the subdevice which reads data */
2689	dev->read_subdev = s;
2690	/* the subdevice receives as private structure the */
2691	/* usb-structure */
2692	s->private = NULL;
2693	/* analog input */
2694	s->type = COMEDI_SUBD_AI;
2695	/* readable and ref is to ground */
2696	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2697	/* 8 channels */
2698	s->n_chan = 8;
2699	/* length of the channellist */
2700	s->len_chanlist = 8;
2701	/* callback functions */
2702	s->insn_read = usbdux_ai_insn_read;
2703	s->do_cmdtest = usbdux_ai_cmdtest;
2704	s->do_cmd = usbdux_ai_cmd;
2705	s->cancel = usbdux_ai_cancel;
2706	/* max value from the A/D converter (12bit) */
2707	s->maxdata = 0xfff;
2708	/* range table to convert to physical units */
2709	s->range_table = (&range_usbdux_ai_range);
2710
2711	/* analog out */
2712	s = dev->subdevices + SUBDEV_DA;
2713	/* analog out */
2714	s->type = COMEDI_SUBD_AO;
2715	/* backward pointer */
2716	dev->write_subdev = s;
2717	/* the subdevice receives as private structure the */
2718	/* usb-structure */
2719	s->private = NULL;
2720	/* are writable */
2721	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2722	/* 4 channels */
2723	s->n_chan = 4;
2724	/* length of the channellist */
2725	s->len_chanlist = 4;
2726	/* 12 bit resolution */
2727	s->maxdata = 0x0fff;
2728	/* bipolar range */
2729	s->range_table = (&range_usbdux_ao_range);
2730	/* callback */
2731	s->do_cmdtest = usbdux_ao_cmdtest;
2732	s->do_cmd = usbdux_ao_cmd;
2733	s->cancel = usbdux_ao_cancel;
2734	s->insn_read = usbdux_ao_insn_read;
2735	s->insn_write = usbdux_ao_insn_write;
2736
2737	/* digital I/O */
2738	s = dev->subdevices + SUBDEV_DIO;
2739	s->type = COMEDI_SUBD_DIO;
2740	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2741	s->n_chan = 8;
2742	s->maxdata = 1;
2743	s->range_table = (&range_digital);
2744	s->insn_bits = usbdux_dio_insn_bits;
2745	s->insn_config = usbdux_dio_insn_config;
2746	/* we don't use it */
2747	s->private = NULL;
2748
2749	/* counter */
2750	s = dev->subdevices + SUBDEV_COUNTER;
2751	s->type = COMEDI_SUBD_COUNTER;
2752	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2753	s->n_chan = 4;
2754	s->maxdata = 0xFFFF;
2755	s->insn_read = usbdux_counter_read;
2756	s->insn_write = usbdux_counter_write;
2757	s->insn_config = usbdux_counter_config;
2758
2759	if (udev->high_speed) {
2760		/* timer / pwm */
2761		s = dev->subdevices + SUBDEV_PWM;
2762		s->type = COMEDI_SUBD_PWM;
2763		s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2764		s->n_chan = 8;
2765		/* this defines the max duty cycle resolution */
2766		s->maxdata = udev->sizePwmBuf;
2767		s->insn_write = usbdux_pwm_write;
2768		s->insn_read = usbdux_pwm_read;
2769		s->insn_config = usbdux_pwm_config;
2770		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2771	}
2772	/* finally decide that it's attached */
2773	udev->attached = 1;
2774
2775	up(&udev->sem);
2776
2777	up(&start_stop_sem);
2778
2779	dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n",
2780		 dev->minor);
2781
2782	return 0;
2783}
2784
2785static int usbdux_detach(struct comedi_device *dev)
2786{
2787	struct usbduxsub *usbduxsub_tmp;
2788
2789	if (!dev) {
2790		printk(KERN_ERR
2791		       "comedi?: usbdux: detach without dev variable...\n");
2792		return -EFAULT;
2793	}
2794
2795	usbduxsub_tmp = dev->private;
2796	if (!usbduxsub_tmp) {
2797		printk(KERN_ERR
2798		       "comedi?: usbdux: detach without ptr to usbduxsub[]\n");
2799		return -EFAULT;
2800	}
2801
2802	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi%d: detach usb device\n",
2803		dev->minor);
2804
2805	down(&usbduxsub_tmp->sem);
2806	/* Don't allow detach to free the private structure */
2807	/* It's one entry of of usbduxsub[] */
2808	dev->private = NULL;
2809	usbduxsub_tmp->attached = 0;
2810	usbduxsub_tmp->comedidev = NULL;
2811	dev_dbg(&usbduxsub_tmp->interface->dev,
2812		"comedi%d: detach: successfully removed\n", dev->minor);
2813	up(&usbduxsub_tmp->sem);
2814	return 0;
2815}
2816
2817/* main driver struct */
2818static struct comedi_driver driver_usbdux = {
2819	.driver_name = "usbdux",
2820	.module = THIS_MODULE,
2821	.attach = usbdux_attach,
2822	.detach = usbdux_detach,
2823};
2824
2825/* Table with the USB-devices: just now only testing IDs */
2826static const struct usb_device_id usbduxsub_table[] = {
2827	{USB_DEVICE(0x13d8, 0x0001)},
2828	{USB_DEVICE(0x13d8, 0x0002)},
2829	{}			/* Terminating entry */
2830};
2831
2832MODULE_DEVICE_TABLE(usb, usbduxsub_table);
2833
2834/* The usbduxsub-driver */
2835static struct usb_driver usbduxsub_driver = {
2836	.name = BOARDNAME,
2837	.probe = usbduxsub_probe,
2838	.disconnect = usbduxsub_disconnect,
2839	.id_table = usbduxsub_table,
2840};
2841
2842/* Can't use the nice macro as I have also to initialise the USB */
2843/* subsystem: */
2844/* registering the usb-system _and_ the comedi-driver */
2845static int __init init_usbdux(void)
2846{
2847	printk(KERN_INFO KBUILD_MODNAME ": "
2848	       DRIVER_VERSION ":" DRIVER_DESC "\n");
2849	usb_register(&usbduxsub_driver);
2850	comedi_driver_register(&driver_usbdux);
2851	return 0;
2852}
2853
2854/* deregistering the comedi driver and the usb-subsystem */
2855static void __exit exit_usbdux(void)
2856{
2857	comedi_driver_unregister(&driver_usbdux);
2858	usb_deregister(&usbduxsub_driver);
2859}
2860
2861module_init(init_usbdux);
2862module_exit(exit_usbdux);
2863
2864MODULE_AUTHOR(DRIVER_AUTHOR);
2865MODULE_DESCRIPTION(DRIVER_DESC);
2866MODULE_LICENSE("GPL");
2867