xref: /linux/drivers/comedi/drivers/usbduxfast.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
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  */
136 static 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  */
149 struct 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 
usbduxfast_send_cmd(struct comedi_device * dev,int cmd_type)164 static 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 
usbduxfast_cmd_data(struct comedi_device * dev,int index,u8 len,u8 op,u8 out,u8 log)183 static 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 
usbduxfast_ai_stop(struct comedi_device * dev,int do_unlink)195 static 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 
usbduxfast_ai_cancel(struct comedi_device * dev,struct comedi_subdevice * s)210 static 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 
usbduxfast_ai_handle_urb(struct comedi_device * dev,struct comedi_subdevice * s,struct urb * urb)223 static 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 
usbduxfast_ai_interrupt(struct urb * urb)258 static 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 
usbduxfast_submit_urb(struct comedi_device * dev)301 static 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 
usbduxfast_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)319 static 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 
usbduxfast_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)349 static 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 
usbduxfast_ai_inttrig(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)434 static 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 
usbduxfast_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)464 static 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 
751 cmd_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  */
usbduxfast_ai_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)760 static 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 
usbduxfast_upload_firmware(struct comedi_device * dev,const u8 * data,size_t size,unsigned long context)841 static 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 
906 done:
907 	kfree(tmp);
908 	kfree(buf);
909 	return ret;
910 }
911 
usbduxfast_auto_attach(struct comedi_device * dev,unsigned long context_unused)912 static 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 
usbduxfast_detach(struct comedi_device * dev)980 static 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 
1007 static 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 
usbduxfast_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)1014 static 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 
1020 static 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 };
1026 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
1027 
1028 static 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 };
1034 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
1035 
1036 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1037 MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
1038 MODULE_LICENSE("GPL");
1039 MODULE_FIRMWARE(FIRMWARE);
1040