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