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