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