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