usbdux.c revision 85678d5d27cb0ea1005316f51b1b062bf4609b66
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		up(&this_usbduxsub->sem);
1469		return -EINVAL;
1470	}
1471	if (!(this_usbduxsub->ao_cmd_running)) {
1472		this_usbduxsub->ao_cmd_running = 1;
1473		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1474		if (ret < 0) {
1475			dev_err(&this_usbduxsub->interface->dev,
1476				"comedi%d: usbdux_ao_inttrig: submitURB: "
1477				"err=%d\n", dev->minor, ret);
1478			this_usbduxsub->ao_cmd_running = 0;
1479			up(&this_usbduxsub->sem);
1480			return ret;
1481		}
1482		s->async->inttrig = NULL;
1483	} else {
1484		dev_err(&this_usbduxsub->interface->dev,
1485			"comedi%d: ao_inttrig but acqu is already running.\n",
1486			dev->minor);
1487	}
1488	up(&this_usbduxsub->sem);
1489	return 1;
1490}
1491
1492static int usbdux_ao_cmdtest(struct comedi_device *dev,
1493			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
1494{
1495	int err = 0, tmp;
1496	struct usbduxsub *this_usbduxsub = dev->private;
1497
1498	if (!this_usbduxsub)
1499		return -EFAULT;
1500
1501	if (!(this_usbduxsub->probed))
1502		return -ENODEV;
1503
1504	dev_dbg(&this_usbduxsub->interface->dev,
1505		"comedi%d: usbdux_ao_cmdtest\n", dev->minor);
1506
1507	/* make sure triggers are valid */
1508	/* Only immediate triggers are allowed */
1509	tmp = cmd->start_src;
1510	cmd->start_src &= TRIG_NOW | TRIG_INT;
1511	if (!cmd->start_src || tmp != cmd->start_src)
1512		err++;
1513
1514	/* trigger should happen timed */
1515	tmp = cmd->scan_begin_src;
1516	/* just now we scan also in the high speed mode every frame */
1517	/* this is due to ehci driver limitations */
1518	if (0) {		/* (this_usbduxsub->high_speed) */
1519		/* start immediately a new scan */
1520		/* the sampling rate is set by the coversion rate */
1521		cmd->scan_begin_src &= TRIG_FOLLOW;
1522	} else {
1523		/* start a new scan (output at once) with a timer */
1524		cmd->scan_begin_src &= TRIG_TIMER;
1525	}
1526	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1527		err++;
1528
1529	/* scanning is continuous */
1530	tmp = cmd->convert_src;
1531	/* we always output at 1kHz just now all channels at once */
1532	if (0) {		/* (this_usbduxsub->high_speed) */
1533		/*
1534		 * in usb-2.0 only one conversion it transmitted but with 8kHz/n
1535		 */
1536		cmd->convert_src &= TRIG_TIMER;
1537	} else {
1538		/* all conversion events happen simultaneously with a rate of
1539		 * 1kHz/n */
1540		cmd->convert_src &= TRIG_NOW;
1541	}
1542	if (!cmd->convert_src || tmp != cmd->convert_src)
1543		err++;
1544
1545	/* issue a trigger when scan is finished and start a new scan */
1546	tmp = cmd->scan_end_src;
1547	cmd->scan_end_src &= TRIG_COUNT;
1548	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1549		err++;
1550
1551	/* trigger at the end of count events or not, stop condition or not */
1552	tmp = cmd->stop_src;
1553	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1554	if (!cmd->stop_src || tmp != cmd->stop_src)
1555		err++;
1556
1557	if (err)
1558		return 1;
1559
1560	/*
1561	 * step 2: make sure trigger sources are unique and mutually compatible
1562	 * note that mutual compatibility is not an issue here
1563	 */
1564	if (cmd->scan_begin_src != TRIG_FOLLOW &&
1565	    cmd->scan_begin_src != TRIG_EXT &&
1566	    cmd->scan_begin_src != TRIG_TIMER)
1567		err++;
1568	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1569		err++;
1570
1571	if (err)
1572		return 2;
1573
1574	/* step 3: make sure arguments are trivially compatible */
1575
1576	if (cmd->start_arg != 0) {
1577		cmd->start_arg = 0;
1578		err++;
1579	}
1580
1581	if (cmd->scan_begin_src == TRIG_FOLLOW) {
1582		/* internal trigger */
1583		if (cmd->scan_begin_arg != 0) {
1584			cmd->scan_begin_arg = 0;
1585			err++;
1586		}
1587	}
1588
1589	if (cmd->scan_begin_src == TRIG_TIMER) {
1590		/* timer */
1591		if (cmd->scan_begin_arg < 1000000) {
1592			cmd->scan_begin_arg = 1000000;
1593			err++;
1594		}
1595	}
1596	/* not used now, is for later use */
1597	if (cmd->convert_src == TRIG_TIMER) {
1598		if (cmd->convert_arg < 125000) {
1599			cmd->convert_arg = 125000;
1600			err++;
1601		}
1602	}
1603
1604	/* the same argument */
1605	if (cmd->scan_end_arg != cmd->chanlist_len) {
1606		cmd->scan_end_arg = cmd->chanlist_len;
1607		err++;
1608	}
1609
1610	if (cmd->stop_src == TRIG_COUNT) {
1611		/* any count is allowed */
1612	} else {
1613		/* TRIG_NONE */
1614		if (cmd->stop_arg != 0) {
1615			cmd->stop_arg = 0;
1616			err++;
1617		}
1618	}
1619
1620	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, "
1621		"scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
1622		"convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src,
1623		cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg);
1624
1625	if (err)
1626		return 3;
1627
1628	return 0;
1629}
1630
1631static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1632{
1633	struct comedi_cmd *cmd = &s->async->cmd;
1634	unsigned int chan, gain;
1635	int i, ret;
1636	struct usbduxsub *this_usbduxsub = dev->private;
1637
1638	if (!this_usbduxsub)
1639		return -EFAULT;
1640
1641	down(&this_usbduxsub->sem);
1642	if (!(this_usbduxsub->probed)) {
1643		up(&this_usbduxsub->sem);
1644		return -ENODEV;
1645	}
1646	dev_dbg(&this_usbduxsub->interface->dev,
1647		"comedi%d: %s\n", dev->minor, __func__);
1648
1649	/* set current channel of the running acquisition to zero */
1650	s->async->cur_chan = 0;
1651	for (i = 0; i < cmd->chanlist_len; ++i) {
1652		chan = CR_CHAN(cmd->chanlist[i]);
1653		gain = CR_RANGE(cmd->chanlist[i]);
1654		if (i >= NUMOUTCHANNELS) {
1655			dev_err(&this_usbduxsub->interface->dev,
1656				"comedi%d: %s: channel list too long\n",
1657				dev->minor, __func__);
1658			break;
1659		}
1660		this_usbduxsub->dac_commands[i] = (chan << 6);
1661		dev_dbg(&this_usbduxsub->interface->dev,
1662			"comedi%d: dac command for ch %d is %x\n",
1663			dev->minor, i, this_usbduxsub->dac_commands[i]);
1664	}
1665
1666	/* we count in steps of 1ms (125us) */
1667	/* 125us mode not used yet */
1668	if (0) {		/* (this_usbduxsub->high_speed) */
1669		/* 125us */
1670		/* timing of the conversion itself: every 125 us */
1671		this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
1672	} else {
1673		/* 1ms */
1674		/* timing of the scan: we get all channels at once */
1675		this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
1676		dev_dbg(&this_usbduxsub->interface->dev,
1677			"comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1678			"convert_src=%d, convert_arg=%d\n", dev->minor,
1679			cmd->scan_begin_src, cmd->scan_begin_arg,
1680			cmd->convert_src, cmd->convert_arg);
1681		dev_dbg(&this_usbduxsub->interface->dev,
1682			"comedi%d: ao_timer=%d (ms)\n",
1683			dev->minor, this_usbduxsub->ao_timer);
1684		if (this_usbduxsub->ao_timer < 1) {
1685			dev_err(&this_usbduxsub->interface->dev,
1686				"comedi%d: usbdux: ao_timer=%d, "
1687				"scan_begin_arg=%d. "
1688				"Not properly tested by cmdtest?\n",
1689				dev->minor, this_usbduxsub->ao_timer,
1690				cmd->scan_begin_arg);
1691			up(&this_usbduxsub->sem);
1692			return -EINVAL;
1693		}
1694	}
1695	this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
1696
1697	if (cmd->stop_src == TRIG_COUNT) {
1698		/* not continuous */
1699		/* counter */
1700		/* high speed also scans everything at once */
1701		if (0) {	/* (this_usbduxsub->high_speed) */
1702			this_usbduxsub->ao_sample_count =
1703			    (cmd->stop_arg) * (cmd->scan_end_arg);
1704		} else {
1705			/* there's no scan as the scan has been */
1706			/* perf inside the FX2 */
1707			/* data arrives as one packet */
1708			this_usbduxsub->ao_sample_count = cmd->stop_arg;
1709		}
1710		this_usbduxsub->ao_continous = 0;
1711	} else {
1712		/* continous acquisition */
1713		this_usbduxsub->ao_continous = 1;
1714		this_usbduxsub->ao_sample_count = 0;
1715	}
1716
1717	if (cmd->start_src == TRIG_NOW) {
1718		/* enable this acquisition operation */
1719		this_usbduxsub->ao_cmd_running = 1;
1720		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1721		if (ret < 0) {
1722			this_usbduxsub->ao_cmd_running = 0;
1723			/* fixme: unlink here?? */
1724			up(&this_usbduxsub->sem);
1725			return ret;
1726		}
1727		s->async->inttrig = NULL;
1728	} else {
1729		/* TRIG_INT */
1730		/* submit the urbs later */
1731		/* wait for an internal signal */
1732		s->async->inttrig = usbdux_ao_inttrig;
1733	}
1734
1735	up(&this_usbduxsub->sem);
1736	return 0;
1737}
1738
1739static int usbdux_dio_insn_config(struct comedi_device *dev,
1740				  struct comedi_subdevice *s,
1741				  struct comedi_insn *insn, unsigned int *data)
1742{
1743	int chan = CR_CHAN(insn->chanspec);
1744
1745	/* The input or output configuration of each digital line is
1746	 * configured by a special insn_config instruction.  chanspec
1747	 * contains the channel to be changed, and data[0] contains the
1748	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1749
1750	switch (data[0]) {
1751	case INSN_CONFIG_DIO_OUTPUT:
1752		s->io_bits |= 1 << chan;	/* 1 means Out */
1753		break;
1754	case INSN_CONFIG_DIO_INPUT:
1755		s->io_bits &= ~(1 << chan);
1756		break;
1757	case INSN_CONFIG_DIO_QUERY:
1758		data[1] =
1759		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1760		break;
1761	default:
1762		return -EINVAL;
1763		break;
1764	}
1765	/* we don't tell the firmware here as it would take 8 frames */
1766	/* to submit the information. We do it in the insn_bits. */
1767	return insn->n;
1768}
1769
1770static int usbdux_dio_insn_bits(struct comedi_device *dev,
1771				struct comedi_subdevice *s,
1772				struct comedi_insn *insn, unsigned int *data)
1773{
1774
1775	struct usbduxsub *this_usbduxsub = dev->private;
1776	int err;
1777
1778	if (!this_usbduxsub)
1779		return -EFAULT;
1780
1781	if (insn->n != 2)
1782		return -EINVAL;
1783
1784	down(&this_usbduxsub->sem);
1785
1786	if (!(this_usbduxsub->probed)) {
1787		up(&this_usbduxsub->sem);
1788		return -ENODEV;
1789	}
1790
1791	/* The insn data is a mask in data[0] and the new data
1792	 * in data[1], each channel cooresponding to a bit. */
1793	s->state &= ~data[0];
1794	s->state |= data[0] & data[1];
1795	this_usbduxsub->dux_commands[1] = s->io_bits;
1796	this_usbduxsub->dux_commands[2] = s->state;
1797
1798	/* This command also tells the firmware to return */
1799	/* the digital input lines */
1800	err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1801	if (err < 0) {
1802		up(&this_usbduxsub->sem);
1803		return err;
1804	}
1805	err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
1806	if (err < 0) {
1807		up(&this_usbduxsub->sem);
1808		return err;
1809	}
1810
1811	data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
1812	up(&this_usbduxsub->sem);
1813	return 2;
1814}
1815
1816/* reads the 4 counters, only two are used just now */
1817static int usbdux_counter_read(struct comedi_device *dev,
1818			       struct comedi_subdevice *s,
1819			       struct comedi_insn *insn, unsigned int *data)
1820{
1821	struct usbduxsub *this_usbduxsub = dev->private;
1822	int chan = insn->chanspec;
1823	int err;
1824
1825	if (!this_usbduxsub)
1826		return -EFAULT;
1827
1828	down(&this_usbduxsub->sem);
1829
1830	if (!(this_usbduxsub->probed)) {
1831		up(&this_usbduxsub->sem);
1832		return -ENODEV;
1833	}
1834
1835	err = send_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1836	if (err < 0) {
1837		up(&this_usbduxsub->sem);
1838		return err;
1839	}
1840
1841	err = receive_dux_commands(this_usbduxsub, READCOUNTERCOMMAND);
1842	if (err < 0) {
1843		up(&this_usbduxsub->sem);
1844		return err;
1845	}
1846
1847	data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]);
1848	up(&this_usbduxsub->sem);
1849	return 1;
1850}
1851
1852static int usbdux_counter_write(struct comedi_device *dev,
1853				struct comedi_subdevice *s,
1854				struct comedi_insn *insn, unsigned int *data)
1855{
1856	struct usbduxsub *this_usbduxsub = dev->private;
1857	int err;
1858
1859	if (!this_usbduxsub)
1860		return -EFAULT;
1861
1862	down(&this_usbduxsub->sem);
1863
1864	if (!(this_usbduxsub->probed)) {
1865		up(&this_usbduxsub->sem);
1866		return -ENODEV;
1867	}
1868
1869	this_usbduxsub->dux_commands[1] = insn->chanspec;
1870	*((int16_t *) (this_usbduxsub->dux_commands + 2)) = cpu_to_le16(*data);
1871
1872	err = send_dux_commands(this_usbduxsub, WRITECOUNTERCOMMAND);
1873	if (err < 0) {
1874		up(&this_usbduxsub->sem);
1875		return err;
1876	}
1877
1878	up(&this_usbduxsub->sem);
1879
1880	return 1;
1881}
1882
1883static int usbdux_counter_config(struct comedi_device *dev,
1884				 struct comedi_subdevice *s,
1885				 struct comedi_insn *insn, unsigned int *data)
1886{
1887	/* nothing to do so far */
1888	return 2;
1889}
1890
1891/***********************************/
1892/* PWM */
1893
1894static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
1895{
1896	int err = 0;
1897
1898	if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
1899		if (usbduxsub_tmp->urbPwm)
1900			usb_kill_urb(usbduxsub_tmp->urbPwm);
1901		dev_dbg(&usbduxsub_tmp->interface->dev,
1902			"comedi: unlinked PwmURB: res=%d\n", err);
1903	}
1904	return err;
1905}
1906
1907/* This cancels a running acquisition operation
1908 * in any context.
1909 */
1910static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
1911{
1912	int ret = 0;
1913
1914	if (!this_usbduxsub)
1915		return -EFAULT;
1916
1917	dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
1918	if (do_unlink)
1919		ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
1920
1921	this_usbduxsub->pwm_cmd_running = 0;
1922
1923	return ret;
1924}
1925
1926/* force unlink - is called by comedi */
1927static int usbdux_pwm_cancel(struct comedi_device *dev,
1928			     struct comedi_subdevice *s)
1929{
1930	struct usbduxsub *this_usbduxsub = dev->private;
1931	int res = 0;
1932
1933	/* unlink only if it is really running */
1934	res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
1935
1936	dev_dbg(&this_usbduxsub->interface->dev,
1937		"comedi %d: sending pwm off command to the usb device.\n",
1938		dev->minor);
1939
1940	return send_dux_commands(this_usbduxsub, SENDPWMOFF);
1941}
1942
1943static void usbduxsub_pwm_irq(struct urb *urb)
1944{
1945	int ret;
1946	struct usbduxsub *this_usbduxsub;
1947	struct comedi_device *this_comedidev;
1948	struct comedi_subdevice *s;
1949
1950	/* printk(KERN_DEBUG "PWM: IRQ\n"); */
1951
1952	/* the context variable points to the subdevice */
1953	this_comedidev = urb->context;
1954	/* the private structure of the subdevice is struct usbduxsub */
1955	this_usbduxsub = this_comedidev->private;
1956
1957	s = this_comedidev->subdevices + SUBDEV_DA;
1958
1959	switch (urb->status) {
1960	case 0:
1961		/* success */
1962		break;
1963
1964	case -ECONNRESET:
1965	case -ENOENT:
1966	case -ESHUTDOWN:
1967	case -ECONNABORTED:
1968		/*
1969		 * after an unlink command, unplug, ... etc
1970		 * no unlink needed here. Already shutting down.
1971		 */
1972		if (this_usbduxsub->pwm_cmd_running)
1973			usbdux_pwm_stop(this_usbduxsub, 0);
1974
1975		return;
1976
1977	default:
1978		/* a real error */
1979		if (this_usbduxsub->pwm_cmd_running) {
1980			dev_err(&this_usbduxsub->interface->dev,
1981				"comedi_: Non-zero urb status received in "
1982				"pwm intr context: %d\n", urb->status);
1983			usbdux_pwm_stop(this_usbduxsub, 0);
1984		}
1985		return;
1986	}
1987
1988	/* are we actually running? */
1989	if (!(this_usbduxsub->pwm_cmd_running))
1990		return;
1991
1992	urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
1993	urb->dev = this_usbduxsub->usbdev;
1994	urb->status = 0;
1995	if (this_usbduxsub->pwm_cmd_running) {
1996		ret = usb_submit_urb(urb, GFP_ATOMIC);
1997		if (ret < 0) {
1998			dev_err(&this_usbduxsub->interface->dev,
1999				"comedi_: pwm urb resubm failed in int-cont. "
2000				"ret=%d", ret);
2001			if (ret == EL2NSYNC)
2002				dev_err(&this_usbduxsub->interface->dev,
2003					"buggy USB host controller or bug in "
2004					"IRQ handling!\n");
2005
2006			/* don't do an unlink here */
2007			usbdux_pwm_stop(this_usbduxsub, 0);
2008		}
2009	}
2010}
2011
2012static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
2013{
2014	int errFlag;
2015
2016	if (!usbduxsub)
2017		return -EFAULT;
2018
2019	dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
2020
2021	/* in case of a resubmission after an unlink... */
2022	usb_fill_bulk_urb(usbduxsub->urbPwm,
2023			  usbduxsub->usbdev,
2024			  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
2025			  usbduxsub->urbPwm->transfer_buffer,
2026			  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
2027			  usbduxsub->comedidev);
2028
2029	errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
2030	if (errFlag) {
2031		dev_err(&usbduxsub->interface->dev,
2032			"comedi_: usbdux: pwm: usb_submit_urb error %d\n",
2033			errFlag);
2034		return errFlag;
2035	}
2036	return 0;
2037}
2038
2039static int usbdux_pwm_period(struct comedi_device *dev,
2040			     struct comedi_subdevice *s, unsigned int period)
2041{
2042	struct usbduxsub *this_usbduxsub = dev->private;
2043	int fx2delay = 255;
2044
2045	if (period < MIN_PWM_PERIOD) {
2046		dev_err(&this_usbduxsub->interface->dev,
2047			"comedi%d: illegal period setting for pwm.\n",
2048			dev->minor);
2049		return -EAGAIN;
2050	} else {
2051		fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
2052		if (fx2delay > 255) {
2053			dev_err(&this_usbduxsub->interface->dev,
2054				"comedi%d: period %d for pwm is too low.\n",
2055				dev->minor, period);
2056			return -EAGAIN;
2057		}
2058	}
2059	this_usbduxsub->pwmDelay = fx2delay;
2060	this_usbduxsub->pwmPeriod = period;
2061	dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
2062		__func__, period, fx2delay);
2063	return 0;
2064}
2065
2066/* is called from insn so there's no need to do all the sanity checks */
2067static int usbdux_pwm_start(struct comedi_device *dev,
2068			    struct comedi_subdevice *s)
2069{
2070	int ret, i;
2071	struct usbduxsub *this_usbduxsub = dev->private;
2072
2073	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
2074		dev->minor, __func__);
2075
2076	if (this_usbduxsub->pwm_cmd_running) {
2077		/* already running */
2078		return 0;
2079	}
2080
2081	this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay);
2082	ret = send_dux_commands(this_usbduxsub, SENDPWMON);
2083	if (ret < 0)
2084		return ret;
2085
2086	/* initialise the buffer */
2087	for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
2088		((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
2089
2090	this_usbduxsub->pwm_cmd_running = 1;
2091	ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2092	if (ret < 0) {
2093		this_usbduxsub->pwm_cmd_running = 0;
2094		return ret;
2095	}
2096	return 0;
2097}
2098
2099/* generates the bit pattern for PWM with the optional sign bit */
2100static int usbdux_pwm_pattern(struct comedi_device *dev,
2101			      struct comedi_subdevice *s, int channel,
2102			      unsigned int value, unsigned int sign)
2103{
2104	struct usbduxsub *this_usbduxsub = dev->private;
2105	int i, szbuf;
2106	char *pBuf;
2107	char pwm_mask;
2108	char sgn_mask;
2109	char c;
2110
2111	if (!this_usbduxsub)
2112		return -EFAULT;
2113
2114	/* this is the DIO bit which carries the PWM data */
2115	pwm_mask = (1 << channel);
2116	/* this is the DIO bit which carries the optional direction bit */
2117	sgn_mask = (16 << channel);
2118	/* this is the buffer which will be filled with the with bit */
2119	/* pattern for one period */
2120	szbuf = this_usbduxsub->sizePwmBuf;
2121	pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
2122	for (i = 0; i < szbuf; i++) {
2123		c = *pBuf;
2124		/* reset bits */
2125		c = c & (~pwm_mask);
2126		/* set the bit as long as the index is lower than the value */
2127		if (i < value)
2128			c = c | pwm_mask;
2129		/* set the optional sign bit for a relay */
2130		if (!sign) {
2131			/* positive value */
2132			c = c & (~sgn_mask);
2133		} else {
2134			/* negative value */
2135			c = c | sgn_mask;
2136		}
2137		*(pBuf++) = c;
2138	}
2139	return 1;
2140}
2141
2142static int usbdux_pwm_write(struct comedi_device *dev,
2143			    struct comedi_subdevice *s,
2144			    struct comedi_insn *insn, unsigned int *data)
2145{
2146	struct usbduxsub *this_usbduxsub = dev->private;
2147
2148	if (!this_usbduxsub)
2149		return -EFAULT;
2150
2151	if ((insn->n) != 1) {
2152		/*
2153		 * doesn't make sense to have more than one value here because
2154		 * it would just overwrite the PWM buffer a couple of times
2155		 */
2156		return -EINVAL;
2157	}
2158
2159	/*
2160	 * the sign is set via a special INSN only, this gives us 8 bits for
2161	 * normal operation
2162	 * relay sign 0 by default
2163	 */
2164	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
2165}
2166
2167static int usbdux_pwm_read(struct comedi_device *x1,
2168			   struct comedi_subdevice *x2, struct comedi_insn *x3,
2169			   unsigned int *x4)
2170{
2171	/* not needed */
2172	return -EINVAL;
2173};
2174
2175/* switches on/off PWM */
2176static int usbdux_pwm_config(struct comedi_device *dev,
2177			     struct comedi_subdevice *s,
2178			     struct comedi_insn *insn, unsigned int *data)
2179{
2180	struct usbduxsub *this_usbduxsub = dev->private;
2181	switch (data[0]) {
2182	case INSN_CONFIG_ARM:
2183		/* switch it on */
2184		dev_dbg(&this_usbduxsub->interface->dev,
2185			"comedi%d: %s: pwm on\n", dev->minor, __func__);
2186		/*
2187		 * if not zero the PWM is limited to a certain time which is
2188		 * not supported here
2189		 */
2190		if (data[1] != 0)
2191			return -EINVAL;
2192		return usbdux_pwm_start(dev, s);
2193	case INSN_CONFIG_DISARM:
2194		dev_dbg(&this_usbduxsub->interface->dev,
2195			"comedi%d: %s: pwm off\n", dev->minor, __func__);
2196		return usbdux_pwm_cancel(dev, s);
2197	case INSN_CONFIG_GET_PWM_STATUS:
2198		/*
2199		 * to check if the USB transmission has failed or in case PWM
2200		 * was limited to n cycles to check if it has terminated
2201		 */
2202		data[1] = this_usbduxsub->pwm_cmd_running;
2203		return 0;
2204	case INSN_CONFIG_PWM_SET_PERIOD:
2205		dev_dbg(&this_usbduxsub->interface->dev,
2206			"comedi%d: %s: setting period\n", dev->minor, __func__);
2207		return usbdux_pwm_period(dev, s, data[1]);
2208	case INSN_CONFIG_PWM_GET_PERIOD:
2209		data[1] = this_usbduxsub->pwmPeriod;
2210		return 0;
2211	case INSN_CONFIG_PWM_SET_H_BRIDGE:
2212		/* value in the first byte and the sign in the second for a
2213		   relay */
2214		return usbdux_pwm_pattern(dev, s,
2215					  /* the channel number */
2216					  CR_CHAN(insn->chanspec),
2217					  /* actual PWM data */
2218					  data[1],
2219					  /* just a sign */
2220					  (data[2] != 0));
2221	case INSN_CONFIG_PWM_GET_H_BRIDGE:
2222		/* values are not kept in this driver, nothing to return here */
2223		return -EINVAL;
2224	}
2225	return -EINVAL;
2226}
2227
2228/* end of PWM */
2229/*****************************************************************/
2230
2231static void tidy_up(struct usbduxsub *usbduxsub_tmp)
2232{
2233	int i;
2234
2235	if (!usbduxsub_tmp)
2236		return;
2237	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
2238
2239	/* shows the usb subsystem that the driver is down */
2240	if (usbduxsub_tmp->interface)
2241		usb_set_intfdata(usbduxsub_tmp->interface, NULL);
2242
2243	usbduxsub_tmp->probed = 0;
2244
2245	if (usbduxsub_tmp->urbIn) {
2246		if (usbduxsub_tmp->ai_cmd_running) {
2247			usbduxsub_tmp->ai_cmd_running = 0;
2248			usbduxsub_unlink_InURBs(usbduxsub_tmp);
2249		}
2250		for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
2251			kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
2252			usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
2253			usb_kill_urb(usbduxsub_tmp->urbIn[i]);
2254			usb_free_urb(usbduxsub_tmp->urbIn[i]);
2255			usbduxsub_tmp->urbIn[i] = NULL;
2256		}
2257		kfree(usbduxsub_tmp->urbIn);
2258		usbduxsub_tmp->urbIn = NULL;
2259	}
2260	if (usbduxsub_tmp->urbOut) {
2261		if (usbduxsub_tmp->ao_cmd_running) {
2262			usbduxsub_tmp->ao_cmd_running = 0;
2263			usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2264		}
2265		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
2266			kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer);
2267			usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL;
2268			if (usbduxsub_tmp->urbOut[i]) {
2269				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
2270				usb_free_urb(usbduxsub_tmp->urbOut[i]);
2271				usbduxsub_tmp->urbOut[i] = NULL;
2272			}
2273		}
2274		kfree(usbduxsub_tmp->urbOut);
2275		usbduxsub_tmp->urbOut = NULL;
2276	}
2277	if (usbduxsub_tmp->urbPwm) {
2278		if (usbduxsub_tmp->pwm_cmd_running) {
2279			usbduxsub_tmp->pwm_cmd_running = 0;
2280			usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2281		}
2282		kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
2283		usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
2284		usb_kill_urb(usbduxsub_tmp->urbPwm);
2285		usb_free_urb(usbduxsub_tmp->urbPwm);
2286		usbduxsub_tmp->urbPwm = NULL;
2287	}
2288	kfree(usbduxsub_tmp->inBuffer);
2289	usbduxsub_tmp->inBuffer = NULL;
2290	kfree(usbduxsub_tmp->insnBuffer);
2291	usbduxsub_tmp->insnBuffer = NULL;
2292	kfree(usbduxsub_tmp->outBuffer);
2293	usbduxsub_tmp->outBuffer = NULL;
2294	kfree(usbduxsub_tmp->dac_commands);
2295	usbduxsub_tmp->dac_commands = NULL;
2296	kfree(usbduxsub_tmp->dux_commands);
2297	usbduxsub_tmp->dux_commands = NULL;
2298	usbduxsub_tmp->ai_cmd_running = 0;
2299	usbduxsub_tmp->ao_cmd_running = 0;
2300	usbduxsub_tmp->pwm_cmd_running = 0;
2301}
2302
2303static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
2304						     void *context)
2305{
2306	struct usbduxsub *usbduxsub_tmp = context;
2307	struct usb_device *usbdev = usbduxsub_tmp->usbdev;
2308	int ret;
2309
2310	if (fw == NULL) {
2311		dev_err(&usbdev->dev,
2312			"Firmware complete handler without firmware!\n");
2313		return;
2314	}
2315
2316	/*
2317	 * we need to upload the firmware here because fw will be
2318	 * freed once we've left this function
2319	 */
2320	ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
2321
2322	if (ret) {
2323		dev_err(&usbdev->dev,
2324			"Could not upload firmware (err=%d)\n", ret);
2325		goto out;
2326	}
2327	comedi_usb_auto_config(usbdev, BOARDNAME);
2328 out:
2329	release_firmware(fw);
2330}
2331
2332/* allocate memory for the urbs and initialise them */
2333static int usbduxsub_probe(struct usb_interface *uinterf,
2334			   const struct usb_device_id *id)
2335{
2336	struct usb_device *udev = interface_to_usbdev(uinterf);
2337	struct device *dev = &uinterf->dev;
2338	int i;
2339	int index;
2340	int ret;
2341
2342	dev_dbg(dev, "comedi_: usbdux_: "
2343		"finding a free structure for the usb-device\n");
2344
2345	down(&start_stop_sem);
2346	/* look for a free place in the usbdux array */
2347	index = -1;
2348	for (i = 0; i < NUMUSBDUX; i++) {
2349		if (!(usbduxsub[i].probed)) {
2350			index = i;
2351			break;
2352		}
2353	}
2354
2355	/* no more space */
2356	if (index == -1) {
2357		dev_err(dev, "Too many usbdux-devices connected.\n");
2358		up(&start_stop_sem);
2359		return -EMFILE;
2360	}
2361	dev_dbg(dev, "comedi_: usbdux: "
2362		"usbduxsub[%d] is ready to connect to comedi.\n", index);
2363
2364	sema_init(&(usbduxsub[index].sem), 1);
2365	/* save a pointer to the usb device */
2366	usbduxsub[index].usbdev = udev;
2367
2368	/* 2.6: save the interface itself */
2369	usbduxsub[index].interface = uinterf;
2370	/* get the interface number from the interface */
2371	usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2372	/* hand the private data over to the usb subsystem */
2373	/* will be needed for disconnect */
2374	usb_set_intfdata(uinterf, &(usbduxsub[index]));
2375
2376	dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2377
2378	/* test if it is high speed (USB 2.0) */
2379	usbduxsub[index].high_speed =
2380	    (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
2381
2382	/* create space for the commands of the DA converter */
2383	usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
2384	if (!usbduxsub[index].dac_commands) {
2385		dev_err(dev, "comedi_: usbdux: "
2386			"error alloc space for dac commands\n");
2387		tidy_up(&(usbduxsub[index]));
2388		up(&start_stop_sem);
2389		return -ENOMEM;
2390	}
2391	/* create space for the commands going to the usb device */
2392	usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
2393	if (!usbduxsub[index].dux_commands) {
2394		dev_err(dev, "comedi_: usbdux: "
2395			"error alloc space for dux commands\n");
2396		tidy_up(&(usbduxsub[index]));
2397		up(&start_stop_sem);
2398		return -ENOMEM;
2399	}
2400	/* create space for the in buffer and set it to zero */
2401	usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
2402	if (!(usbduxsub[index].inBuffer)) {
2403		dev_err(dev, "comedi_: usbdux: "
2404			"could not alloc space for inBuffer\n");
2405		tidy_up(&(usbduxsub[index]));
2406		up(&start_stop_sem);
2407		return -ENOMEM;
2408	}
2409	/* create space of the instruction buffer */
2410	usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
2411	if (!(usbduxsub[index].insnBuffer)) {
2412		dev_err(dev, "comedi_: usbdux: "
2413			"could not alloc space for insnBuffer\n");
2414		tidy_up(&(usbduxsub[index]));
2415		up(&start_stop_sem);
2416		return -ENOMEM;
2417	}
2418	/* create space for the outbuffer */
2419	usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
2420	if (!(usbduxsub[index].outBuffer)) {
2421		dev_err(dev, "comedi_: usbdux: "
2422			"could not alloc space for outBuffer\n");
2423		tidy_up(&(usbduxsub[index]));
2424		up(&start_stop_sem);
2425		return -ENOMEM;
2426	}
2427	/* setting to alternate setting 3: enabling iso ep and bulk ep. */
2428	i = usb_set_interface(usbduxsub[index].usbdev,
2429			      usbduxsub[index].ifnum, 3);
2430	if (i < 0) {
2431		dev_err(dev, "comedi_: usbdux%d: "
2432			"could not set alternate setting 3 in high speed.\n",
2433			index);
2434		tidy_up(&(usbduxsub[index]));
2435		up(&start_stop_sem);
2436		return -ENODEV;
2437	}
2438	if (usbduxsub[index].high_speed)
2439		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
2440	else
2441		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
2442
2443	usbduxsub[index].urbIn =
2444	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
2445		    GFP_KERNEL);
2446	if (!(usbduxsub[index].urbIn)) {
2447		dev_err(dev, "comedi_: usbdux: Could not alloc. urbIn array\n");
2448		tidy_up(&(usbduxsub[index]));
2449		up(&start_stop_sem);
2450		return -ENOMEM;
2451	}
2452	for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
2453		/* one frame: 1ms */
2454		usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
2455		if (usbduxsub[index].urbIn[i] == NULL) {
2456			dev_err(dev, "comedi_: usbdux%d: "
2457				"Could not alloc. urb(%d)\n", index, i);
2458			tidy_up(&(usbduxsub[index]));
2459			up(&start_stop_sem);
2460			return -ENOMEM;
2461		}
2462		usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
2463		/* will be filled later with a pointer to the comedi-device */
2464		/* and ONLY then the urb should be submitted */
2465		usbduxsub[index].urbIn[i]->context = NULL;
2466		usbduxsub[index].urbIn[i]->pipe =
2467		    usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
2468		usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
2469		usbduxsub[index].urbIn[i]->transfer_buffer =
2470		    kzalloc(SIZEINBUF, GFP_KERNEL);
2471		if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
2472			dev_err(dev, "comedi_: usbdux%d: "
2473				"could not alloc. transb.\n", index);
2474			tidy_up(&(usbduxsub[index]));
2475			up(&start_stop_sem);
2476			return -ENOMEM;
2477		}
2478		usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
2479		usbduxsub[index].urbIn[i]->number_of_packets = 1;
2480		usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
2481		usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
2482		usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF;
2483	}
2484
2485	/* out */
2486	if (usbduxsub[index].high_speed)
2487		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
2488	else
2489		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
2490
2491	usbduxsub[index].urbOut =
2492	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
2493		    GFP_KERNEL);
2494	if (!(usbduxsub[index].urbOut)) {
2495		dev_err(dev, "comedi_: usbdux: "
2496			"Could not alloc. urbOut array\n");
2497		tidy_up(&(usbduxsub[index]));
2498		up(&start_stop_sem);
2499		return -ENOMEM;
2500	}
2501	for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
2502		/* one frame: 1ms */
2503		usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
2504		if (usbduxsub[index].urbOut[i] == NULL) {
2505			dev_err(dev, "comedi_: usbdux%d: "
2506				"Could not alloc. urb(%d)\n", index, i);
2507			tidy_up(&(usbduxsub[index]));
2508			up(&start_stop_sem);
2509			return -ENOMEM;
2510		}
2511		usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
2512		/* will be filled later with a pointer to the comedi-device */
2513		/* and ONLY then the urb should be submitted */
2514		usbduxsub[index].urbOut[i]->context = NULL;
2515		usbduxsub[index].urbOut[i]->pipe =
2516		    usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
2517		usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
2518		usbduxsub[index].urbOut[i]->transfer_buffer =
2519		    kzalloc(SIZEOUTBUF, GFP_KERNEL);
2520		if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
2521			dev_err(dev, "comedi_: usbdux%d: "
2522				"could not alloc. transb.\n", index);
2523			tidy_up(&(usbduxsub[index]));
2524			up(&start_stop_sem);
2525			return -ENOMEM;
2526		}
2527		usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
2528		usbduxsub[index].urbOut[i]->number_of_packets = 1;
2529		usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
2530		usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
2531		usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
2532		    SIZEOUTBUF;
2533		if (usbduxsub[index].high_speed) {
2534			/* uframes */
2535			usbduxsub[index].urbOut[i]->interval = 8;
2536		} else {
2537			/* frames */
2538			usbduxsub[index].urbOut[i]->interval = 1;
2539		}
2540	}
2541
2542	/* pwm */
2543	if (usbduxsub[index].high_speed) {
2544		/* max bulk ep size in high speed */
2545		usbduxsub[index].sizePwmBuf = 512;
2546		usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
2547		if (usbduxsub[index].urbPwm == NULL) {
2548			dev_err(dev, "comedi_: usbdux%d: "
2549				"Could not alloc. pwm urb\n", index);
2550			tidy_up(&(usbduxsub[index]));
2551			up(&start_stop_sem);
2552			return -ENOMEM;
2553		}
2554		usbduxsub[index].urbPwm->transfer_buffer =
2555		    kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
2556		if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2557			dev_err(dev, "comedi_: usbdux%d: "
2558				"could not alloc. transb. for pwm\n", index);
2559			tidy_up(&(usbduxsub[index]));
2560			up(&start_stop_sem);
2561			return -ENOMEM;
2562		}
2563	} else {
2564		usbduxsub[index].urbPwm = NULL;
2565		usbduxsub[index].sizePwmBuf = 0;
2566	}
2567
2568	usbduxsub[index].ai_cmd_running = 0;
2569	usbduxsub[index].ao_cmd_running = 0;
2570	usbduxsub[index].pwm_cmd_running = 0;
2571
2572	/* we've reached the bottom of the function */
2573	usbduxsub[index].probed = 1;
2574	up(&start_stop_sem);
2575
2576	ret = request_firmware_nowait(THIS_MODULE,
2577				      FW_ACTION_HOTPLUG,
2578				      "usbdux_firmware.bin",
2579				      &udev->dev,
2580				      GFP_KERNEL,
2581				      usbduxsub + index,
2582				      usbdux_firmware_request_complete_handler);
2583
2584	if (ret) {
2585		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
2586		return ret;
2587	}
2588
2589	dev_info(dev, "comedi_: usbdux%d "
2590		 "has been successfully initialised.\n", index);
2591	/* success */
2592	return 0;
2593}
2594
2595static void usbduxsub_disconnect(struct usb_interface *intf)
2596{
2597	struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2598	struct usb_device *udev = interface_to_usbdev(intf);
2599
2600	if (!usbduxsub_tmp) {
2601		dev_err(&intf->dev,
2602			"comedi_: disconnect called with null pointer.\n");
2603		return;
2604	}
2605	if (usbduxsub_tmp->usbdev != udev) {
2606		dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
2607		return;
2608	}
2609	comedi_usb_auto_unconfig(udev);
2610	down(&start_stop_sem);
2611	down(&usbduxsub_tmp->sem);
2612	tidy_up(usbduxsub_tmp);
2613	up(&usbduxsub_tmp->sem);
2614	up(&start_stop_sem);
2615	dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n");
2616}
2617
2618/* is called when comedi-config is called */
2619static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2620{
2621	int ret;
2622	int index;
2623	int i;
2624	struct usbduxsub *udev;
2625
2626	struct comedi_subdevice *s = NULL;
2627	dev->private = NULL;
2628
2629	down(&start_stop_sem);
2630	/* find a valid device which has been detected by the probe function of
2631	 * the usb */
2632	index = -1;
2633	for (i = 0; i < NUMUSBDUX; i++) {
2634		if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
2635			index = i;
2636			break;
2637		}
2638	}
2639
2640	if (index < 0) {
2641		printk(KERN_ERR "comedi%d: usbdux: error: attach failed, no "
2642		       "usbdux devs connected to the usb bus.\n", dev->minor);
2643		up(&start_stop_sem);
2644		return -ENODEV;
2645	}
2646
2647	udev = &usbduxsub[index];
2648	down(&udev->sem);
2649	/* pointer back to the corresponding comedi device */
2650	udev->comedidev = dev;
2651
2652	/* trying to upload the firmware into the chip */
2653	if (comedi_aux_data(it->options, 0) &&
2654	    it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
2655		firmwareUpload(udev, comedi_aux_data(it->options, 0),
2656			       it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
2657	}
2658
2659	dev->board_name = BOARDNAME;
2660
2661	/* set number of subdevices */
2662	if (udev->high_speed) {
2663		/* with pwm */
2664		dev->n_subdevices = 5;
2665	} else {
2666		/* without pwm */
2667		dev->n_subdevices = 4;
2668	}
2669
2670	/* allocate space for the subdevices */
2671	ret = alloc_subdevices(dev, dev->n_subdevices);
2672	if (ret < 0) {
2673		dev_err(&udev->interface->dev,
2674			"comedi%d: error alloc space for subdev\n", dev->minor);
2675		up(&udev->sem);
2676		up(&start_stop_sem);
2677		return ret;
2678	}
2679
2680	dev_info(&udev->interface->dev,
2681		 "comedi%d: usb-device %d is attached to comedi.\n",
2682		 dev->minor, index);
2683	/* private structure is also simply the usb-structure */
2684	dev->private = udev;
2685
2686	/* the first subdevice is the A/D converter */
2687	s = dev->subdevices + SUBDEV_AD;
2688	/* the URBs get the comedi subdevice */
2689	/* which is responsible for reading */
2690	/* this is the subdevice which reads data */
2691	dev->read_subdev = s;
2692	/* the subdevice receives as private structure the */
2693	/* usb-structure */
2694	s->private = NULL;
2695	/* analog input */
2696	s->type = COMEDI_SUBD_AI;
2697	/* readable and ref is to ground */
2698	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
2699	/* 8 channels */
2700	s->n_chan = 8;
2701	/* length of the channellist */
2702	s->len_chanlist = 8;
2703	/* callback functions */
2704	s->insn_read = usbdux_ai_insn_read;
2705	s->do_cmdtest = usbdux_ai_cmdtest;
2706	s->do_cmd = usbdux_ai_cmd;
2707	s->cancel = usbdux_ai_cancel;
2708	/* max value from the A/D converter (12bit) */
2709	s->maxdata = 0xfff;
2710	/* range table to convert to physical units */
2711	s->range_table = (&range_usbdux_ai_range);
2712
2713	/* analog out */
2714	s = dev->subdevices + SUBDEV_DA;
2715	/* analog out */
2716	s->type = COMEDI_SUBD_AO;
2717	/* backward pointer */
2718	dev->write_subdev = s;
2719	/* the subdevice receives as private structure the */
2720	/* usb-structure */
2721	s->private = NULL;
2722	/* are writable */
2723	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
2724	/* 4 channels */
2725	s->n_chan = 4;
2726	/* length of the channellist */
2727	s->len_chanlist = 4;
2728	/* 12 bit resolution */
2729	s->maxdata = 0x0fff;
2730	/* bipolar range */
2731	s->range_table = (&range_usbdux_ao_range);
2732	/* callback */
2733	s->do_cmdtest = usbdux_ao_cmdtest;
2734	s->do_cmd = usbdux_ao_cmd;
2735	s->cancel = usbdux_ao_cancel;
2736	s->insn_read = usbdux_ao_insn_read;
2737	s->insn_write = usbdux_ao_insn_write;
2738
2739	/* digital I/O */
2740	s = dev->subdevices + SUBDEV_DIO;
2741	s->type = COMEDI_SUBD_DIO;
2742	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
2743	s->n_chan = 8;
2744	s->maxdata = 1;
2745	s->range_table = (&range_digital);
2746	s->insn_bits = usbdux_dio_insn_bits;
2747	s->insn_config = usbdux_dio_insn_config;
2748	/* we don't use it */
2749	s->private = NULL;
2750
2751	/* counter */
2752	s = dev->subdevices + SUBDEV_COUNTER;
2753	s->type = COMEDI_SUBD_COUNTER;
2754	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
2755	s->n_chan = 4;
2756	s->maxdata = 0xFFFF;
2757	s->insn_read = usbdux_counter_read;
2758	s->insn_write = usbdux_counter_write;
2759	s->insn_config = usbdux_counter_config;
2760
2761	if (udev->high_speed) {
2762		/* timer / pwm */
2763		s = dev->subdevices + SUBDEV_PWM;
2764		s->type = COMEDI_SUBD_PWM;
2765		s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
2766		s->n_chan = 8;
2767		/* this defines the max duty cycle resolution */
2768		s->maxdata = udev->sizePwmBuf;
2769		s->insn_write = usbdux_pwm_write;
2770		s->insn_read = usbdux_pwm_read;
2771		s->insn_config = usbdux_pwm_config;
2772		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
2773	}
2774	/* finally decide that it's attached */
2775	udev->attached = 1;
2776
2777	up(&udev->sem);
2778
2779	up(&start_stop_sem);
2780
2781	dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n",
2782		 dev->minor);
2783
2784	return 0;
2785}
2786
2787static int usbdux_detach(struct comedi_device *dev)
2788{
2789	struct usbduxsub *usbduxsub_tmp;
2790
2791	if (!dev) {
2792		printk(KERN_ERR
2793		       "comedi?: usbdux: detach without dev variable...\n");
2794		return -EFAULT;
2795	}
2796
2797	usbduxsub_tmp = dev->private;
2798	if (!usbduxsub_tmp) {
2799		printk(KERN_ERR
2800		       "comedi?: usbdux: detach without ptr to usbduxsub[]\n");
2801		return -EFAULT;
2802	}
2803
2804	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi%d: detach usb device\n",
2805		dev->minor);
2806
2807	down(&usbduxsub_tmp->sem);
2808	/* Don't allow detach to free the private structure */
2809	/* It's one entry of of usbduxsub[] */
2810	dev->private = NULL;
2811	usbduxsub_tmp->attached = 0;
2812	usbduxsub_tmp->comedidev = NULL;
2813	dev_dbg(&usbduxsub_tmp->interface->dev,
2814		"comedi%d: detach: successfully removed\n", dev->minor);
2815	up(&usbduxsub_tmp->sem);
2816	return 0;
2817}
2818
2819/* main driver struct */
2820static struct comedi_driver driver_usbdux = {
2821	.driver_name = "usbdux",
2822	.module = THIS_MODULE,
2823	.attach = usbdux_attach,
2824	.detach = usbdux_detach,
2825};
2826
2827/* Table with the USB-devices: just now only testing IDs */
2828static const struct usb_device_id usbduxsub_table[] = {
2829	{USB_DEVICE(0x13d8, 0x0001)},
2830	{USB_DEVICE(0x13d8, 0x0002)},
2831	{}			/* Terminating entry */
2832};
2833
2834MODULE_DEVICE_TABLE(usb, usbduxsub_table);
2835
2836/* The usbduxsub-driver */
2837static struct usb_driver usbduxsub_driver = {
2838	.name = BOARDNAME,
2839	.probe = usbduxsub_probe,
2840	.disconnect = usbduxsub_disconnect,
2841	.id_table = usbduxsub_table,
2842};
2843
2844/* Can't use the nice macro as I have also to initialise the USB */
2845/* subsystem: */
2846/* registering the usb-system _and_ the comedi-driver */
2847static int __init init_usbdux(void)
2848{
2849	printk(KERN_INFO KBUILD_MODNAME ": "
2850	       DRIVER_VERSION ":" DRIVER_DESC "\n");
2851	usb_register(&usbduxsub_driver);
2852	comedi_driver_register(&driver_usbdux);
2853	return 0;
2854}
2855
2856/* deregistering the comedi driver and the usb-subsystem */
2857static void __exit exit_usbdux(void)
2858{
2859	comedi_driver_unregister(&driver_usbdux);
2860	usb_deregister(&usbduxsub_driver);
2861}
2862
2863module_init(init_usbdux);
2864module_exit(exit_usbdux);
2865
2866MODULE_AUTHOR(DRIVER_AUTHOR);
2867MODULE_DESCRIPTION(DRIVER_DESC);
2868MODULE_LICENSE("GPL");
2869