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