[go: nahoru, domu]

1/*
2   comedi/drivers/usbdux.c
3   Copyright (C) 2003-2007 Bernd Porr, Bernd.Porr@f2s.com
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 */
15/*
16Driver: usbdux
17Description: University of Stirling USB DAQ & INCITE Technology Limited
18Devices: [ITL] USB-DUX (usbdux.o)
19Author: Bernd Porr <BerndPorr@f2s.com>
20Updated: 8 Dec 2008
21Status: Stable
22Configuration options:
23  You have to upload firmware with the -i option. The
24  firmware is usually installed under /usr/share/usb or
25  /usr/local/share/usb or /lib/firmware.
26
27Connection scheme for the counter at the digital port:
28  0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
29  The sampling rate of the counter is approximately 500Hz.
30
31Please note that under USB2.0 the length of the channel list determines
32the max sampling rate. If you sample only one channel you get 8kHz
33sampling rate. If you sample two channels you get 4kHz and so on.
34*/
35/*
36 * I must give credit here to Chris Baugher who
37 * wrote the driver for AT-MIO-16d. I used some parts of this
38 * driver. I also must give credits to David Brownell
39 * who supported me with the USB development.
40 *
41 * Bernd Porr
42 *
43 *
44 * Revision history:
45 * 0.94: D/A output should work now with any channel list combinations
46 * 0.95: .owner commented out for kernel vers below 2.4.19
47 *       sanity checks in ai/ao_cmd
48 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
49 *       attach final USB IDs
50 *       moved memory allocation completely to the corresponding comedi
51 *       functions firmware upload is by fxload and no longer by comedi (due to
52 *       enumeration)
53 * 0.97: USB IDs received, adjusted table
54 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
55 *       to the usb subsystem and moved all comedi related memory
56 *       alloc to comedi.
57 *       | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
58 * 0.99: USB 2.0: changed protocol to isochronous transfer
59 *                IRQ transfer is too buggy and too risky in 2.0
60 *                for the high speed ISO transfer is now a working version
61 *                available
62 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
63 *        chipsets miss out IRQs. Deeper buffering is needed.
64 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
65 *       rate.
66 *       Firmware vers 1.00 is needed for this.
67 *       Two 16 bit up/down/reset counter with a sampling rate of 1kHz
68 *       And loads of cleaning up, in particular streamlining the
69 *       bulk transfers.
70 * 1.1:  moved EP4 transfers to EP1 to make space for a PWM output on EP4
71 * 1.2:  added PWM support via EP4
72 * 2.0:  PWM seems to be stable and is not interfering with the other functions
73 * 2.1:  changed PWM API
74 * 2.2:  added firmware kernel request to fix an udev problem
75 * 2.3:  corrected a bug in bulk timeouts which were far too short
76 * 2.4:  fixed a bug which causes the driver to hang when it ran out of data.
77 *       Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
78 *
79 */
80
81#include <linux/kernel.h>
82#include <linux/module.h>
83#include <linux/slab.h>
84#include <linux/input.h>
85#include <linux/usb.h>
86#include <linux/fcntl.h>
87#include <linux/compiler.h>
88
89#include "../comedidev.h"
90
91#include "comedi_fc.h"
92
93/* constants for firmware upload and download */
94#define USBDUX_FIRMWARE		"usbdux_firmware.bin"
95#define USBDUX_FIRMWARE_MAX_LEN	0x2000
96#define USBDUX_FIRMWARE_CMD	0xa0
97#define VENDOR_DIR_IN		0xc0
98#define VENDOR_DIR_OUT		0x40
99#define USBDUX_CPU_CS		0xe600
100
101/* usbdux bulk transfer commands */
102#define USBDUX_CMD_MULT_AI	0
103#define USBDUX_CMD_AO		1
104#define USBDUX_CMD_DIO_CFG	2
105#define USBDUX_CMD_DIO_BITS	3
106#define USBDUX_CMD_SINGLE_AI	4
107#define USBDUX_CMD_TIMER_RD	5
108#define USBDUX_CMD_TIMER_WR	6
109#define USBDUX_CMD_PWM_ON	7
110#define USBDUX_CMD_PWM_OFF	8
111
112/* timeout for the USB-transfer in ms */
113#define BULK_TIMEOUT		1000
114
115/* 300Hz max frequ under PWM */
116#define MIN_PWM_PERIOD  ((long)(1E9/300))
117
118/* Default PWM frequency */
119#define PWM_DEFAULT_PERIOD ((long)(1E9/100))
120
121/* Size of one A/D value */
122#define SIZEADIN          ((sizeof(uint16_t)))
123
124/*
125 * Size of the input-buffer IN BYTES
126 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
127 */
128#define SIZEINBUF         ((8*SIZEADIN))
129
130/* 16 bytes. */
131#define SIZEINSNBUF       16
132
133/* size of one value for the D/A converter: channel and value */
134#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
135
136/*
137 * Size of the output-buffer in bytes
138 * Actually only the first 4 triplets are used but for the
139 * high speed mode we need to pad it to 8 (microframes).
140 */
141#define SIZEOUTBUF         ((8*SIZEDAOUT))
142
143/*
144 * Size of the buffer for the dux commands: just now max size is determined
145 * by the analogue out + command byte + panic bytes...
146 */
147#define SIZEOFDUXBUFFER    ((8*SIZEDAOUT+2))
148
149/* Number of in-URBs which receive the data: min=2 */
150#define NUMOFINBUFFERSFULL     5
151
152/* Number of out-URBs which send the data: min=2 */
153#define NUMOFOUTBUFFERSFULL    5
154
155/* Number of in-URBs which receive the data: min=5 */
156/* must have more buffers due to buggy USB ctr */
157#define NUMOFINBUFFERSHIGH     10
158
159/* Number of out-URBs which send the data: min=5 */
160/* must have more buffers due to buggy USB ctr */
161#define NUMOFOUTBUFFERSHIGH    10
162
163/* number of retries to get the right dux command */
164#define RETRIES 10
165
166static const struct comedi_lrange range_usbdux_ai_range = {
167	4, {
168		BIP_RANGE(4.096),
169		BIP_RANGE(4.096 / 2),
170		UNI_RANGE(4.096),
171		UNI_RANGE(4.096 / 2)
172	}
173};
174
175static const struct comedi_lrange range_usbdux_ao_range = {
176	2, {
177		BIP_RANGE(4.096),
178		UNI_RANGE(4.096)
179	}
180};
181
182struct usbdux_private {
183	/* actual number of in-buffers */
184	int n_ai_urbs;
185	/* actual number of out-buffers */
186	int n_ao_urbs;
187	/* ISO-transfer handling: buffers */
188	struct urb **ai_urbs;
189	struct urb **ao_urbs;
190	/* pwm-transfer handling */
191	struct urb *pwm_urb;
192	/* PWM period */
193	unsigned int pwm_period;
194	/* PWM internal delay for the GPIF in the FX2 */
195	uint8_t pwm_delay;
196	/* size of the PWM buffer which holds the bit pattern */
197	int pwm_buf_sz;
198	/* input buffer for the ISO-transfer */
199	__le16 *in_buf;
200	/* input buffer for single insn */
201	__le16 *insn_buf;
202
203	unsigned int high_speed:1;
204	unsigned int ai_cmd_running:1;
205	unsigned int ao_cmd_running:1;
206	unsigned int pwm_cmd_running:1;
207
208	/* number of samples to acquire */
209	int ai_sample_count;
210	int ao_sample_count;
211	/* time between samples in units of the timer */
212	unsigned int ai_timer;
213	unsigned int ao_timer;
214	/* counter between aquisitions */
215	unsigned int ai_counter;
216	unsigned int ao_counter;
217	/* interval in frames/uframes */
218	unsigned int ai_interval;
219	/* commands */
220	uint8_t *dux_commands;
221	struct semaphore sem;
222};
223
224static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
225{
226	int i;
227
228	for (i = 0; i < num_urbs; i++)
229		usb_kill_urb(urbs[i]);
230}
231
232static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink)
233{
234	struct usbdux_private *devpriv = dev->private;
235
236	if (do_unlink && devpriv->ai_urbs)
237		usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
238
239	devpriv->ai_cmd_running = 0;
240}
241
242static int usbdux_ai_cancel(struct comedi_device *dev,
243			    struct comedi_subdevice *s)
244{
245	struct usbdux_private *devpriv = dev->private;
246
247	/* prevent other CPUs from submitting new commands just now */
248	down(&devpriv->sem);
249	/* unlink only if the urb really has been submitted */
250	usbdux_ai_stop(dev, devpriv->ai_cmd_running);
251	up(&devpriv->sem);
252
253	return 0;
254}
255
256/* analogue IN - interrupt service routine */
257static void usbduxsub_ai_isoc_irq(struct urb *urb)
258{
259	struct comedi_device *dev = urb->context;
260	struct comedi_subdevice *s = dev->read_subdev;
261	struct usbdux_private *devpriv = dev->private;
262	struct comedi_cmd *cmd = &s->async->cmd;
263	int i, err;
264
265	/* first we test if something unusual has just happened */
266	switch (urb->status) {
267	case 0:
268		/* copy the result in the transfer buffer */
269		memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
270		break;
271	case -EILSEQ:
272		/* error in the ISOchronous data */
273		/* we don't copy the data into the transfer buffer */
274		/* and recycle the last data byte */
275		dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
276		break;
277
278	case -ECONNRESET:
279	case -ENOENT:
280	case -ESHUTDOWN:
281	case -ECONNABORTED:
282		/* happens after an unlink command */
283		if (devpriv->ai_cmd_running) {
284			s->async->events |= COMEDI_CB_EOA;
285			s->async->events |= COMEDI_CB_ERROR;
286			comedi_event(dev, s);
287			/* stop the transfer w/o unlink */
288			usbdux_ai_stop(dev, 0);
289		}
290		return;
291
292	default:
293		/* a real error on the bus */
294		/* pass error to comedi if we are really running a command */
295		if (devpriv->ai_cmd_running) {
296			dev_err(dev->class_dev,
297				"Non-zero urb status received in ai intr context: %d\n",
298				urb->status);
299			s->async->events |= COMEDI_CB_EOA;
300			s->async->events |= COMEDI_CB_ERROR;
301			comedi_event(dev, s);
302			/* don't do an unlink here */
303			usbdux_ai_stop(dev, 0);
304		}
305		return;
306	}
307
308	/*
309	 * at this point we are reasonably sure that nothing dodgy has happened
310	 * are we running a command?
311	 */
312	if (unlikely(!devpriv->ai_cmd_running)) {
313		/*
314		 * not running a command, do not continue execution if no
315		 * asynchronous command is running in particular not resubmit
316		 */
317		return;
318	}
319
320	urb->dev = comedi_to_usb_dev(dev);
321
322	/* resubmit the urb */
323	err = usb_submit_urb(urb, GFP_ATOMIC);
324	if (unlikely(err < 0)) {
325		dev_err(dev->class_dev,
326			"urb resubmit failed in int-context! err=%d\n", err);
327		if (err == -EL2NSYNC)
328			dev_err(dev->class_dev,
329				"buggy USB host controller or bug in IRQ handler!\n");
330		s->async->events |= COMEDI_CB_EOA;
331		s->async->events |= COMEDI_CB_ERROR;
332		comedi_event(dev, s);
333		/* don't do an unlink here */
334		usbdux_ai_stop(dev, 0);
335		return;
336	}
337
338	devpriv->ai_counter--;
339	if (likely(devpriv->ai_counter > 0))
340		return;
341
342	/* timer zero, transfer measurements to comedi */
343	devpriv->ai_counter = devpriv->ai_timer;
344
345	/* test, if we transmit only a fixed number of samples */
346	if (cmd->stop_src == TRIG_COUNT) {
347		/* not continuous, fixed number of samples */
348		devpriv->ai_sample_count--;
349		/* all samples received? */
350		if (devpriv->ai_sample_count < 0) {
351			/* prevent a resubmit next time */
352			usbdux_ai_stop(dev, 0);
353			/* say comedi that the acquistion is over */
354			s->async->events |= COMEDI_CB_EOA;
355			comedi_event(dev, s);
356			return;
357		}
358	}
359	/* get the data from the USB bus and hand it over to comedi */
360	for (i = 0; i < cmd->chanlist_len; i++) {
361		unsigned int range = CR_RANGE(cmd->chanlist[i]);
362		uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
363
364		/* bipolar data is two's-complement */
365		if (comedi_range_is_bipolar(s, range))
366			val ^= ((s->maxdata + 1) >> 1);
367
368		/* transfer data */
369		err = comedi_buf_put(s, val);
370		if (unlikely(err == 0)) {
371			/* buffer overflow */
372			usbdux_ai_stop(dev, 0);
373			return;
374		}
375	}
376	/* tell comedi that data is there */
377	s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
378	comedi_event(dev, s);
379}
380
381static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink)
382{
383	struct usbdux_private *devpriv = dev->private;
384
385	if (do_unlink && devpriv->ao_urbs)
386		usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
387
388	devpriv->ao_cmd_running = 0;
389}
390
391static int usbdux_ao_cancel(struct comedi_device *dev,
392			    struct comedi_subdevice *s)
393{
394	struct usbdux_private *devpriv = dev->private;
395
396	/* prevent other CPUs from submitting a command just now */
397	down(&devpriv->sem);
398	/* unlink only if it is really running */
399	usbdux_ao_stop(dev, devpriv->ao_cmd_running);
400	up(&devpriv->sem);
401
402	return 0;
403}
404
405static void usbduxsub_ao_isoc_irq(struct urb *urb)
406{
407	struct comedi_device *dev = urb->context;
408	struct comedi_subdevice *s = dev->write_subdev;
409	struct usbdux_private *devpriv = dev->private;
410	struct comedi_cmd *cmd = &s->async->cmd;
411	uint8_t *datap;
412	int ret;
413	int i;
414
415	switch (urb->status) {
416	case 0:
417		/* success */
418		break;
419
420	case -ECONNRESET:
421	case -ENOENT:
422	case -ESHUTDOWN:
423	case -ECONNABORTED:
424		/* after an unlink command, unplug, ... etc */
425		/* no unlink needed here. Already shutting down. */
426		if (devpriv->ao_cmd_running) {
427			s->async->events |= COMEDI_CB_EOA;
428			comedi_event(dev, s);
429			usbdux_ao_stop(dev, 0);
430		}
431		return;
432
433	default:
434		/* a real error */
435		if (devpriv->ao_cmd_running) {
436			dev_err(dev->class_dev,
437				"Non-zero urb status received in ao intr context: %d\n",
438				urb->status);
439			s->async->events |= COMEDI_CB_ERROR;
440			s->async->events |= COMEDI_CB_EOA;
441			comedi_event(dev, s);
442			/* we do an unlink if we are in the high speed mode */
443			usbdux_ao_stop(dev, 0);
444		}
445		return;
446	}
447
448	/* are we actually running? */
449	if (!devpriv->ao_cmd_running)
450		return;
451
452	/* normal operation: executing a command in this subdevice */
453	devpriv->ao_counter--;
454	if ((int)devpriv->ao_counter <= 0) {
455		/* timer zero */
456		devpriv->ao_counter = devpriv->ao_timer;
457
458		/* handle non continous acquisition */
459		if (cmd->stop_src == TRIG_COUNT) {
460			/* fixed number of samples */
461			devpriv->ao_sample_count--;
462			if (devpriv->ao_sample_count < 0) {
463				/* all samples transmitted */
464				usbdux_ao_stop(dev, 0);
465				s->async->events |= COMEDI_CB_EOA;
466				comedi_event(dev, s);
467				/* no resubmit of the urb */
468				return;
469			}
470		}
471
472		/* transmit data to the USB bus */
473		datap = urb->transfer_buffer;
474		*datap++ = cmd->chanlist_len;
475		for (i = 0; i < cmd->chanlist_len; i++) {
476			unsigned int chan = CR_CHAN(cmd->chanlist[i]);
477			unsigned short val;
478
479			ret = comedi_buf_get(s, &val);
480			if (ret < 0) {
481				dev_err(dev->class_dev, "buffer underflow\n");
482				s->async->events |= (COMEDI_CB_EOA |
483						     COMEDI_CB_OVERFLOW);
484			}
485			/* pointer to the DA */
486			*datap++ = val & 0xff;
487			*datap++ = (val >> 8) & 0xff;
488			*datap++ = chan << 6;
489			s->readback[chan] = val;
490
491			s->async->events |= COMEDI_CB_BLOCK;
492			comedi_event(dev, s);
493		}
494	}
495	urb->transfer_buffer_length = SIZEOUTBUF;
496	urb->dev = comedi_to_usb_dev(dev);
497	urb->status = 0;
498	if (devpriv->ao_cmd_running) {
499		if (devpriv->high_speed)
500			urb->interval = 8;	/* uframes */
501		else
502			urb->interval = 1;	/* frames */
503		urb->number_of_packets = 1;
504		urb->iso_frame_desc[0].offset = 0;
505		urb->iso_frame_desc[0].length = SIZEOUTBUF;
506		urb->iso_frame_desc[0].status = 0;
507		ret = usb_submit_urb(urb, GFP_ATOMIC);
508		if (ret < 0) {
509			dev_err(dev->class_dev,
510				"ao urb resubm failed in int-cont. ret=%d",
511				ret);
512			if (ret == -EL2NSYNC)
513				dev_err(dev->class_dev,
514					"buggy USB host controller or bug in IRQ handling!\n");
515
516			s->async->events |= COMEDI_CB_EOA;
517			s->async->events |= COMEDI_CB_ERROR;
518			comedi_event(dev, s);
519			/* don't do an unlink here */
520			usbdux_ao_stop(dev, 0);
521		}
522	}
523}
524
525static int usbdux_submit_urbs(struct comedi_device *dev,
526			      struct urb **urbs, int num_urbs,
527			      int input_urb)
528{
529	struct usb_device *usb = comedi_to_usb_dev(dev);
530	struct usbdux_private *devpriv = dev->private;
531	struct urb *urb;
532	int ret;
533	int i;
534
535	/* Submit all URBs and start the transfer on the bus */
536	for (i = 0; i < num_urbs; i++) {
537		urb = urbs[i];
538
539		/* in case of a resubmission after an unlink... */
540		if (input_urb)
541			urb->interval = devpriv->ai_interval;
542		urb->context = dev;
543		urb->dev = usb;
544		urb->status = 0;
545		urb->transfer_flags = URB_ISO_ASAP;
546
547		ret = usb_submit_urb(urb, GFP_ATOMIC);
548		if (ret)
549			return ret;
550	}
551	return 0;
552}
553
554static int usbdux_ai_cmdtest(struct comedi_device *dev,
555			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
556{
557	struct usbdux_private *this_usbduxsub = dev->private;
558	int err = 0, i;
559	unsigned int tmp_timer;
560
561	/* Step 1 : check if triggers are trivially valid */
562
563	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
564	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
565	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
566	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
567	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
568
569	if (err)
570		return 1;
571
572	/* Step 2a : make sure trigger sources are unique */
573
574	err |= cfc_check_trigger_is_unique(cmd->start_src);
575	err |= cfc_check_trigger_is_unique(cmd->stop_src);
576
577	/* Step 2b : and mutually compatible */
578
579	if (err)
580		return 2;
581
582	/* Step 3: check if arguments are trivially valid */
583
584	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
585
586	if (cmd->scan_begin_src == TRIG_FOLLOW)	/* internal trigger */
587		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
588
589	if (cmd->scan_begin_src == TRIG_TIMER) {
590		if (this_usbduxsub->high_speed) {
591			/*
592			 * In high speed mode microframes are possible.
593			 * However, during one microframe we can roughly
594			 * sample one channel. Thus, the more channels
595			 * are in the channel list the more time we need.
596			 */
597			i = 1;
598			/* find a power of 2 for the number of channels */
599			while (i < (cmd->chanlist_len))
600				i = i * 2;
601
602			err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
603							 1000000 / 8 * i);
604			/* now calc the real sampling rate with all the
605			 * rounding errors */
606			tmp_timer =
607			    ((unsigned int)(cmd->scan_begin_arg / 125000)) *
608			    125000;
609		} else {
610			/* full speed */
611			/* 1kHz scans every USB frame */
612			err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
613							 1000000);
614			/*
615			 * calc the real sampling rate with the rounding errors
616			 */
617			tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
618						   1000000)) * 1000000;
619		}
620		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
621						tmp_timer);
622	}
623
624	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
625
626	if (cmd->stop_src == TRIG_COUNT)
627		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
628	else	/* TRIG_NONE */
629		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
630
631	if (err)
632		return 3;
633
634	return 0;
635}
636
637/*
638 * creates the ADC command for the MAX1271
639 * range is the range value from comedi
640 */
641static uint8_t create_adc_command(unsigned int chan, unsigned int range)
642{
643	uint8_t p = (range <= 1);
644	uint8_t r = ((range % 2) == 0);
645
646	return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
647}
648
649static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
650{
651	struct usb_device *usb = comedi_to_usb_dev(dev);
652	struct usbdux_private *devpriv = dev->private;
653	int nsent;
654
655	devpriv->dux_commands[0] = cmd_type;
656
657	return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
658			    devpriv->dux_commands, SIZEOFDUXBUFFER,
659			    &nsent, BULK_TIMEOUT);
660}
661
662static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
663{
664	struct usb_device *usb = comedi_to_usb_dev(dev);
665	struct usbdux_private *devpriv = dev->private;
666	int ret;
667	int nrec;
668	int i;
669
670	for (i = 0; i < RETRIES; i++) {
671		ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
672				      devpriv->insn_buf, SIZEINSNBUF,
673				      &nrec, BULK_TIMEOUT);
674		if (ret < 0)
675			return ret;
676		if (le16_to_cpu(devpriv->insn_buf[0]) == command)
677			return ret;
678	}
679	/* command not received */
680	return -EFAULT;
681}
682
683static int usbdux_ai_inttrig(struct comedi_device *dev,
684			     struct comedi_subdevice *s,
685			     unsigned int trig_num)
686{
687	struct usbdux_private *devpriv = dev->private;
688	struct comedi_cmd *cmd = &s->async->cmd;
689	int ret;
690
691	if (trig_num != cmd->start_arg)
692		return -EINVAL;
693
694	down(&devpriv->sem);
695
696	if (!devpriv->ai_cmd_running) {
697		devpriv->ai_cmd_running = 1;
698		ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
699					 devpriv->n_ai_urbs, 1);
700		if (ret < 0) {
701			devpriv->ai_cmd_running = 0;
702			goto ai_trig_exit;
703		}
704		s->async->inttrig = NULL;
705	} else {
706		ret = -EBUSY;
707	}
708
709ai_trig_exit:
710	up(&devpriv->sem);
711	return ret;
712}
713
714static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
715{
716	struct usbdux_private *devpriv = dev->private;
717	struct comedi_cmd *cmd = &s->async->cmd;
718	int len = cmd->chanlist_len;
719	int ret = -EBUSY;
720	int i;
721
722	/* block other CPUs from starting an ai_cmd */
723	down(&devpriv->sem);
724
725	if (devpriv->ai_cmd_running)
726		goto ai_cmd_exit;
727
728	/* set current channel of the running acquisition to zero */
729	s->async->cur_chan = 0;
730
731	devpriv->dux_commands[1] = len;
732	for (i = 0; i < len; ++i) {
733		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
734		unsigned int range = CR_RANGE(cmd->chanlist[i]);
735
736		devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
737	}
738
739	ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI);
740	if (ret < 0)
741		goto ai_cmd_exit;
742
743	if (devpriv->high_speed) {
744		/*
745		 * every channel gets a time window of 125us. Thus, if we
746		 * sample all 8 channels we need 1ms. If we sample only one
747		 * channel we need only 125us
748		 */
749		devpriv->ai_interval = 1;
750		/* find a power of 2 for the interval */
751		while (devpriv->ai_interval < len)
752			devpriv->ai_interval *= 2;
753
754		devpriv->ai_timer = cmd->scan_begin_arg /
755				    (125000 * devpriv->ai_interval);
756	} else {
757		/* interval always 1ms */
758		devpriv->ai_interval = 1;
759		devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
760	}
761	if (devpriv->ai_timer < 1) {
762		ret = -EINVAL;
763		goto ai_cmd_exit;
764	}
765
766	devpriv->ai_counter = devpriv->ai_timer;
767
768	if (cmd->stop_src == TRIG_COUNT) {
769		/* data arrives as one packet */
770		devpriv->ai_sample_count = cmd->stop_arg;
771	} else {
772		/* continous acquisition */
773		devpriv->ai_sample_count = 0;
774	}
775
776	if (cmd->start_src == TRIG_NOW) {
777		/* enable this acquisition operation */
778		devpriv->ai_cmd_running = 1;
779		ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
780					 devpriv->n_ai_urbs, 1);
781		if (ret < 0) {
782			devpriv->ai_cmd_running = 0;
783			/* fixme: unlink here?? */
784			goto ai_cmd_exit;
785		}
786		s->async->inttrig = NULL;
787	} else {
788		/* TRIG_INT */
789		/* don't enable the acquision operation */
790		/* wait for an internal signal */
791		s->async->inttrig = usbdux_ai_inttrig;
792	}
793
794ai_cmd_exit:
795	up(&devpriv->sem);
796
797	return ret;
798}
799
800/* Mode 0 is used to get a single conversion on demand */
801static int usbdux_ai_insn_read(struct comedi_device *dev,
802			       struct comedi_subdevice *s,
803			       struct comedi_insn *insn,
804			       unsigned int *data)
805{
806	struct usbdux_private *devpriv = dev->private;
807	unsigned int chan = CR_CHAN(insn->chanspec);
808	unsigned int range = CR_RANGE(insn->chanspec);
809	unsigned int val;
810	int ret = -EBUSY;
811	int i;
812
813	down(&devpriv->sem);
814
815	if (devpriv->ai_cmd_running)
816		goto ai_read_exit;
817
818	/* set command for the first channel */
819	devpriv->dux_commands[1] = create_adc_command(chan, range);
820
821	/* adc commands */
822	ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
823	if (ret < 0)
824		goto ai_read_exit;
825
826	for (i = 0; i < insn->n; i++) {
827		ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
828		if (ret < 0)
829			goto ai_read_exit;
830
831		val = le16_to_cpu(devpriv->insn_buf[1]);
832
833		/* bipolar data is two's-complement */
834		if (comedi_range_is_bipolar(s, range))
835			val ^= ((s->maxdata + 1) >> 1);
836
837		data[i] = val;
838	}
839
840ai_read_exit:
841	up(&devpriv->sem);
842
843	return ret ? ret : insn->n;
844}
845
846static int usbdux_ao_insn_read(struct comedi_device *dev,
847			       struct comedi_subdevice *s,
848			       struct comedi_insn *insn,
849			       unsigned int *data)
850{
851	struct usbdux_private *devpriv = dev->private;
852	int ret;
853
854	down(&devpriv->sem);
855	ret = comedi_readback_insn_read(dev, s, insn, data);
856	up(&devpriv->sem);
857
858	return ret;
859}
860
861static int usbdux_ao_insn_write(struct comedi_device *dev,
862				struct comedi_subdevice *s,
863				struct comedi_insn *insn,
864				unsigned int *data)
865{
866	struct usbdux_private *devpriv = dev->private;
867	unsigned int chan = CR_CHAN(insn->chanspec);
868	unsigned int val = s->readback[chan];
869	__le16 *p = (__le16 *)&devpriv->dux_commands[2];
870	int ret = -EBUSY;
871	int i;
872
873	down(&devpriv->sem);
874
875	if (devpriv->ao_cmd_running)
876		goto ao_write_exit;
877
878	/* number of channels: 1 */
879	devpriv->dux_commands[1] = 1;
880	/* channel number */
881	devpriv->dux_commands[4] = chan << 6;
882
883	for (i = 0; i < insn->n; i++) {
884		val = data[i];
885
886		/* one 16 bit value */
887		*p = cpu_to_le16(val);
888
889		ret = send_dux_commands(dev, USBDUX_CMD_AO);
890		if (ret < 0)
891			goto ao_write_exit;
892
893		s->readback[chan] = val;
894	}
895
896ao_write_exit:
897	up(&devpriv->sem);
898
899	return ret ? ret : insn->n;
900}
901
902static int usbdux_ao_inttrig(struct comedi_device *dev,
903			     struct comedi_subdevice *s,
904			     unsigned int trig_num)
905{
906	struct usbdux_private *devpriv = dev->private;
907	struct comedi_cmd *cmd = &s->async->cmd;
908	int ret;
909
910	if (trig_num != cmd->start_arg)
911		return -EINVAL;
912
913	down(&devpriv->sem);
914
915	if (!devpriv->ao_cmd_running) {
916		devpriv->ao_cmd_running = 1;
917		ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
918					 devpriv->n_ao_urbs, 0);
919		if (ret < 0) {
920			devpriv->ao_cmd_running = 0;
921			goto ao_trig_exit;
922		}
923		s->async->inttrig = NULL;
924	} else {
925		ret = -EBUSY;
926	}
927
928ao_trig_exit:
929	up(&devpriv->sem);
930	return ret;
931}
932
933static int usbdux_ao_cmdtest(struct comedi_device *dev,
934			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
935{
936	struct usbdux_private *this_usbduxsub = dev->private;
937	int err = 0;
938	unsigned int flags;
939
940	if (!this_usbduxsub)
941		return -EFAULT;
942
943	/* Step 1 : check if triggers are trivially valid */
944
945	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
946
947	if (0) {		/* (this_usbduxsub->high_speed) */
948		/* the sampling rate is set by the coversion rate */
949		flags = TRIG_FOLLOW;
950	} else {
951		/* start a new scan (output at once) with a timer */
952		flags = TRIG_TIMER;
953	}
954	err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
955
956	if (0) {		/* (this_usbduxsub->high_speed) */
957		/*
958		 * in usb-2.0 only one conversion it transmitted
959		 * but with 8kHz/n
960		 */
961		flags = TRIG_TIMER;
962	} else {
963		/*
964		 * all conversion events happen simultaneously with
965		 * a rate of 1kHz/n
966		 */
967		flags = TRIG_NOW;
968	}
969	err |= cfc_check_trigger_src(&cmd->convert_src, flags);
970
971	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
972	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
973
974	if (err)
975		return 1;
976
977	/* Step 2a : make sure trigger sources are unique */
978
979	err |= cfc_check_trigger_is_unique(cmd->start_src);
980	err |= cfc_check_trigger_is_unique(cmd->stop_src);
981
982	/* Step 2b : and mutually compatible */
983
984	if (err)
985		return 2;
986
987	/* Step 3: check if arguments are trivially valid */
988
989	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
990
991	if (cmd->scan_begin_src == TRIG_FOLLOW)	/* internal trigger */
992		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
993
994	if (cmd->scan_begin_src == TRIG_TIMER)
995		err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
996						 1000000);
997
998	/* not used now, is for later use */
999	if (cmd->convert_src == TRIG_TIMER)
1000		err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1001
1002	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1003
1004	if (cmd->stop_src == TRIG_COUNT)
1005		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1006	else	/* TRIG_NONE */
1007		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1008
1009	if (err)
1010		return 3;
1011
1012	return 0;
1013}
1014
1015static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1016{
1017	struct usbdux_private *devpriv = dev->private;
1018	struct comedi_cmd *cmd = &s->async->cmd;
1019	int ret = -EBUSY;
1020
1021	down(&devpriv->sem);
1022
1023	if (devpriv->ao_cmd_running)
1024		goto ao_cmd_exit;
1025
1026	/* set current channel of the running acquisition to zero */
1027	s->async->cur_chan = 0;
1028
1029	/* we count in steps of 1ms (125us) */
1030	/* 125us mode not used yet */
1031	if (0) {		/* (devpriv->high_speed) */
1032		/* 125us */
1033		/* timing of the conversion itself: every 125 us */
1034		devpriv->ao_timer = cmd->convert_arg / 125000;
1035	} else {
1036		/* 1ms */
1037		/* timing of the scan: we get all channels at once */
1038		devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
1039		if (devpriv->ao_timer < 1) {
1040			ret = -EINVAL;
1041			goto ao_cmd_exit;
1042		}
1043	}
1044
1045	devpriv->ao_counter = devpriv->ao_timer;
1046
1047	if (cmd->stop_src == TRIG_COUNT) {
1048		/* not continuous */
1049		/* counter */
1050		/* high speed also scans everything at once */
1051		if (0) {	/* (devpriv->high_speed) */
1052			devpriv->ao_sample_count = cmd->stop_arg *
1053						   cmd->scan_end_arg;
1054		} else {
1055			/* there's no scan as the scan has been */
1056			/* perf inside the FX2 */
1057			/* data arrives as one packet */
1058			devpriv->ao_sample_count = cmd->stop_arg;
1059		}
1060	} else {
1061		/* continous acquisition */
1062		devpriv->ao_sample_count = 0;
1063	}
1064
1065	if (cmd->start_src == TRIG_NOW) {
1066		/* enable this acquisition operation */
1067		devpriv->ao_cmd_running = 1;
1068		ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
1069					 devpriv->n_ao_urbs, 0);
1070		if (ret < 0) {
1071			devpriv->ao_cmd_running = 0;
1072			/* fixme: unlink here?? */
1073			goto ao_cmd_exit;
1074		}
1075		s->async->inttrig = NULL;
1076	} else {
1077		/* TRIG_INT */
1078		/* submit the urbs later */
1079		/* wait for an internal signal */
1080		s->async->inttrig = usbdux_ao_inttrig;
1081	}
1082
1083ao_cmd_exit:
1084	up(&devpriv->sem);
1085
1086	return ret;
1087}
1088
1089static int usbdux_dio_insn_config(struct comedi_device *dev,
1090				  struct comedi_subdevice *s,
1091				  struct comedi_insn *insn,
1092				  unsigned int *data)
1093{
1094	int ret;
1095
1096	ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1097	if (ret)
1098		return ret;
1099
1100	/*
1101	 * We don't tell the firmware here as it would take 8 frames
1102	 * to submit the information. We do it in the insn_bits.
1103	 */
1104	return insn->n;
1105}
1106
1107static int usbdux_dio_insn_bits(struct comedi_device *dev,
1108				struct comedi_subdevice *s,
1109				struct comedi_insn *insn,
1110				unsigned int *data)
1111{
1112
1113	struct usbdux_private *devpriv = dev->private;
1114	int ret;
1115
1116	down(&devpriv->sem);
1117
1118	comedi_dio_update_state(s, data);
1119
1120	/* Always update the hardware. See the (*insn_config). */
1121	devpriv->dux_commands[1] = s->io_bits;
1122	devpriv->dux_commands[2] = s->state;
1123
1124	/*
1125	 * This command also tells the firmware to return
1126	 * the digital input lines.
1127	 */
1128	ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1129	if (ret < 0)
1130		goto dio_exit;
1131	ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1132	if (ret < 0)
1133		goto dio_exit;
1134
1135	data[1] = le16_to_cpu(devpriv->insn_buf[1]);
1136
1137dio_exit:
1138	up(&devpriv->sem);
1139
1140	return ret ? ret : insn->n;
1141}
1142
1143static int usbdux_counter_read(struct comedi_device *dev,
1144			       struct comedi_subdevice *s,
1145			       struct comedi_insn *insn,
1146			       unsigned int *data)
1147{
1148	struct usbdux_private *devpriv = dev->private;
1149	unsigned int chan = CR_CHAN(insn->chanspec);
1150	int ret = 0;
1151	int i;
1152
1153	down(&devpriv->sem);
1154
1155	for (i = 0; i < insn->n; i++) {
1156		ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1157		if (ret < 0)
1158			goto counter_read_exit;
1159		ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1160		if (ret < 0)
1161			goto counter_read_exit;
1162
1163		data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
1164	}
1165
1166counter_read_exit:
1167	up(&devpriv->sem);
1168
1169	return ret ? ret : insn->n;
1170}
1171
1172static int usbdux_counter_write(struct comedi_device *dev,
1173				struct comedi_subdevice *s,
1174				struct comedi_insn *insn,
1175				unsigned int *data)
1176{
1177	struct usbdux_private *devpriv = dev->private;
1178	unsigned int chan = CR_CHAN(insn->chanspec);
1179	__le16 *p = (__le16 *)&devpriv->dux_commands[2];
1180	int ret = 0;
1181	int i;
1182
1183	down(&devpriv->sem);
1184
1185	devpriv->dux_commands[1] = chan;
1186
1187	for (i = 0; i < insn->n; i++) {
1188		*p = cpu_to_le16(data[i]);
1189
1190		ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
1191		if (ret < 0)
1192			break;
1193	}
1194
1195	up(&devpriv->sem);
1196
1197	return ret ? ret : insn->n;
1198}
1199
1200static int usbdux_counter_config(struct comedi_device *dev,
1201				 struct comedi_subdevice *s,
1202				 struct comedi_insn *insn, unsigned int *data)
1203{
1204	/* nothing to do so far */
1205	return 2;
1206}
1207
1208static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
1209{
1210	struct usbdux_private *devpriv = dev->private;
1211
1212	usb_kill_urb(devpriv->pwm_urb);
1213}
1214
1215static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
1216{
1217	struct usbdux_private *devpriv = dev->private;
1218
1219	if (do_unlink)
1220		usbduxsub_unlink_pwm_urbs(dev);
1221
1222	devpriv->pwm_cmd_running = 0;
1223}
1224
1225static int usbdux_pwm_cancel(struct comedi_device *dev,
1226			     struct comedi_subdevice *s)
1227{
1228	struct usbdux_private *devpriv = dev->private;
1229	int ret;
1230
1231	down(&devpriv->sem);
1232	/* unlink only if it is really running */
1233	usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
1234	ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
1235	up(&devpriv->sem);
1236
1237	return ret;
1238}
1239
1240static void usbduxsub_pwm_irq(struct urb *urb)
1241{
1242	struct comedi_device *dev = urb->context;
1243	struct usbdux_private *devpriv = dev->private;
1244	int ret;
1245
1246	switch (urb->status) {
1247	case 0:
1248		/* success */
1249		break;
1250
1251	case -ECONNRESET:
1252	case -ENOENT:
1253	case -ESHUTDOWN:
1254	case -ECONNABORTED:
1255		/*
1256		 * after an unlink command, unplug, ... etc
1257		 * no unlink needed here. Already shutting down.
1258		 */
1259		if (devpriv->pwm_cmd_running)
1260			usbdux_pwm_stop(dev, 0);
1261
1262		return;
1263
1264	default:
1265		/* a real error */
1266		if (devpriv->pwm_cmd_running) {
1267			dev_err(dev->class_dev,
1268				"Non-zero urb status received in pwm intr context: %d\n",
1269				urb->status);
1270			usbdux_pwm_stop(dev, 0);
1271		}
1272		return;
1273	}
1274
1275	/* are we actually running? */
1276	if (!devpriv->pwm_cmd_running)
1277		return;
1278
1279	urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1280	urb->dev = comedi_to_usb_dev(dev);
1281	urb->status = 0;
1282	if (devpriv->pwm_cmd_running) {
1283		ret = usb_submit_urb(urb, GFP_ATOMIC);
1284		if (ret < 0) {
1285			dev_err(dev->class_dev,
1286				"pwm urb resubm failed in int-cont. ret=%d",
1287				ret);
1288			if (ret == -EL2NSYNC)
1289				dev_err(dev->class_dev,
1290					"buggy USB host controller or bug in IRQ handling!\n");
1291
1292			/* don't do an unlink here */
1293			usbdux_pwm_stop(dev, 0);
1294		}
1295	}
1296}
1297
1298static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
1299{
1300	struct usb_device *usb = comedi_to_usb_dev(dev);
1301	struct usbdux_private *devpriv = dev->private;
1302	struct urb *urb = devpriv->pwm_urb;
1303
1304	/* in case of a resubmission after an unlink... */
1305	usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1306			  urb->transfer_buffer,
1307			  devpriv->pwm_buf_sz,
1308			  usbduxsub_pwm_irq,
1309			  dev);
1310
1311	return usb_submit_urb(urb, GFP_ATOMIC);
1312}
1313
1314static int usbdux_pwm_period(struct comedi_device *dev,
1315			     struct comedi_subdevice *s,
1316			     unsigned int period)
1317{
1318	struct usbdux_private *devpriv = dev->private;
1319	int fx2delay = 255;
1320
1321	if (period < MIN_PWM_PERIOD)
1322		return -EAGAIN;
1323
1324	fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1325	if (fx2delay > 255)
1326		return -EAGAIN;
1327
1328	devpriv->pwm_delay = fx2delay;
1329	devpriv->pwm_period = period;
1330
1331	return 0;
1332}
1333
1334static int usbdux_pwm_start(struct comedi_device *dev,
1335			    struct comedi_subdevice *s)
1336{
1337	struct usbdux_private *devpriv = dev->private;
1338	int ret = 0;
1339
1340	down(&devpriv->sem);
1341
1342	if (devpriv->pwm_cmd_running)
1343		goto pwm_start_exit;
1344
1345	devpriv->dux_commands[1] = devpriv->pwm_delay;
1346	ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
1347	if (ret < 0)
1348		goto pwm_start_exit;
1349
1350	/* initialise the buffer */
1351	memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1352
1353	devpriv->pwm_cmd_running = 1;
1354	ret = usbduxsub_submit_pwm_urbs(dev);
1355	if (ret < 0)
1356		devpriv->pwm_cmd_running = 0;
1357
1358pwm_start_exit:
1359	up(&devpriv->sem);
1360
1361	return ret;
1362}
1363
1364static void usbdux_pwm_pattern(struct comedi_device *dev,
1365			       struct comedi_subdevice *s,
1366			       unsigned int chan,
1367			       unsigned int value,
1368			       unsigned int sign)
1369{
1370	struct usbdux_private *devpriv = dev->private;
1371	char pwm_mask = (1 << chan);	/* DIO bit for the PWM data */
1372	char sgn_mask = (16 << chan);	/* DIO bit for the sign */
1373	char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1374	int szbuf = devpriv->pwm_buf_sz;
1375	int i;
1376
1377	for (i = 0; i < szbuf; i++) {
1378		char c = *buf;
1379
1380		c &= ~pwm_mask;
1381		if (i < value)
1382			c |= pwm_mask;
1383		if (!sign)
1384			c &= ~sgn_mask;
1385		else
1386			c |= sgn_mask;
1387		*buf++ = c;
1388	}
1389}
1390
1391static int usbdux_pwm_write(struct comedi_device *dev,
1392			    struct comedi_subdevice *s,
1393			    struct comedi_insn *insn,
1394			    unsigned int *data)
1395{
1396	unsigned int chan = CR_CHAN(insn->chanspec);
1397
1398	/*
1399	 * It doesn't make sense to support more than one value here
1400	 * because it would just overwrite the PWM buffer.
1401	 */
1402	if (insn->n != 1)
1403		return -EINVAL;
1404
1405	/*
1406	 * The sign is set via a special INSN only, this gives us 8 bits
1407	 * for normal operation, sign is 0 by default.
1408	 */
1409	usbdux_pwm_pattern(dev, s, chan, data[0], 0);
1410
1411	return insn->n;
1412}
1413
1414static int usbdux_pwm_config(struct comedi_device *dev,
1415			     struct comedi_subdevice *s,
1416			     struct comedi_insn *insn,
1417			     unsigned int *data)
1418{
1419	struct usbdux_private *devpriv = dev->private;
1420	unsigned int chan = CR_CHAN(insn->chanspec);
1421
1422	switch (data[0]) {
1423	case INSN_CONFIG_ARM:
1424		/*
1425		 * if not zero the PWM is limited to a certain time which is
1426		 * not supported here
1427		 */
1428		if (data[1] != 0)
1429			return -EINVAL;
1430		return usbdux_pwm_start(dev, s);
1431	case INSN_CONFIG_DISARM:
1432		return usbdux_pwm_cancel(dev, s);
1433	case INSN_CONFIG_GET_PWM_STATUS:
1434		data[1] = devpriv->pwm_cmd_running;
1435		return 0;
1436	case INSN_CONFIG_PWM_SET_PERIOD:
1437		return usbdux_pwm_period(dev, s, data[1]);
1438	case INSN_CONFIG_PWM_GET_PERIOD:
1439		data[1] = devpriv->pwm_period;
1440		return 0;
1441	case INSN_CONFIG_PWM_SET_H_BRIDGE:
1442		/*
1443		 * data[1] = value
1444		 * data[2] = sign (for a relay)
1445		 */
1446		usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1447		return 0;
1448	case INSN_CONFIG_PWM_GET_H_BRIDGE:
1449		/* values are not kept in this driver, nothing to return here */
1450		return -EINVAL;
1451	}
1452	return -EINVAL;
1453}
1454
1455static int usbdux_firmware_upload(struct comedi_device *dev,
1456				  const u8 *data, size_t size,
1457				  unsigned long context)
1458{
1459	struct usb_device *usb = comedi_to_usb_dev(dev);
1460	uint8_t *buf;
1461	uint8_t *tmp;
1462	int ret;
1463
1464	if (!data)
1465		return 0;
1466
1467	if (size > USBDUX_FIRMWARE_MAX_LEN) {
1468		dev_err(dev->class_dev,
1469			"usbdux firmware binary it too large for FX2.\n");
1470		return -ENOMEM;
1471	}
1472
1473	/* we generate a local buffer for the firmware */
1474	buf = kmemdup(data, size, GFP_KERNEL);
1475	if (!buf)
1476		return -ENOMEM;
1477
1478	/* we need a malloc'ed buffer for usb_control_msg() */
1479	tmp = kmalloc(1, GFP_KERNEL);
1480	if (!tmp) {
1481		kfree(buf);
1482		return -ENOMEM;
1483	}
1484
1485	/* stop the current firmware on the device */
1486	*tmp = 1;	/* 7f92 to one */
1487	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1488			      USBDUX_FIRMWARE_CMD,
1489			      VENDOR_DIR_OUT,
1490			      USBDUX_CPU_CS, 0x0000,
1491			      tmp, 1,
1492			      BULK_TIMEOUT);
1493	if (ret < 0) {
1494		dev_err(dev->class_dev, "can not stop firmware\n");
1495		goto done;
1496	}
1497
1498	/* upload the new firmware to the device */
1499	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1500			      USBDUX_FIRMWARE_CMD,
1501			      VENDOR_DIR_OUT,
1502			      0, 0x0000,
1503			      buf, size,
1504			      BULK_TIMEOUT);
1505	if (ret < 0) {
1506		dev_err(dev->class_dev, "firmware upload failed\n");
1507		goto done;
1508	}
1509
1510	/* start the new firmware on the device */
1511	*tmp = 0;	/* 7f92 to zero */
1512	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1513			      USBDUX_FIRMWARE_CMD,
1514			      VENDOR_DIR_OUT,
1515			      USBDUX_CPU_CS, 0x0000,
1516			      tmp, 1,
1517			      BULK_TIMEOUT);
1518	if (ret < 0)
1519		dev_err(dev->class_dev, "can not start firmware\n");
1520
1521done:
1522	kfree(tmp);
1523	kfree(buf);
1524	return ret;
1525}
1526
1527static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
1528{
1529	struct usb_device *usb = comedi_to_usb_dev(dev);
1530	struct usbdux_private *devpriv = dev->private;
1531	struct urb *urb;
1532	int i;
1533
1534	devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1535	devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1536	devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1537	devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
1538				   GFP_KERNEL);
1539	devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
1540				   GFP_KERNEL);
1541	if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1542	    !devpriv->ai_urbs || !devpriv->ao_urbs)
1543		return -ENOMEM;
1544
1545	for (i = 0; i < devpriv->n_ai_urbs; i++) {
1546		/* one frame: 1ms */
1547		urb = usb_alloc_urb(1, GFP_KERNEL);
1548		if (!urb)
1549			return -ENOMEM;
1550		devpriv->ai_urbs[i] = urb;
1551
1552		urb->dev = usb;
1553		urb->context = dev;
1554		urb->pipe = usb_rcvisocpipe(usb, 6);
1555		urb->transfer_flags = URB_ISO_ASAP;
1556		urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1557		if (!urb->transfer_buffer)
1558			return -ENOMEM;
1559
1560		urb->complete = usbduxsub_ai_isoc_irq;
1561		urb->number_of_packets = 1;
1562		urb->transfer_buffer_length = SIZEINBUF;
1563		urb->iso_frame_desc[0].offset = 0;
1564		urb->iso_frame_desc[0].length = SIZEINBUF;
1565	}
1566
1567	for (i = 0; i < devpriv->n_ao_urbs; i++) {
1568		/* one frame: 1ms */
1569		urb = usb_alloc_urb(1, GFP_KERNEL);
1570		if (!urb)
1571			return -ENOMEM;
1572		devpriv->ao_urbs[i] = urb;
1573
1574		urb->dev = usb;
1575		urb->context = dev;
1576		urb->pipe = usb_sndisocpipe(usb, 2);
1577		urb->transfer_flags = URB_ISO_ASAP;
1578		urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1579		if (!urb->transfer_buffer)
1580			return -ENOMEM;
1581
1582		urb->complete = usbduxsub_ao_isoc_irq;
1583		urb->number_of_packets = 1;
1584		urb->transfer_buffer_length = SIZEOUTBUF;
1585		urb->iso_frame_desc[0].offset = 0;
1586		urb->iso_frame_desc[0].length = SIZEOUTBUF;
1587		if (devpriv->high_speed)
1588			urb->interval = 8;	/* uframes */
1589		else
1590			urb->interval = 1;	/* frames */
1591	}
1592
1593	/* pwm */
1594	if (devpriv->pwm_buf_sz) {
1595		urb = usb_alloc_urb(0, GFP_KERNEL);
1596		if (!urb)
1597			return -ENOMEM;
1598		devpriv->pwm_urb = urb;
1599
1600		/* max bulk ep size in high speed */
1601		urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1602					       GFP_KERNEL);
1603		if (!urb->transfer_buffer)
1604			return -ENOMEM;
1605	}
1606
1607	return 0;
1608}
1609
1610static void usbdux_free_usb_buffers(struct comedi_device *dev)
1611{
1612	struct usbdux_private *devpriv = dev->private;
1613	struct urb *urb;
1614	int i;
1615
1616	urb = devpriv->pwm_urb;
1617	if (urb) {
1618		kfree(urb->transfer_buffer);
1619		usb_free_urb(urb);
1620	}
1621	if (devpriv->ao_urbs) {
1622		for (i = 0; i < devpriv->n_ao_urbs; i++) {
1623			urb = devpriv->ao_urbs[i];
1624			if (urb) {
1625				kfree(urb->transfer_buffer);
1626				usb_free_urb(urb);
1627			}
1628		}
1629		kfree(devpriv->ao_urbs);
1630	}
1631	if (devpriv->ai_urbs) {
1632		for (i = 0; i < devpriv->n_ai_urbs; i++) {
1633			urb = devpriv->ai_urbs[i];
1634			if (urb) {
1635				kfree(urb->transfer_buffer);
1636				usb_free_urb(urb);
1637			}
1638		}
1639		kfree(devpriv->ai_urbs);
1640	}
1641	kfree(devpriv->insn_buf);
1642	kfree(devpriv->in_buf);
1643	kfree(devpriv->dux_commands);
1644}
1645
1646static int usbdux_auto_attach(struct comedi_device *dev,
1647			      unsigned long context_unused)
1648{
1649	struct usb_interface *intf = comedi_to_usb_interface(dev);
1650	struct usb_device *usb = comedi_to_usb_dev(dev);
1651	struct usbdux_private *devpriv;
1652	struct comedi_subdevice *s;
1653	int ret;
1654
1655	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1656	if (!devpriv)
1657		return -ENOMEM;
1658
1659	sema_init(&devpriv->sem, 1);
1660
1661	usb_set_intfdata(intf, devpriv);
1662
1663	devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1664	if (devpriv->high_speed) {
1665		devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1666		devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1667		devpriv->pwm_buf_sz = 512;
1668	} else {
1669		devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1670		devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1671	}
1672
1673	ret = usbdux_alloc_usb_buffers(dev);
1674	if (ret)
1675		return ret;
1676
1677	/* setting to alternate setting 3: enabling iso ep and bulk ep. */
1678	ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1679				3);
1680	if (ret < 0) {
1681		dev_err(dev->class_dev,
1682			"could not set alternate setting 3 in high speed\n");
1683		return ret;
1684	}
1685
1686	ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
1687				   usbdux_firmware_upload, 0);
1688	if (ret < 0)
1689		return ret;
1690
1691	ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
1692	if (ret)
1693		return ret;
1694
1695	/* Analog Input subdevice */
1696	s = &dev->subdevices[0];
1697	dev->read_subdev = s;
1698	s->type		= COMEDI_SUBD_AI;
1699	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1700	s->n_chan	= 8;
1701	s->maxdata	= 0x0fff;
1702	s->len_chanlist	= 8;
1703	s->range_table	= &range_usbdux_ai_range;
1704	s->insn_read	= usbdux_ai_insn_read;
1705	s->do_cmdtest	= usbdux_ai_cmdtest;
1706	s->do_cmd	= usbdux_ai_cmd;
1707	s->cancel	= usbdux_ai_cancel;
1708
1709	/* Analog Output subdevice */
1710	s = &dev->subdevices[1];
1711	dev->write_subdev = s;
1712	s->type		= COMEDI_SUBD_AO;
1713	s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1714	s->n_chan	= 4;
1715	s->maxdata	= 0x0fff;
1716	s->len_chanlist	= s->n_chan;
1717	s->range_table	= &range_usbdux_ao_range;
1718	s->do_cmdtest	= usbdux_ao_cmdtest;
1719	s->do_cmd	= usbdux_ao_cmd;
1720	s->cancel	= usbdux_ao_cancel;
1721	s->insn_read	= usbdux_ao_insn_read;
1722	s->insn_write	= usbdux_ao_insn_write;
1723
1724	ret = comedi_alloc_subdev_readback(s);
1725	if (ret)
1726		return ret;
1727
1728	/* Digital I/O subdevice */
1729	s = &dev->subdevices[2];
1730	s->type		= COMEDI_SUBD_DIO;
1731	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
1732	s->n_chan	= 8;
1733	s->maxdata	= 1;
1734	s->range_table	= &range_digital;
1735	s->insn_bits	= usbdux_dio_insn_bits;
1736	s->insn_config	= usbdux_dio_insn_config;
1737
1738	/* Counter subdevice */
1739	s = &dev->subdevices[3];
1740	s->type		= COMEDI_SUBD_COUNTER;
1741	s->subdev_flags	= SDF_WRITABLE | SDF_READABLE;
1742	s->n_chan	= 4;
1743	s->maxdata	= 0xffff;
1744	s->insn_read	= usbdux_counter_read;
1745	s->insn_write	= usbdux_counter_write;
1746	s->insn_config	= usbdux_counter_config;
1747
1748	if (devpriv->high_speed) {
1749		/* PWM subdevice */
1750		s = &dev->subdevices[4];
1751		s->type		= COMEDI_SUBD_PWM;
1752		s->subdev_flags	= SDF_WRITABLE | SDF_PWM_HBRIDGE;
1753		s->n_chan	= 8;
1754		s->maxdata	= devpriv->pwm_buf_sz;
1755		s->insn_write	= usbdux_pwm_write;
1756		s->insn_config	= usbdux_pwm_config;
1757
1758		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1759	}
1760
1761	return 0;
1762}
1763
1764static void usbdux_detach(struct comedi_device *dev)
1765{
1766	struct usb_interface *intf = comedi_to_usb_interface(dev);
1767	struct usbdux_private *devpriv = dev->private;
1768
1769	usb_set_intfdata(intf, NULL);
1770
1771	if (!devpriv)
1772		return;
1773
1774	down(&devpriv->sem);
1775
1776	/* force unlink all urbs */
1777	usbdux_pwm_stop(dev, 1);
1778	usbdux_ao_stop(dev, 1);
1779	usbdux_ai_stop(dev, 1);
1780
1781	usbdux_free_usb_buffers(dev);
1782
1783	up(&devpriv->sem);
1784}
1785
1786static struct comedi_driver usbdux_driver = {
1787	.driver_name	= "usbdux",
1788	.module		= THIS_MODULE,
1789	.auto_attach	= usbdux_auto_attach,
1790	.detach		= usbdux_detach,
1791};
1792
1793static int usbdux_usb_probe(struct usb_interface *intf,
1794			    const struct usb_device_id *id)
1795{
1796	return comedi_usb_auto_config(intf, &usbdux_driver, 0);
1797}
1798
1799static const struct usb_device_id usbdux_usb_table[] = {
1800	{ USB_DEVICE(0x13d8, 0x0001) },
1801	{ USB_DEVICE(0x13d8, 0x0002) },
1802	{ }
1803};
1804MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
1805
1806static struct usb_driver usbdux_usb_driver = {
1807	.name		= "usbdux",
1808	.probe		= usbdux_usb_probe,
1809	.disconnect	= comedi_usb_auto_unconfig,
1810	.id_table	= usbdux_usb_table,
1811};
1812module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
1813
1814MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1815MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1816MODULE_LICENSE("GPL");
1817MODULE_FIRMWARE(USBDUX_FIRMWARE);
1818