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