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