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