1// SPDX-License-Identifier: GPL-2.0+
2/*
3 *  Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk
4 */
5
6/*
7 * Driver: usbduxfast
8 * Description: University of Stirling USB DAQ & INCITE Technology Limited
9 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
10 * Author: Bernd Porr <mail@berndporr.me.uk>
11 * Updated: 16 Nov 2019
12 * Status: stable
13 */
14
15/*
16 * I must give credit here to Chris Baugher who
17 * wrote the driver for AT-MIO-16d. I used some parts of this
18 * driver. I also must give credits to David Brownell
19 * who supported me with the USB development.
20 *
21 * Bernd Porr
22 *
23 *
24 * Revision history:
25 * 1.0: Fixed a rounding error in usbduxfast_ai_cmdtest
26 * 0.9: Dropping the first data packet which seems to be from the last transfer.
27 *      Buffer overflows in the FX2 are handed over to comedi.
28 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
29 *       Added insn command basically for testing. Sample rate is
30 *       1MHz/16ch=62.5kHz
31 * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
32 * 0.99a: added external trigger.
33 * 1.00: added firmware kernel request to the driver which fixed
34 *       udev coldplug problem
35 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/slab.h>
40#include <linux/input.h>
41#include <linux/fcntl.h>
42#include <linux/compiler.h>
43#include <linux/comedi/comedi_usb.h>
44
45/*
46 * timeout for the USB-transfer
47 */
48#define EZTIMEOUT	30
49
50/*
51 * constants for "firmware" upload and download
52 */
53#define FIRMWARE		"usbduxfast_firmware.bin"
54#define FIRMWARE_MAX_LEN	0x2000
55#define USBDUXFASTSUB_FIRMWARE	0xA0
56#define VENDOR_DIR_IN		0xC0
57#define VENDOR_DIR_OUT		0x40
58
59/*
60 * internal addresses of the 8051 processor
61 */
62#define USBDUXFASTSUB_CPUCS	0xE600
63
64/*
65 * max length of the transfer-buffer for software upload
66 */
67#define TB_LEN	0x2000
68
69/*
70 * input endpoint number
71 */
72#define BULKINEP	6
73
74/*
75 * endpoint for the A/D channellist: bulk OUT
76 */
77#define CHANNELLISTEP	4
78
79/*
80 * number of channels
81 */
82#define NUMCHANNELS	32
83
84/*
85 * size of the waveform descriptor
86 */
87#define WAVESIZE	0x20
88
89/*
90 * size of one A/D value
91 */
92#define SIZEADIN	(sizeof(s16))
93
94/*
95 * size of the input-buffer IN BYTES
96 */
97#define SIZEINBUF	512
98
99/*
100 * 16 bytes
101 */
102#define SIZEINSNBUF	512
103
104/*
105 * size of the buffer for the dux commands in bytes
106 */
107#define SIZEOFDUXBUF	256
108
109/*
110 * number of in-URBs which receive the data: min=5
111 */
112#define NUMOFINBUFFERSHIGH	10
113
114/*
115 * min delay steps for more than one channel
116 * basically when the mux gives up ;-)
117 *
118 * steps at 30MHz in the FX2
119 */
120#define MIN_SAMPLING_PERIOD	9
121
122/*
123 * max number of 1/30MHz delay steps
124 */
125#define MAX_SAMPLING_PERIOD	500
126
127/*
128 * number of received packets to ignore before we start handing data
129 * over to comedi, it's quad buffering and we have to ignore 4 packets
130 */
131#define PACKETS_TO_IGNORE	4
132
133/*
134 * comedi constants
135 */
136static const struct comedi_lrange range_usbduxfast_ai_range = {
137	2, {
138		BIP_RANGE(0.75),
139		BIP_RANGE(0.5)
140	}
141};
142
143/*
144 * private structure of one subdevice
145 *
146 * this is the structure which holds all the data of this driver
147 * one sub device just now: A/D
148 */
149struct usbduxfast_private {
150	struct urb *urb;	/* BULK-transfer handling: urb */
151	u8 *duxbuf;
152	s8 *inbuf;
153	short int ai_cmd_running;	/* asynchronous command is running */
154	int ignore;		/* counter which ignores the first buffers */
155	struct mutex mut;
156};
157
158/*
159 * bulk transfers to usbduxfast
160 */
161#define SENDADCOMMANDS            0
162#define SENDINITEP6               1
163
164static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
165{
166	struct usb_device *usb = comedi_to_usb_dev(dev);
167	struct usbduxfast_private *devpriv = dev->private;
168	int nsent;
169	int ret;
170
171	devpriv->duxbuf[0] = cmd_type;
172
173	ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
174			   devpriv->duxbuf, SIZEOFDUXBUF,
175			   &nsent, 10000);
176	if (ret < 0)
177		dev_err(dev->class_dev,
178			"could not transmit command to the usb-device, err=%d\n",
179			ret);
180	return ret;
181}
182
183static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
184				u8 len, u8 op, u8 out, u8 log)
185{
186	struct usbduxfast_private *devpriv = dev->private;
187
188	/* Set the GPIF bytes, the first byte is the command byte */
189	devpriv->duxbuf[1 + 0x00 + index] = len;
190	devpriv->duxbuf[1 + 0x08 + index] = op;
191	devpriv->duxbuf[1 + 0x10 + index] = out;
192	devpriv->duxbuf[1 + 0x18 + index] = log;
193}
194
195static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
196{
197	struct usbduxfast_private *devpriv = dev->private;
198
199	/* stop aquistion */
200	devpriv->ai_cmd_running = 0;
201
202	if (do_unlink && devpriv->urb) {
203		/* kill the running transfer */
204		usb_kill_urb(devpriv->urb);
205	}
206
207	return 0;
208}
209
210static int usbduxfast_ai_cancel(struct comedi_device *dev,
211				struct comedi_subdevice *s)
212{
213	struct usbduxfast_private *devpriv = dev->private;
214	int ret;
215
216	mutex_lock(&devpriv->mut);
217	ret = usbduxfast_ai_stop(dev, 1);
218	mutex_unlock(&devpriv->mut);
219
220	return ret;
221}
222
223static void usbduxfast_ai_handle_urb(struct comedi_device *dev,
224				     struct comedi_subdevice *s,
225				     struct urb *urb)
226{
227	struct usbduxfast_private *devpriv = dev->private;
228	struct comedi_async *async = s->async;
229	struct comedi_cmd *cmd = &async->cmd;
230	int ret;
231
232	if (devpriv->ignore) {
233		devpriv->ignore--;
234	} else {
235		unsigned int nsamples;
236
237		nsamples = comedi_bytes_to_samples(s, urb->actual_length);
238		nsamples = comedi_nsamples_left(s, nsamples);
239		comedi_buf_write_samples(s, urb->transfer_buffer, nsamples);
240
241		if (cmd->stop_src == TRIG_COUNT &&
242		    async->scans_done >= cmd->stop_arg)
243			async->events |= COMEDI_CB_EOA;
244	}
245
246	/* if command is still running, resubmit urb for BULK transfer */
247	if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
248		urb->dev = comedi_to_usb_dev(dev);
249		urb->status = 0;
250		ret = usb_submit_urb(urb, GFP_ATOMIC);
251		if (ret < 0) {
252			dev_err(dev->class_dev, "urb resubm failed: %d", ret);
253			async->events |= COMEDI_CB_ERROR;
254		}
255	}
256}
257
258static void usbduxfast_ai_interrupt(struct urb *urb)
259{
260	struct comedi_device *dev = urb->context;
261	struct comedi_subdevice *s = dev->read_subdev;
262	struct comedi_async *async = s->async;
263	struct usbduxfast_private *devpriv = dev->private;
264
265	/* exit if not running a command, do not resubmit urb */
266	if (!devpriv->ai_cmd_running)
267		return;
268
269	switch (urb->status) {
270	case 0:
271		usbduxfast_ai_handle_urb(dev, s, urb);
272		break;
273
274	case -ECONNRESET:
275	case -ENOENT:
276	case -ESHUTDOWN:
277	case -ECONNABORTED:
278		/* after an unlink command, unplug, ... etc */
279		async->events |= COMEDI_CB_ERROR;
280		break;
281
282	default:
283		/* a real error */
284		dev_err(dev->class_dev,
285			"non-zero urb status received in ai intr context: %d\n",
286			urb->status);
287		async->events |= COMEDI_CB_ERROR;
288		break;
289	}
290
291	/*
292	 * comedi_handle_events() cannot be used in this driver. The (*cancel)
293	 * operation would unlink the urb.
294	 */
295	if (async->events & COMEDI_CB_CANCEL_MASK)
296		usbduxfast_ai_stop(dev, 0);
297
298	comedi_event(dev, s);
299}
300
301static int usbduxfast_submit_urb(struct comedi_device *dev)
302{
303	struct usb_device *usb = comedi_to_usb_dev(dev);
304	struct usbduxfast_private *devpriv = dev->private;
305	int ret;
306
307	usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
308			  devpriv->inbuf, SIZEINBUF,
309			  usbduxfast_ai_interrupt, dev);
310
311	ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
312	if (ret) {
313		dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
314		return ret;
315	}
316	return 0;
317}
318
319static int usbduxfast_ai_check_chanlist(struct comedi_device *dev,
320					struct comedi_subdevice *s,
321					struct comedi_cmd *cmd)
322{
323	unsigned int gain0 = CR_RANGE(cmd->chanlist[0]);
324	int i;
325
326	if (cmd->chanlist_len > 3 && cmd->chanlist_len != 16) {
327		dev_err(dev->class_dev, "unsupported combination of channels\n");
328		return -EINVAL;
329	}
330
331	for (i = 0; i < cmd->chanlist_len; ++i) {
332		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
333		unsigned int gain = CR_RANGE(cmd->chanlist[i]);
334
335		if (chan != i) {
336			dev_err(dev->class_dev,
337				"channels are not consecutive\n");
338			return -EINVAL;
339		}
340		if (gain != gain0 && cmd->chanlist_len > 3) {
341			dev_err(dev->class_dev,
342				"gain must be the same for all channels\n");
343			return -EINVAL;
344		}
345	}
346	return 0;
347}
348
349static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
350				 struct comedi_subdevice *s,
351				 struct comedi_cmd *cmd)
352{
353	int err = 0;
354	int err2 = 0;
355	unsigned int steps;
356	unsigned int arg;
357
358	/* Step 1 : check if triggers are trivially valid */
359
360	err |= comedi_check_trigger_src(&cmd->start_src,
361					TRIG_NOW | TRIG_EXT | TRIG_INT);
362	err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
363	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
364	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
365	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
366
367	if (err)
368		return 1;
369
370	/* Step 2a : make sure trigger sources are unique */
371
372	err |= comedi_check_trigger_is_unique(cmd->start_src);
373	err |= comedi_check_trigger_is_unique(cmd->stop_src);
374
375	/* Step 2b : and mutually compatible */
376
377	if (err)
378		return 2;
379
380	/* Step 3: check if arguments are trivially valid */
381
382	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
383
384	if (!cmd->chanlist_len)
385		err |= -EINVAL;
386
387	/* external start trigger is only valid for 1 or 16 channels */
388	if (cmd->start_src == TRIG_EXT &&
389	    cmd->chanlist_len != 1 && cmd->chanlist_len != 16)
390		err |= -EINVAL;
391
392	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
393					   cmd->chanlist_len);
394
395	/*
396	 * Validate the conversion timing:
397	 * for 1 channel the timing in 30MHz "steps" is:
398	 *	steps <= MAX_SAMPLING_PERIOD
399	 * for all other chanlist_len it is:
400	 *	MIN_SAMPLING_PERIOD <= steps <= MAX_SAMPLING_PERIOD
401	 */
402	steps = (cmd->convert_arg * 30) / 1000;
403	if (cmd->chanlist_len !=  1)
404		err2 |= comedi_check_trigger_arg_min(&steps,
405						     MIN_SAMPLING_PERIOD);
406	else
407		err2 |= comedi_check_trigger_arg_min(&steps, 1);
408	err2 |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD);
409	if (err2) {
410		err |= err2;
411		arg = (steps * 1000) / 30;
412		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
413	}
414
415	if (cmd->stop_src == TRIG_COUNT)
416		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
417	else	/* TRIG_NONE */
418		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
419
420	if (err)
421		return 3;
422
423	/* Step 4: fix up any arguments */
424
425	/* Step 5: check channel list if it exists */
426	if (cmd->chanlist && cmd->chanlist_len > 0)
427		err |= usbduxfast_ai_check_chanlist(dev, s, cmd);
428	if (err)
429		return 5;
430
431	return 0;
432}
433
434static int usbduxfast_ai_inttrig(struct comedi_device *dev,
435				 struct comedi_subdevice *s,
436				 unsigned int trig_num)
437{
438	struct usbduxfast_private *devpriv = dev->private;
439	struct comedi_cmd *cmd = &s->async->cmd;
440	int ret;
441
442	if (trig_num != cmd->start_arg)
443		return -EINVAL;
444
445	mutex_lock(&devpriv->mut);
446
447	if (!devpriv->ai_cmd_running) {
448		devpriv->ai_cmd_running = 1;
449		ret = usbduxfast_submit_urb(dev);
450		if (ret < 0) {
451			dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
452			devpriv->ai_cmd_running = 0;
453			mutex_unlock(&devpriv->mut);
454			return ret;
455		}
456		s->async->inttrig = NULL;
457	} else {
458		dev_err(dev->class_dev, "ai is already running\n");
459	}
460	mutex_unlock(&devpriv->mut);
461	return 1;
462}
463
464static int usbduxfast_ai_cmd(struct comedi_device *dev,
465			     struct comedi_subdevice *s)
466{
467	struct usbduxfast_private *devpriv = dev->private;
468	struct comedi_cmd *cmd = &s->async->cmd;
469	unsigned int rngmask = 0xff;
470	int j, ret;
471	long steps, steps_tmp;
472
473	mutex_lock(&devpriv->mut);
474	if (devpriv->ai_cmd_running) {
475		ret = -EBUSY;
476		goto cmd_exit;
477	}
478
479	/*
480	 * ignore the first buffers from the device if there
481	 * is an error condition
482	 */
483	devpriv->ignore = PACKETS_TO_IGNORE;
484
485	steps = (cmd->convert_arg * 30) / 1000;
486
487	switch (cmd->chanlist_len) {
488	case 1:
489		/*
490		 * one channel
491		 */
492
493		if (CR_RANGE(cmd->chanlist[0]) > 0)
494			rngmask = 0xff - 0x04;
495		else
496			rngmask = 0xff;
497
498		/*
499		 * for external trigger: looping in this state until
500		 * the RDY0 pin becomes zero
501		 */
502
503		/* we loop here until ready has been set */
504		if (cmd->start_src == TRIG_EXT) {
505			/* branch back to state 0 */
506			/* deceision state w/o data */
507			/* RDY0 = 0 */
508			usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
509		} else {	/* we just proceed to state 1 */
510			usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
511		}
512
513		if (steps < MIN_SAMPLING_PERIOD) {
514			/* for fast single channel aqu without mux */
515			if (steps <= 1) {
516				/*
517				 * we just stay here at state 1 and rexecute
518				 * the same state this gives us 30MHz sampling
519				 * rate
520				 */
521
522				/* branch back to state 1 */
523				/* deceision state with data */
524				/* doesn't matter */
525				usbduxfast_cmd_data(dev, 1,
526						    0x89, 0x03, rngmask, 0xff);
527			} else {
528				/*
529				 * we loop through two states: data and delay
530				 * max rate is 15MHz
531				 */
532				/* data */
533				/* doesn't matter */
534				usbduxfast_cmd_data(dev, 1, steps - 1,
535						    0x02, rngmask, 0x00);
536
537				/* branch back to state 1 */
538				/* deceision state w/o data */
539				/* doesn't matter */
540				usbduxfast_cmd_data(dev, 2,
541						    0x09, 0x01, rngmask, 0xff);
542			}
543		} else {
544			/*
545			 * we loop through 3 states: 2x delay and 1x data
546			 * this gives a min sampling rate of 60kHz
547			 */
548
549			/* we have 1 state with duration 1 */
550			steps = steps - 1;
551
552			/* do the first part of the delay */
553			usbduxfast_cmd_data(dev, 1,
554					    steps / 2, 0x00, rngmask, 0x00);
555
556			/* and the second part */
557			usbduxfast_cmd_data(dev, 2, steps - steps / 2,
558					    0x00, rngmask, 0x00);
559
560			/* get the data and branch back */
561
562			/* branch back to state 1 */
563			/* deceision state w data */
564			/* doesn't matter */
565			usbduxfast_cmd_data(dev, 3,
566					    0x09, 0x03, rngmask, 0xff);
567		}
568		break;
569
570	case 2:
571		/*
572		 * two channels
573		 * commit data to the FIFO
574		 */
575
576		if (CR_RANGE(cmd->chanlist[0]) > 0)
577			rngmask = 0xff - 0x04;
578		else
579			rngmask = 0xff;
580
581		/* data */
582		usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
583
584		/* we have 1 state with duration 1: state 0 */
585		steps_tmp = steps - 1;
586
587		if (CR_RANGE(cmd->chanlist[1]) > 0)
588			rngmask = 0xff - 0x04;
589		else
590			rngmask = 0xff;
591
592		/* do the first part of the delay */
593		/* count */
594		usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
595				    0x00, 0xfe & rngmask, 0x00);
596
597		/* and the second part */
598		usbduxfast_cmd_data(dev, 2, steps_tmp  - steps_tmp / 2,
599				    0x00, rngmask, 0x00);
600
601		/* data */
602		usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
603
604		/*
605		 * we have 2 states with duration 1: step 6 and
606		 * the IDLE state
607		 */
608		steps_tmp = steps - 2;
609
610		if (CR_RANGE(cmd->chanlist[0]) > 0)
611			rngmask = 0xff - 0x04;
612		else
613			rngmask = 0xff;
614
615		/* do the first part of the delay */
616		/* reset */
617		usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
618				    0x00, (0xff - 0x02) & rngmask, 0x00);
619
620		/* and the second part */
621		usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
622				    0x00, rngmask, 0x00);
623
624		usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
625		break;
626
627	case 3:
628		/*
629		 * three channels
630		 */
631		for (j = 0; j < 1; j++) {
632			int index = j * 2;
633
634			if (CR_RANGE(cmd->chanlist[j]) > 0)
635				rngmask = 0xff - 0x04;
636			else
637				rngmask = 0xff;
638			/*
639			 * commit data to the FIFO and do the first part
640			 * of the delay
641			 */
642			/* data */
643			/* no change */
644			usbduxfast_cmd_data(dev, index, steps / 2,
645					    0x02, rngmask, 0x00);
646
647			if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
648				rngmask = 0xff - 0x04;
649			else
650				rngmask = 0xff;
651
652			/* do the second part of the delay */
653			/* no data */
654			/* count */
655			usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
656					    0x00, 0xfe & rngmask, 0x00);
657		}
658
659		/* 2 steps with duration 1: the idele step and step 6: */
660		steps_tmp = steps - 2;
661
662		/* commit data to the FIFO and do the first part of the delay */
663		/* data */
664		usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
665				    0x02, rngmask, 0x00);
666
667		if (CR_RANGE(cmd->chanlist[0]) > 0)
668			rngmask = 0xff - 0x04;
669		else
670			rngmask = 0xff;
671
672		/* do the second part of the delay */
673		/* no data */
674		/* reset */
675		usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
676				    0x00, (0xff - 0x02) & rngmask, 0x00);
677
678		usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
679		break;
680
681	case 16:
682		if (CR_RANGE(cmd->chanlist[0]) > 0)
683			rngmask = 0xff - 0x04;
684		else
685			rngmask = 0xff;
686
687		if (cmd->start_src == TRIG_EXT) {
688			/*
689			 * we loop here until ready has been set
690			 */
691
692			/* branch back to state 0 */
693			/* deceision state w/o data */
694			/* reset */
695			/* RDY0 = 0 */
696			usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
697					    (0xff - 0x02) & rngmask, 0x00);
698		} else {
699			/*
700			 * we just proceed to state 1
701			 */
702
703			/* 30us reset pulse */
704			/* reset */
705			usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
706					    (0xff - 0x02) & rngmask, 0x00);
707		}
708
709		/* commit data to the FIFO */
710		/* data */
711		usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
712
713		/* we have 2 states with duration 1 */
714		steps = steps - 2;
715
716		/* do the first part of the delay */
717		usbduxfast_cmd_data(dev, 2, steps / 2,
718				    0x00, 0xfe & rngmask, 0x00);
719
720		/* and the second part */
721		usbduxfast_cmd_data(dev, 3, steps - steps / 2,
722				    0x00, rngmask, 0x00);
723
724		/* branch back to state 1 */
725		/* deceision state w/o data */
726		/* doesn't matter */
727		usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
728
729		break;
730	}
731
732	/* 0 means that the AD commands are sent */
733	ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
734	if (ret < 0)
735		goto cmd_exit;
736
737	if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
738		/* enable this acquisition operation */
739		devpriv->ai_cmd_running = 1;
740		ret = usbduxfast_submit_urb(dev);
741		if (ret < 0) {
742			devpriv->ai_cmd_running = 0;
743			/* fixme: unlink here?? */
744			goto cmd_exit;
745		}
746		s->async->inttrig = NULL;
747	} else {	/* TRIG_INT */
748		s->async->inttrig = usbduxfast_ai_inttrig;
749	}
750
751cmd_exit:
752	mutex_unlock(&devpriv->mut);
753
754	return ret;
755}
756
757/*
758 * Mode 0 is used to get a single conversion on demand.
759 */
760static int usbduxfast_ai_insn_read(struct comedi_device *dev,
761				   struct comedi_subdevice *s,
762				   struct comedi_insn *insn,
763				   unsigned int *data)
764{
765	struct usb_device *usb = comedi_to_usb_dev(dev);
766	struct usbduxfast_private *devpriv = dev->private;
767	unsigned int chan = CR_CHAN(insn->chanspec);
768	unsigned int range = CR_RANGE(insn->chanspec);
769	u8 rngmask = range ? (0xff - 0x04) : 0xff;
770	int i, j, n, actual_length;
771	int ret;
772
773	mutex_lock(&devpriv->mut);
774
775	if (devpriv->ai_cmd_running) {
776		dev_err(dev->class_dev,
777			"ai_insn_read not possible, async cmd is running\n");
778		mutex_unlock(&devpriv->mut);
779		return -EBUSY;
780	}
781
782	/* set command for the first channel */
783
784	/* commit data to the FIFO */
785	/* data */
786	usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
787
788	/* do the first part of the delay */
789	usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
790	usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
791	usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
792	usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
793
794	/* second part */
795	usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
796	usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
797
798	ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
799	if (ret < 0) {
800		mutex_unlock(&devpriv->mut);
801		return ret;
802	}
803
804	for (i = 0; i < PACKETS_TO_IGNORE; i++) {
805		ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
806				   devpriv->inbuf, SIZEINBUF,
807				   &actual_length, 10000);
808		if (ret < 0) {
809			dev_err(dev->class_dev, "insn timeout, no data\n");
810			mutex_unlock(&devpriv->mut);
811			return ret;
812		}
813	}
814
815	for (i = 0; i < insn->n;) {
816		ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
817				   devpriv->inbuf, SIZEINBUF,
818				   &actual_length, 10000);
819		if (ret < 0) {
820			dev_err(dev->class_dev, "insn data error: %d\n", ret);
821			mutex_unlock(&devpriv->mut);
822			return ret;
823		}
824		n = actual_length / sizeof(u16);
825		if ((n % 16) != 0) {
826			dev_err(dev->class_dev, "insn data packet corrupted\n");
827			mutex_unlock(&devpriv->mut);
828			return -EINVAL;
829		}
830		for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
831			data[i] = ((u16 *)(devpriv->inbuf))[j];
832			i++;
833		}
834	}
835
836	mutex_unlock(&devpriv->mut);
837
838	return insn->n;
839}
840
841static int usbduxfast_upload_firmware(struct comedi_device *dev,
842				      const u8 *data, size_t size,
843				      unsigned long context)
844{
845	struct usb_device *usb = comedi_to_usb_dev(dev);
846	u8 *buf;
847	unsigned char *tmp;
848	int ret;
849
850	if (!data)
851		return 0;
852
853	if (size > FIRMWARE_MAX_LEN) {
854		dev_err(dev->class_dev, "firmware binary too large for FX2\n");
855		return -ENOMEM;
856	}
857
858	/* we generate a local buffer for the firmware */
859	buf = kmemdup(data, size, GFP_KERNEL);
860	if (!buf)
861		return -ENOMEM;
862
863	/* we need a malloc'ed buffer for usb_control_msg() */
864	tmp = kmalloc(1, GFP_KERNEL);
865	if (!tmp) {
866		kfree(buf);
867		return -ENOMEM;
868	}
869
870	/* stop the current firmware on the device */
871	*tmp = 1;	/* 7f92 to one */
872	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
873			      USBDUXFASTSUB_FIRMWARE,
874			      VENDOR_DIR_OUT,
875			      USBDUXFASTSUB_CPUCS, 0x0000,
876			      tmp, 1,
877			      EZTIMEOUT);
878	if (ret < 0) {
879		dev_err(dev->class_dev, "can not stop firmware\n");
880		goto done;
881	}
882
883	/* upload the new firmware to the device */
884	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
885			      USBDUXFASTSUB_FIRMWARE,
886			      VENDOR_DIR_OUT,
887			      0, 0x0000,
888			      buf, size,
889			      EZTIMEOUT);
890	if (ret < 0) {
891		dev_err(dev->class_dev, "firmware upload failed\n");
892		goto done;
893	}
894
895	/* start the new firmware on the device */
896	*tmp = 0;	/* 7f92 to zero */
897	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
898			      USBDUXFASTSUB_FIRMWARE,
899			      VENDOR_DIR_OUT,
900			      USBDUXFASTSUB_CPUCS, 0x0000,
901			      tmp, 1,
902			      EZTIMEOUT);
903	if (ret < 0)
904		dev_err(dev->class_dev, "can not start firmware\n");
905
906done:
907	kfree(tmp);
908	kfree(buf);
909	return ret;
910}
911
912static int usbduxfast_auto_attach(struct comedi_device *dev,
913				  unsigned long context_unused)
914{
915	struct usb_interface *intf = comedi_to_usb_interface(dev);
916	struct usb_device *usb = comedi_to_usb_dev(dev);
917	struct usbduxfast_private *devpriv;
918	struct comedi_subdevice *s;
919	int ret;
920
921	if (usb->speed != USB_SPEED_HIGH) {
922		dev_err(dev->class_dev,
923			"This driver needs USB 2.0 to operate. Aborting...\n");
924		return -ENODEV;
925	}
926
927	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
928	if (!devpriv)
929		return -ENOMEM;
930
931	mutex_init(&devpriv->mut);
932	usb_set_intfdata(intf, devpriv);
933
934	devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
935	if (!devpriv->duxbuf)
936		return -ENOMEM;
937
938	ret = usb_set_interface(usb,
939				intf->altsetting->desc.bInterfaceNumber, 1);
940	if (ret < 0) {
941		dev_err(dev->class_dev,
942			"could not switch to alternate setting 1\n");
943		return -ENODEV;
944	}
945
946	devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
947	if (!devpriv->urb)
948		return -ENOMEM;
949
950	devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
951	if (!devpriv->inbuf)
952		return -ENOMEM;
953
954	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
955				   usbduxfast_upload_firmware, 0);
956	if (ret)
957		return ret;
958
959	ret = comedi_alloc_subdevices(dev, 1);
960	if (ret)
961		return ret;
962
963	/* Analog Input subdevice */
964	s = &dev->subdevices[0];
965	dev->read_subdev = s;
966	s->type		= COMEDI_SUBD_AI;
967	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
968	s->n_chan	= 16;
969	s->maxdata	= 0x1000;	/* 12-bit + 1 overflow bit */
970	s->range_table	= &range_usbduxfast_ai_range;
971	s->insn_read	= usbduxfast_ai_insn_read;
972	s->len_chanlist	= s->n_chan;
973	s->do_cmdtest	= usbduxfast_ai_cmdtest;
974	s->do_cmd	= usbduxfast_ai_cmd;
975	s->cancel	= usbduxfast_ai_cancel;
976
977	return 0;
978}
979
980static void usbduxfast_detach(struct comedi_device *dev)
981{
982	struct usb_interface *intf = comedi_to_usb_interface(dev);
983	struct usbduxfast_private *devpriv = dev->private;
984
985	if (!devpriv)
986		return;
987
988	mutex_lock(&devpriv->mut);
989
990	usb_set_intfdata(intf, NULL);
991
992	if (devpriv->urb) {
993		/* waits until a running transfer is over */
994		usb_kill_urb(devpriv->urb);
995
996		kfree(devpriv->inbuf);
997		usb_free_urb(devpriv->urb);
998	}
999
1000	kfree(devpriv->duxbuf);
1001
1002	mutex_unlock(&devpriv->mut);
1003
1004	mutex_destroy(&devpriv->mut);
1005}
1006
1007static struct comedi_driver usbduxfast_driver = {
1008	.driver_name	= "usbduxfast",
1009	.module		= THIS_MODULE,
1010	.auto_attach	= usbduxfast_auto_attach,
1011	.detach		= usbduxfast_detach,
1012};
1013
1014static int usbduxfast_usb_probe(struct usb_interface *intf,
1015				const struct usb_device_id *id)
1016{
1017	return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
1018}
1019
1020static const struct usb_device_id usbduxfast_usb_table[] = {
1021	/* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1022	{ USB_DEVICE(0x13d8, 0x0010) },	/* real ID */
1023	{ USB_DEVICE(0x13d8, 0x0011) },	/* real ID */
1024	{ }
1025};
1026MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1027
1028static struct usb_driver usbduxfast_usb_driver = {
1029	.name		= "usbduxfast",
1030	.probe		= usbduxfast_usb_probe,
1031	.disconnect	= comedi_usb_auto_unconfig,
1032	.id_table	= usbduxfast_usb_table,
1033};
1034module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1035
1036MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1037MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1038MODULE_LICENSE("GPL");
1039MODULE_FIRMWARE(FIRMWARE);
1040